Shifting Story Text: Combinatorial Narrative, Part Three

In part one and part two of this series on the combinatorial narrative system behind Ice-Bound, we gave an overview of how stories are constructed from narrative fragments, and how the player uses the printed book to communicate to the AI KRIS which themes are most important. In this installment, we’re going to dive into the actual story text itself: how we make hand-authored prose that’s still responsive to a changing narrative context.

While most of the reader’s interaction takes place in the map view, by rotating the iPad (or clicking the appropriate icon in the PC version), you’re taken to the page view, a mode where each story fragment you’ve assembled turns into a paragraph of text: “excerpts” from Kris Holmquist’s novel in its current configuration. While this text looks static, it actually can vary in both obvious and subtle ways, based on the player’s interaction with it, and how the pieces are reconfigured in the other view.

Most of these fragments are not written for a specific story, but for a global pool of content available when the system builds a “level” of Carina Station. Ice-Bound portrait mode combinatorial story textThis means the system must be able to “cast” a fragment with a particular story’s characters, and use appropriate names and pronouns throughout. The system uses the casting call to reject fragments inappropriate for a certain story: for instance, discarding a fragment requiring three characters in a story that has only two. We can also request a character who appeared in an earlier fragment or type of fragment. For example, a scene might require a character who was previously in a fragment where something tagged as “unsettling” happened.

Once the cast has been determined, we need to make sure names and pronouns appear correctly throughout the text. You don’t quite realize how often we use pronouns in English, and how many subtle variants there are, until you need to hand annotate each one! Not only is this prone to mistakes (do you mean his/her as in “her book,” or him/her as in “give it to her”?) but an awkward syntax makes it nearly impossible to write creatively: constantly having to interrupt the prose to call a function or insert curly braces can be a real cognitive drain that makes it hard to stay in a creative zone. We devised an authoring syntax that tries to minimize mental overhead. For instance, when you reference a character you tag which alphabetical “cast position” it’s referring to, but subsequent pronouns will assume you’re still talking about the same character unless you say otherwise, simplifying the syntax:

_name/a/ tried and tried to get to sleep. _They rolled over and clasped _their pillow over _their ears, hummed lullabies to _them~self.

(Why “they” and not “he” or “she”? It’s because third person plural is the one of the few pronoun forms in English that has a distinct word for each possible pronoun. We also have tags like _himher, but found the “they” form more natural once we got used to it.)


But slotting characters interchangeably into stories doesn’t do much to make those stories feel personalized. We also have more complex replacements triggered via additional underscore-prefixed keywords. One example is “mix-ins,” a technique borrowed from Aaron’s work authoring stories for the game Prom Week. By giving each character a word or phrase that they’d use in a particular context, such as saying hello or in a moment of shock, you can personalize dialog written for any character. So for instance:

_mixin/thanks/a/~, _mixin/friend/a/~,” _they said.

…might produce “Thanks, comrade” from one character, or “Thank you, my dear” from another. While this technique seems simple, it’s a remarkably effective injection of a particular character’s sensibilities into a narrative moment, and makes the rest of the scene seem written just for them.

These replacements can get rather complex. The underlying system is actually a full contextual expansion grammar, meaning a replacement can expand to a more complex form containing additional replacements, ad infinitum, and that each replacement can execute code referencing the full state of the system to decide what text to produce. (Aaron actually used Ice-Bound’s system to write a procedurally generated novel in a couple of hours for NaNoGenMo last year.) Some of the other tricks this system enables include using different text based on how many other characters are present, using specific language for specific time periods (such as changing an “email” to a “letter” or a “telegram”), or even changing text based on the way the reader ended a previous story.

icebound-story-variants
Example of the same story fragment appearing in two different contexts.

These techniques get even more powerful when combined with conditions that let us guarantee certain things about the story state before even selecting a narrative fragment. For instance, we can request that an event card only appear when the character we’ve cast in Slot A has an active “personal” socket, regardless of what it is. Since each personal socket corresponds to an item connected to that character, we can then write some story text where that item plays an important role:

_They/a/ held _item clenched tight in one hand, the can of kerosene in the other. “What are you doing?” _name/b/ asked.

This strikes a nice balance for our purposes between hinting at a dramatically consistent story, without actually doing all the incredibly difficult work of generating narrative from whole cloth. Why would Katrin burn her prized college diploma? Was it Bjorn’s trip below that led him to give up his drug addiction? Humans are remarkable meaning-making machines, and Ice-Bound’s fragments provide just enough leverage to imagine connective tissue between our isolated fragments, without us actually having to generate it.

Another example of this weakly-connected cause and effect is conditions that can require fragments to appear in conjunction with others sharing the same tag and cast members. For instance, readers who enjoy horror stories and start showing KRIS creepy Compendium pages might start seeing horrific symbols in their story maps. One set of these introduce some sort of monstrous force loose in the station: these are given the “monster” tag. We can then have ending fragments that require a “monster” tag to be already present: so, feeling in an actiony sort of mood, we might write a dramatic conclusion (perhaps involving a flamethrower) that could be the end to any of the various “monster” intros. This is some of what we mean when we say the system feels like playing with Legos: “monster” events become a block type that can attach to “monster” endings to produce something with narrative coherence. (We also do this in less melodramatic ways, too: creating emotional setups and payoffs involving a character dealing with loss, a romance, or a journey of self-discovery.)


One of the most visually pleasing aspects of the system is what we call “shimmer text,” that wriggles into other forms even as you’re reading it. We author this quite simply by including a run of alternatives set off by curly braces:

Katrin was {only seven|nine|eleven|just thirteen|already fifteen} when the accident happened.

As the text changes between options, the reader can tap one to “freeze” it in that configuration. We use this to create the feeling that KRIS is constantly exploring permutations of the story, even down to individual words, and also to give the reader a sense of editorial control: any writer can relate to the feeling of agonizing over the right word for the right moment. The speed and frequency of the changes can also be tuned with a special control tag for authorial effect: frantic constant shimmers suggest text KRIS is worried about, while slow, contemplative changes make him feel more musing. The choices themselves don’t mechanically affect the rest of the story, but can sometimes have a profound effect on your perception of an entire scene:

McKinley stared down at the bloody knife, {eyes filling with tears|feeling nothing at all|and his grin eventually turned into giddy laughter}.

Pulling all these tools together, we have a flexible system for authoring Ice-Bound stories that lets them adapt to the particular context the system decides to use them in, without becoming overwhelming for us as authors. Here’s an example of a complete story fragment, appropriate for a moment where one character has “gone below,” and when themes of despair and futility are not prevalent in the current story configuration:

"foolhardyRescue": {
	conditions: "tag_goingBelow && !tag_manIsWicked && !theme_futility",
	cast: "/tags_goingBelow/anyone/anyone/",
	name: "_name/b/ sets out Below to search for _name/a/~.",
	text: "_name/b/ was hefting the expedition pack onto _their parka-covered shoulders when _name/c/ found _them/b/~. \"What _mixin/swearmodifier/c/ are you doing?\" _they asked {frantically|calmly|angrily}. \"_name/a/~'s gone, _name/b/~. _They/a/~'s not coming back. Even if there wasn't _timeGate/anything strange about this place/1992/any weird shit going down/~, _they/a/~d be dead by now in this _mixin/swearAdjective/c/ cold.\" _name/b/~'s face was a mask as _they kept loading _their pack. \"For god's sakes, _mixin/friend/c/~, why?\"<br><br>_name/b/ pulled a strap tighter and finally looked at _them/c/~. \"Because,\" _they/b/ said simply, \"there's a chance _they/a/~'s still alive.\"",
	themes: ["doingWhatsRight", "humanDignity", "trialByFire"]
}

While this isn’t exactly free writing in a notebook, it’s simpler than a lot of interactive narrative environments we’ve worked in in the past, and once we got the format down, we can more or less just write, staying in a creative zone but still ending up with content that can be flexibly used by our combinatorial narrative system.


We’ve got one more post in this series scheduled, talking about the visualization tools we built to help manage the space of possible narratives, so stay tuned. In the meantime, check out our Kickstarter page, or follow the official site, Facebook, or Twitter accounts to keep up with the project. More soon!