Quiescent Theater

A Chris Martens and Rob Simmons Production

This website showcases several procedurally generated stories. Each story is based on a set of rules. These storyworlds allow multiple characters to act interdependently and independently. Every hour, a program generates a story from the world and produces a choice-based simulation game with the Twine hypertext engine.

Every scene in the story represents an interaction between characters; you experience the story by following characters through the scenes in which they interact. You can visit the same production multiple times to get a fuller sense of the story, but only until it is replaced by the next production!

Every path through a story will reach an ending, though some are quite long!

Current productions

Last generated at Thursday the 25th, 9:19pm Pittsburgh time (log).


The performance of Tamara will be the same in each generation. It is based on a static script which is typically performed as a live play in a multi-room stage. It is also to some extent the inspiration for this entire project.

By John Krizanc, adapted by Chris Martens.
Storyworld: tamara.clf
Script: tamara.scenes
Story Skeleton: tamara.out
Twee output: tamara.tw

The Swallows of Summer

This show is based on a world model that was used to generate a 50,000 word novel for NaNoGenMo (national novel generation month).

By Chris Martens and Rob Simmons. Concept by Chris Pressey.
Storyworld: swallows.clf
Script: swallows.scenes
Story Skeleton: swallows.out
Twee output: swallows.tw

Shakespearean Tragedy World

A social simulation based on Romeo and Juliet. Described in detail in this paper.

By Chris Martens
Storyworld: shakespeare.clf
Script: shakespeare.scenes
Story Skeleton: shakespeare.out
Twee output: shakespeare.tw

The Core

A tiny demo based on the author's apartment.

By Chris Martens
Storyworld: core.clf
Script: core.scenes
Story Skeleton: core.out
Twee output: core.tw

The Cloak of Darkness

An Interactive Fiction "benchmark" world described here.

By Chris Martens. Concept by Roger Firth.
Storyworld: cloak.clf
Script: cloak.scenes
Story Skeleton: cloak.out
Twee output: cloak.tw

Why we did this

We pursued this project based on an interest in the ideas of simulation and focalization in the context of narratives. We took most of our inspiration from two sources:
  • The Swallows of Summer - a contribution to NaNoGenMo that created a 50k word novel based on a simulation of characters, rooms, and things, where characters' actions were reminiscent of z-machine-style interactive fiction.
  • Tamara - a play performed in multiple rooms where the audience members could choose who to follow when characters' paths diverge, allowing the story to be experienced from multiple perspectives or focalizations.

Chris's prior work on generating narrative skeletons with the programming language Celf gave us a starting point. Her paper describes a social simulation environment based on Shakespearean tragedy tropes, using general rules that can apply to any character.

From there, we realized that we could transcribe Celf's output into a Twine format, making each choice in a passage correspond to a single resource generated by a rule. This approach yields a mechanism very close in spirit to that employed by Tamara, in a way that we could also apply it to highly nondeterministic, generative stories like those in the Swallows of Summer.

How our engine works

Schematic diagram of how our engine works

Celf and Twine are existing programs. We wrote the compiler in Standard ML. It is available on Github.

Each world is described as a collection of rules written in the programming language Celf. An example of a rule is

search : Pi C. Pi B. Pi O.
     loc C R * loc_o B (inroom R) * loc_o O (inside B)
 -o {loc C R * loc_o B (inroom R) * loc_o O (has C)}.

This is a rule from the Swallows of Summer story world describing how a character C can search a container B and retrieve an object O from it (in a room R). It requires that C be in the same room as B and that O is inside B. If this rule is executed, it replaces the facts before the -o symbol with those after it. In this case, the facts that C and B are in the room R are maintained, while the fact that O is inside B is replaced with the fact that O is in C's possession.

These rules give the mechanical structure to the story. The scenes file describes the actual text to be displayed corresponding to a rule application. The part of the scenes file corresponding to this rule is

:: search 1
<1> searches the <2> carefully.
<1> takes the <3> hidden there.                                                                 
<1> rustles through the <2>, and then pockets the hidden <3>.

Explaining this rule in pieces:

  • "::" is just a prefix indicating a new scene. "search" is the name of the Celf rule to which this scene corresponds.
  • "1" is the number of followable resources the scene should have, corresponding the first output of the rule, "loc C R." This means that after the "search" action happens, the player will be able to follow the character C (but not the object O, which would be the case if we wrote "2" instead).
  • This scene description contains references <1>, <2>, and <3> to the first, second, and third terms bound by the "Pi"s in the rule. The text from Celf's output instantiating those terms will replace those references in the text.
  • Finally, the "||" delimits multiple variants of the scene. One variant will be chosen randomly for each passage generated for this rule.

Putting these pieces together will render a Twine scene that looks like this:

Scene from shakespeare world

...where "Follow Alice" links to the next scene whose rule takes Alice's location as a premise.

We chose the name "quiescent theater" based on a twofold pun: for one thing, Celf generates output by running our rules on an initial state until no more rules apply, a state referred to as quiescence. "Quiescent" can also mean "latent" or "potential", and in the sense of Oulipo's "potential literature", our story worlds represent "potential theater;" they are static artifacts that algorithmically generate dynamic performance.

Additional Credits

Thanks to Leon Arnott for the CSS we used in the Twine output and for this webpage.