-
Notifications
You must be signed in to change notification settings - Fork 3
Technical System Description
It isn't necessary (hopefully!) for authors to understand the technical underpinnings of StoryAssembler in order to write with it, just the affordances the system allows. That said, for fellow creators of dynamic narrative systems, or academics with an interest in the space, it's useful to understand what's going on under the hood, so it can be understood what these sorts of systems are good at, and where they fall down.
StoryAssembler is two systems working in tandem to satisfy a story spec: a fragment composition system, and a choice-graph construction system. StoryAssembler greedily optimizes for fragments that fulfill the maximum number of spec entries, as well as every choice in that fragment going to subsequent fragments that fulfill the maximum number of spec entries.
This system is a forward state-space planner. The "goal state" is broken into a list of intermediary states (the "story spec"). The system greedily tries to satisfy as many intermediary states ("spec entries") as possible. It does this by activating the fragment composition system, and then picking the composition with the highest score. A scene ends once all of the story spec entries are satisfied.
This system is very similar to a [hierarchical task network (HTN) planner] (https://en.wikipedia.org/wiki/Hierarchical_task_network). Fragments are composed by recursively searching the content library for components, be that body text or choices. Fragments are given scores to maximize progress towards fulfilling all story specs entries. Additionally, fragments score slightly higher if their choices link to other fragments that make goal progress, or incorporate into themselves other fragments that make goal progress as compound fragments. One can think of these as HTN planner sub-tasks (e.g. finding choices or body-text with specific properties).
The number of choice-steps forward the system looks is controlled by DEFAULT_MAX_DEPTH in bestPath.js. Because it exhaustively searches, upping this parameter (which hypothetically could be desirable, if the content is structured correctly) can dramatically increase the time between the player clicking a choice and the fragment displayed.
The chosen assembled fragment represents the best next step for the forward state-space planner, and it continues in this manner until the scene ends.
Because it's forward-looking, it's possible for the planner to end up in situations (especially in more complex works) where the author has not accounted for all cases, and the scene cannot continue. In that case, StoryAssembler allows author-defined fallback text to display, in order to gracefully end the scene.