Tobias Reithmeier

Gamebooks

The language behind the books

Story Weaver is a small language for adventure gamebooks that I designed and wrote myself: Markdown as its syntax, semantics inspired by ink, rules borrowed from the gamebooks of the 1980s with skill, stamina and luck. It exists because a book like this is mostly text and should be written like text, not inside a tool with its own file format. A book stays a readable text file that any editor can open, version and diff. How it looks on screen is not part of the book: presentation and controls come from whatever plays it.

Three books are written in it, a fourth imported, and all four are playable here: The Crypt Under the Thorn as a starting point, The House Behind the Moor as the larger one, Brüder dunklen Rufes as the longest, retold from the Over the Hills podcast and the only one that exists in German alone, and The Intercept, inkle's own ink demo, brought across with story-weaver import: no rules layer, and proof that the storytelling half of the language carries someone else's text too.

Nodes and choices

A heading starts a node and gives it an identifier; a choice is a list item linking to a node. A plus sign marks a choice that may be taken more than once, curly braces a condition.

# Am Waldrand {#begin}

Der Pfad teilt sich vor einer Weißdornhecke.

* [Nach links, ins Dickicht](#thicket)
+ [Zurück zur Hecke](#begin)
* {has("lantern")} [In den Spalt unter der Hecke](#crypt.crypt)

All in the header

Every book opens with a YAML header: title, start node, the stats with their dice formulas, items and what they do, opponents, combat rules and the condition under which a character dies. The prose only refers to it. Even the choice of what to travel with lives here.

stats:
  skill: { name: Geschick, start: "roll(1,6) + 6", max: start }
  fear:  { name: Angst, start: 0, max: 15 }

enemies:
  hound: { name: Kettenhund, skill: 7, stamina: 6, flee_after: 2 }

death:
  when: "stamina <= 0 or fear >= fear_max"

Dice, stats, combat

Skill, stamina and luck are rolled at the start; tests and fights roll against them. A fight names only the opponent and the outcomes, its rules live in the book header; a tilde changes a stat or the inventory.

!combat goblin
  win  -> chamber
  lose -> death
  flee [Zurück durch den Spalt](#start.thicket)

~ take("silver-key")
~ stamina -= 2

Text with a memory

Paragraphs change with the state of play: stats can be inserted into the text, and curly variants show one thing on a first visit and another afterwards, cycle in order, pick at random, or depend on a condition such as an item in the pack. With remember, a book also keeps notes that later choices can read.

{!Kalte Luft schlägt dir entgegen.|Du kennst den Weg jetzt.}
{&Ein Krachen|Ein Knirschen|Stille} im Unterholz.
{has("lantern"): Das Licht reicht weit.|Es ist stockdunkel.}

Du hast noch {gold} Goldstücke und ein Glück von {luck}.

~ remember("KRAKEN")

Two languages, one structure

Translations carry only text: the structure lives in the default language, and the second language is a catalogue of paragraphs in the same order. Nodes, choices and rules exist exactly once, and targets are written in the default language only.

de/start.md
# Am Waldrand {#begin}
* [Nach links, ins Dickicht](#thicket)

en/start.md
# At the Forest Edge {#begin}
* Left, into the thicket

Checking and playtesting

A tool checks every book before release for unreachable nodes, dead links and dead ends. It also plays through many runs automatically and reports how they ended. That is how the long book revealed that the fear stat punished every second visit to the same room.

story-weaver lint examples/house/book.yaml --strict
story-weaver simulate examples/house/book.yaml --runs 300
# Das eiserne Tor {#gate}

Das Tor schließt die Gruft nach Norden ab.

{ has("silver-key") and knows("KRAKEN") }
  Der Schlüssel dreht sich, als hätte er auf dich gewartet.
  ~ heal(2)
{ else }
  Ohne Schlüssel und ohne das Wort bleibt das Tor, was es ist.
  -> chamber

* [Hinaus ins Licht](#daylight)
A node and its choices, as they appear in the source.

Story Weaver is my own project, open under MPL-2.0; this page ships a frozen build of the books, translated, bundled and free of runtime dependencies.

More from the gamebook shelf