Procedural Generation in Ink: Part 1: Random Entries

Procedural Generation in Ink

Ink is a narrative scripting language for creating interactive fiction and other vast, branching digital projects.

Random Entries

Procedural generation is the creation of content through automatic means. Complex interactions can be made through writing a series of interlocking or dependent simple rules.

In narrative games and projects, procedural generation is often used as a way to create content through including several options and having one or more be selected during startup. From there, more complex rules can react to the choice to make anything from which items can be found within a room to the layout of buildings or even whole planets.

Randomness in Ink

In Ink, the tilde character (~) is used to choose a random entry when used inside alternatives. During run-time, one of its many possibilites will be picked from the list. (Ink prevents an author from setting an initial value using the random operator. An initial, default value must be set and then overwritten during run-time.)

VAR year = 0
~ year = "{~two|three|four|five}"

In Ink terminology, the use of the tilde character is known as shuffling. It is one of a number of alternatives.

Using this same method of setting an initial value and then getting a random shuffled entry, multiple values can be pulled together to create a simple grammar (series of rules) that use the random entries to make content.

VAR year = 0
~ year = "{~two|three|four|five}"

VAR pronoun = ""
~ pronoun = "{~he|she|them}"

VAR arrivalMethod = ""
~ arrivalMethod = "{~on a boat|from over the mountain|traveling down the long road}"

It has been {year} years since I {pronoun} arriving {arrivalMethod}.

Building Stories from Randomness

While not strictly a narrative game, Caves of Qud (2014) is a great example of how random elements can be used within a series of rules to create compelling, strange, or just silly content. Its history of civilization, for example, builds off a short series of rules that follow a story formula to build a structure.

While not the same exact thing, Tony Veale has created a project called Scéalextric that is a series of interlocking story triples. These can be used to populate the random choices that run from one to another to create a story arc.

Following the same random method outlined above, a simple (but probably nonsense) story can be crafted through defining the rules of how the shuffled entries should be shown and then using the run-time to create a three-point story arc.

VAR beforeAction = ""
~ beforeAction = "{~abandon|are feared by|underestimate|turn against|are inspired by|are bought off by|turn against|take up with|pursue|take up with|are manipulated by|kill|are lured by|turn against|are moved by|indoctrinate|sympathize with|release|seek forgiveness from|enlist|fall in love with|abuse||enlist|look for|supervise|are obeyed by|supervise|are obeyed by|disfigure|fall in love with|admire}"

VAR afterAction = ""
~ afterAction = "{~are pursued by|overthrow|are suppressed by|are attacked by|imitate|settle with|are beaten by|are impressed by|are taunted by|are flattered by|cede power to|are cursed by|surrender to|are underestimated by|fall in love with|are trusted by|fall in love with|are forgotten by|are pitied by|are trusted by|are worshipped by|are bitten by|are respected by|are trusted by|are trusted by|lead astray|are respected by|profit from|are disgusted by|are concerned about|are encouraged by|are deceived by|are shocked by|are bought off by|are killed by|are arrested for hurting|are arrested for killing|are pitied by|are energized by|are manipulated by|are insulted by|are bitten by|are humiliated by|are bored by|are ejected by|are upstaged by}"

VAR closure = ""
~ closure = "{~abandon|turn against|take aim at|testify against|abuse|kill|alienate|indoctrinate|admire|beg forgiveness from|are shocked by|are bought off by|humiliate|condescend to|write about|share stories with|spread lies about|testify against|argue with|spy on|are abandoned by|are abducted by|are appointed by|are arrested for killing|are cursed by|are attacked by|are attracted by|are banished by|are beaten by|are betrayed by|are bitten by|are blackmailed by|are booed by|are bored by|are bought off by|are brainwashed by|are captured by|are captured by|are censured by|are challenged by|are cheated by|are chosen by|are coached by|are conquered by|are copied by|are corrupted by|are cursed by|are cut off by|are deceived by|are denounced by|are humiliated by|are deposed by|are deposed by}"


This is a story about A and B.

First, A {beforeAction} B.
Next, B {afterAction} A.
Finally, A {closure} B.

This work is based on the following:

Veale, T. (2016). A Rap on the Knuckles and a Twist in the Tale: From Tweeting Affective Metaphors to Generating Stories with a Moral. In Proceedings of the AAAI Spring Symposium on Ethical and Moral Considerations in Non-Human Agents.

Additional information can be found on the GitHub page: