Writing with Ink – Lists with an Oxford Comma

The guys at Inkle Studios have shared their method for printing a list using a recursion function on their Patreon page, but I found an easier method to insert an Oxford Comma when printing a list.

   - 0: No one is here. 
   - 1: Only {IsPresent} is here. 
   - 2: {LIST_MIN(IsPresent)} and {LIST_MAX(IsPresent)} are here. 
   - else: {IsPresent-LIST_MAX(IsPresent)}, and {LIST_MAX(IsPresent)} are here. 

In this example I’m grabbing the LIST_COUNT of IsPresent, and printing the contents  according to how many items there are.

With 3 or more in the list I subtract the LIST_MAX (the last item in the list) from the full list before printing, then insert a comma before printing the LIST_MAX.

Writing with Ink – Runtime Loop

I’ve written an old knock-knock joke into an Ink script to show a basic runtime loop. The logic here is simple: tell a joke three times, but the third time with a different ending.

I define the loop start with an index: joke.

The loop gate has two settings: closed diverts the runtime to the start of the loop, open (or unlocked) allows the runtime to proceed. My start state is closed. On the third try it will open.

CONST punchline = 3 

- (joke) Knock knock! 
+ Who is there? 
- {joke<punchline: 
   + Banana Who? 
      -> joke 
   - else: 
   * Orange Who? 
      Orange you glad I didn't say banana? 

My conditional test doesn’t use variables, although the loop gate looks as if joke and punchline are variables. Ink is counting how many times the index joke has been seen and comparing it against a constant value called punchline. When joke is less than punchline the loop is closed.


Things to know:

  • A constant looks like a variable in Ink script, but it isn’t dynamic. At runtime it is replaced with the value it represents. Constants are for scripting convenience.
  • The index cannot be addressed from outside this knot, but leaving and coming back to the knot will preserve the seen count.

Ink – Markup Language for Branching Narratives

Ink is an open source narrative scripting language developed by Inkle, creators of the IGF award-winning 80 Days. The free Inky compiler can export Ink story files to JSON for integration with Unity, or create a fully functional Javascript-powered web player like the example below:

At its most basic, Ink can be used to write a branching dialogue tree or a non-linear Choose Your Own Adventure story with multiple endings, but its real strength is allowing non-technical writers to create dynamic narratives using only minimal markup syntax. The text remains readable allowing an author to follow the story flow by eye, and edit at any point to add new branching options and alternate text, update variables, and reconnect to the main story.

Inky, a writing app, player, and compiler for .ink story files

There’s no programming loop. Instead an ink runtime follows a single path through the text, typically following a goto link, jumping directly to sections called knots and their order-prioritized sub-sections called stitches – with a name like ink it would be reasonable to expect the metaphors would be about pens and writing but an inkle loom is a device for weaving straps out of one continuous thread wound around pegs (an elegant metaphor that isn’t terribly helpful in understanding ink’s syntax).

an inkle weaving loom

Ink runtime keeps track of which sections of the story have already been visited, automatically removing the options that have already been picked. Multiple choice dialog branches can be nested in place, creating conversational diversions before seamlessly weaving back into the main thread. Authors can write in natural prose, following conventions of visual novels or interactive fiction, and not worry about specialized code or relying on programmers to generate the options.

Ink Homepage
Ink Documentation
Someone uploaded Ink Playmaker actions on Github

Michael Mateas – How New Playable Models from Recent Work on AI Can Enable New Types of Serious Games

Aug 25, 2013 –– Together with a few collegues, Michael created the interactive story “Façade“, an interactive drama about the relations between three persons in a small flat. Michael holds the MacArthur Chair at University of California, Santa Cruz and runs their Expressive Intelligence Studio where they explore the intersection of artificial intelligence, art and design. “Our goal is to create compelling new forms of interactive art and entertainment that provide more deeply autonomous, generative and dynamic responses to interaction”, says Michael. His talk is titled “How New Playable Models from Recent Work on AI Can Enable New Types of Serious Games, i.a. Games about Human Rights”. The lecture is given as part of the course “Human Rights in Serious Games”.

Storytron – Interactive Storytelling

I spent the day digging into Chris Crawford’s theoretical lectures on generative fiction, finally arriving at Storytron, the procedural narrative engine he wrote in java. I feel like I’ve stumbled on an Aladdin’s cave!

Based on his earlier software Erasmatron and a precursor to his current effort Siboot – Crawford has spent the last quarter century working on the concept, with origins going back as far as the 8-bit game Gossip he made for Atari in the 1980s. Storytron was his ambitious, quixotic stroytelling platform that promised to revolutionize interactivity to an artform, allowing authors to put the human condition at the center of the action and demanding players utilize social intelligence over puzzle-solving and shooting things.

Not only does he describe the abstract concepts of what makes a narrative game more interesting (“people, not things”), he lays out the nuts and bolts of a turn-based procedural story generator where characters act according to their own motives, reacting to crises as they arise, and influencing other characters.


Authors were to define the actions and consequences, and create characters and locations suitable to any genre; ultimately creating the rules of each story world. At the heart of the software lies an event loop that manages a single dramatic action, assigns roles to all available actors and determines each character’s reactions, and progresses time incrementally – all the while keeping track of every character interaction, every emotion, every prop and location.

Drama Loop

Each Event contains a Verb that defines a single action and assigns roles to the Actors who are present: participants and witnesses, protagonists and victims.

– Roles
–– the conditions under which an Actor may assume a Role
–– the emotional reactions of the Actor taking that Role
–– a group of Options for that Actor for reacting to the Event

– each Option specifies:
–– which WordSockets will be used construct the sentence for that Option
–– the rules for what words will be chosen to fill those WordSockets
–– the Inclination of the Actor towards executing that Option

Reaction Cycle

Then each witnessing Actor cycles through the available roles and assumes one of them if appropriate, choosing the Option highest in the list according to their Inclination (current variables). This Option is added to the Actor’s list of Plans, and will be executed in its own cycle as a later Event by the engine. The reacting Actor can also suffer Consequences: ie, be injured, die, have their reputation besmirched, etc….

Events can be Highjacked by a Role if the conditions are met by one of the Actors. Plans can be prioritized, delayed, or aborted. Characters not only keep track of their own inclinations, but also have Attributes that can be perceived by other Actors — and these perceived values are not necessarily the same as the actual values. Characters have their own opinions.

Once each Actor has accepted a role and decided on their Plan, the Event loop ends. The engine calls the next Event loop based on the urgency of pending Events, and the process starts over again.

Meanwhile the engine tracks the opinions actors have of each other, which will influence their reactions to future Events. Whether a character lies or tells the truth, another character’s perception of his honesty may be more influencial than the actual truth.

Scripts are used to break down social situations into simple mathematical formulas. Not every situation triggers a visible reaction from the Actor. Often a brief facial expression is the only clue to what they are thinking. An Actor may create a Plan that requires immediate action, or create a plan for a later time and place. If Mary sees Tom fighting with Bill, she may decide to intervene or wait and tell Joan about it later.

Some events are witnessed by everyone on the Stage, while others are exchanged “cheek by jowl” only between the Actors directly involved. Some events reflect the private mental state of an Actor, and others are completely “under the hood” making changes to the story without the Actors’ knowledge. Actors can travel to other Stages (locations) either through boredom or to accomplish a Plan, and become involved in the Events there.

Deikto: a toy language

Maybe the most ambitious aspect of Storytron is an elaborate linguistic system that pastes together complete sentences with wordsockets, Mad-Libs style. Each defined Verb action references a subject and direct object, usually an Actor and another Actor or Object assigned at runtime, plus helper words to flesh out the sentences. Remarkably the sentence strings can be chained to convey complex relationships and ideas. An Actor can report earlier events to a character who was not there, or an actor can try to influence the actions of other characters by lying, threatening, or bargaining. More on Deikto…


An omniscient, non-Actor named Fate acts as a kind of narrator and deus ex machina, opening the story with “Once upon a time”, describing the Stage and announcing the arrival and departure of characters. Fate acts as a Greek chorus to comment on the unfolding action, and ultimately deciding when the story should end once the goal of certain variables has been maintained for a set amount of time, ie: living happily ever after.

This modular approach to story creation allows any number of Actors to be replaced with players. The Options that would normally be served by the engine based on a hierarchy of roles and reactions are presented to the player as a list of choices. The engine doesn’t actually need a player and can generate an entire story procedurally.

Crawford’s Folly

Ultimately Storytron was so complex that few people could understand it, much less master the interlocking systems to create a complete story world. Crawford is amazingly candid in his online lectures and interviews. Mercurial in his references and brutally honest with his opinions, he relates the shortcomings of the game industry to grasp his larger vision, and his disappointment in games praised for their graphics over their artistic content, as well as his own inability to inspire a revolution. It’s easy to see how he became a polarizing figure, ultimately walking away from the profitable gaming industry to pursue broader truths.

Although in many of his lectures Crawford gleefully criticizes the game industry for focusing on a niche market of hardcore male gamers – the results of a narrow profit-oriented evolution and lack of sophistication – he has also worked to manifest his own ideas into a working “game”, although he is loath to call it a game. Storytron is the applied science to Crawford’s grand theories, attempting to slay his five metaphorical dragons of interactive game design:

1. facial Micro-expressions to communicate real emotions
2. Character personality models: Goodness, Honesty, and Dominance
3. Linguistics
4. Narrative engine/ AI
5. Integrated Design Environment

Crawford readily admits he hasn’t solved the issues, but only pioneered into unexplored territory. Although Storytron is now offline (in a medically induced coma, as he says on the website), he freely offers up his theories, and has scaled back his ambition to a much smaller project focused on one specific story and a simplified language of picticons used to communicate between characters. Still he leaves his many journals and diaries for the next generation, like a treasure map to undiscovered cities of gold.