Storylets and Saliency: A Primer
Last updated
Was this helpful?
Last updated
Was this helpful?
When you do things right, people won't be sure you've done anything at all. - Futurama
Storylets and saliency represent an evolution in interactive storytelling techniques. To understand their significance, let's examine how narrative approaches have developed over time.
The earliest approach to storytelling was linear. Stories followed a single, author-defined path with each moment crafted to lead directly to the next.
The next evolution introduced branching, allowing stories to have multiple paths for players to explore.
Branching narratives offer remarkable flexibility. Some branches might be extensive with significant impact, while others could be minor, adding subtle flavor. Some paths might terminate, while others reconnect with the main storyline. Despite this flexibility, each step remains author-crafted, with branches fixed in the writer's intended order.
Storylets represent the next step in this evolution. They break the rigid connections between narrative elements, creating a more dynamic flow. Theoretically, a story could move from any storylet to any other storylet, creating a potential connection from every block to every other block.
If narrative chunks are disconnected, how do they form a coherent experience? This is where saliency comes in—it's the mechanism that links story pieces together.
Saliency determines which storylet is most relevant (or "salient") at any given moment. Instead of an author-defined sequence, saliency selects the ordering dynamically. For example, if you have two storylets—one about entering any room in an apartment, and another specifically about entering the bedroom—when the player is in the bedroom, the more specific storylet would be more salient.
Interestingly, linear and branching narratives can be viewed as salient stories composed of storylets, where the most salient storylet is defined by the author's explicit connections. This perspective highlights a major strength of storylets: they can incorporate and blend previous structural approaches. This gives you precise control when needed while maintaining flexibility for dynamic narrative progression.
The storylet is the fundamental unit of this narrative system, but how large or small should a storylet be? The answer depends on your specific narrative needs.
Storylets typically exist at three levels of granularity:
Collection Level: The largest unit—a vignette, conversation, or paragraph. At this level, your story assembles by connecting self-contained moments. These moments generally function independently, so their precise order may be flexible, or they might be designed to flow naturally with a subset of other moments.
Line Level: Here, a storylet represents a single line of dialogue. Conversations build by assembling individual lines, which then form larger narrative moments. This approach is particularly effective for creating dynamic NPC barks in games.
Sub-Line Level: The smallest unit, where storylets are fragments within a single line. These pieces combine to form complete lines of dialogue, which then assemble into conversations.
Many games blend these approaches, often mixing storylet techniques with traditional linear or branching content. Rather than focusing exclusively on storylet size, consider what type of narrative experience you want to create and determine what level of storylet granularity will best support that vision.
How do we determine which storylet is "best" to present next? The approach varies based on your narrative goals.
The most common approach uses conditions on each storylet—boolean expressions like "are we in the bedroom?" or "does the player have more than 25 gold coins?" These conditions filter available storylets and help select among the remaining options. When multiple storylets are valid, you select the one with the highest "quality"—typically the one that satisfies the most conditions.
Another approach tags storylets with various attributes. When selecting the next storylet, you filter based on relevant tags. The filtering criteria might come directly from player choices or from systems guiding the narrative.
Some approaches aim to guide the narrative toward specific outcomes:
Pathfinding: Storylets exist on a graph, and the system attempts to progress from the current storylet toward a specific destination, influenced by player choices along the way.
Drama Management: A system with narrative goals selects storylets to work toward those goals. For example, Façade selects storylets to maximize conversational drama. Pathfinding can be viewed as drama management where the goal is reaching a specific point in the narrative graph.
Two less complex but still useful approaches include:
Player Selection: Present all available storylets and let the player choose.
Random Selection: Choose randomly from available storylets.
These methods often incorporate knockout or deprioritization systems to prevent repetition. They're also effective for resolving ambiguity when multiple storylets have equal saliency.
Storylets serve various narrative functions in games:
Perhaps the most common use is creating contextual NPC comments. Skyrim's infamous "arrow to the knee" line exemplifies this—triggered when the player has cleared a dungeon, a condition most players eventually satisfy.
Storylets create specific moments that add life to the game world without connecting directly to the main plot. Mass Effect's elevator conversations, filtered based on your current squad members, demonstrate this approach.
Storylets can create highly specific dialogue responding to gameplay moments, making NPCs seem more aware and reactive. Left 4 Dead's combat and downtime barks showcase this, as do Ellie's contextual reactions in The Last of Us.
In games without predetermined stories, storylets create meaningful moments and side-narratives. Civilization VII uses storylets for historical and alternative historical events, triggered by factors like civilization type, leaders, and current player actions.
Database-driven games use storylets to let players explore narrative space freely. Her Story exemplifies this approach, with self-contained story chunks that both stand alone and contribute to an overall narrative.
Some games build entire narratives from storylets. Mask of a Rose and Wildermyth assemble stories entirely from storylets based on player actions, allowing players to create their own unique narratives.
Yarn Spinner supports two primary levels of storylet granularity: line-based and node-based. Both integrate seamlessly with traditional branching and linear Yarn scripts.
Line Groups implement line-level storylets. They visually resemble option groups but use =>
instead of ->
. Each line within a group represents a potential storylet, but only one will be selected.
The dialogue system receives the Barry line, then one selected line from Alice. The player might see:
The system doesn't indicate that the Alice line came from a storylet selection—it's simply presented as the next line of dialogue.
We can add conditions to modify selection:
Assuming high Barry suspicion and knowledge that he's a cop, the dialogue might present:
The final line is selected as the most salient option, even though multiple options satisfy their conditions.
Like option groups, line groups support nested content that only appears if that specific line is chosen:
Any Yarn dialogue or commands can be nested, including other storylets, jumps, and detours.
Node groups allow larger storylet chunks to be associated. They look like standard nodes but require a when
header:
When <<jump Alice>>
executes, it jumps to the most salient node in the "Alice" group. If Barry is highly suspicious and Alice knows he's a cop, the system selects the last node.
For this simple example, node groups require more writing than line groups for the same effect. However, for larger conversations with significant variability, node groups become more advantageous.
Like line groups, node groups can contain any valid Yarn content, including jumps, detours, and line groups.
The dialogue runner consults a saliency strategy when presenting a storylet, whether from a line group or node group. While you can create custom strategies to implement any approach, Yarn Spinner provides several built-in quality-based strategies:
Best (select the most salient)
Best Least Recently Viewed (prioritize salient content that hasn't been seen recently)
Random Best Least Recently Viewed (like above, with some randomization)
Random (completely random selection)
All built-in strategies first filter out storylets with failing conditions, though custom strategies can include failing conditions if desired.
The recommended default is Random Best Least Recently Viewed, which balances selection of the highest-saliency content while preventing repetition.