Tobias Reithmeier

Blog

Warum ich mir eine eigene Sprache für Spielbücher gebaut habe

Ein Spielbuch besteht fast nur aus Text. Also sollte man es wie Text schreiben können: in einer Datei, die jeder Editor öffnet und die sich versionieren und vergleichen lässt. Dafür habe ich Story Weaver gebaut, eine kleine Sprache für Abenteuerspielbücher.

Worum es geht

Gemeint sind Bücher in der Tradition der Achtzigerjahre. Man liest einen Abschnitt, trifft am Ende eine Entscheidung und blättert zu der Nummer, die sie nennt. Bei Reihen wie Fighting Fantasy kamen Würfel dazu: Geschick, Ausdauer und Glück werden am Anfang ausgewürfelt, und ein Kampf läuft Runde für Runde gegen diese Werte. Solche Bücher habe ich als Jugendlicher gespielt.

Story Weaver bildet genau das ab. Ein Buch ist eine Markdown-Datei oder ein Ordner davon. Eine Überschrift ist ein Abschnitt, ein Listenpunkt ist eine Wahl, ein Link ist das „weiter bei 137“. Die Erzähllogik folgt ink, die Regeln folgen den Spielbüchern von damals. Wie das Ganze am Bildschirm aussieht, steht nicht im Buch. Das entscheidet die Umgebung, die es abspielt.

Angefangen hat das Projekt im August 2026. Story Weaver liegt als Open Source auf GitHub, unter der Mozilla Public License 2.0.

Was es schon gibt

ink ist die Skriptsprache, die das Studio inkle für seine eigenen Spiele geschrieben hat, darunter Sorcery! und 80 Days. Sie steht unter MIT-Lizenz und wird als Middleware in Spiel-Engines wie Unity eingebunden. Im Vordergrund steht der Text, Code und Logik werden hineingesetzt. Story Weaver übernimmt die Ideen von ink weitgehend und ersetzt die Zeichensetzung durch die von Markdown, mit genau einer Schreibweise pro Konzept: Wo ink mehrere Wege für dieselbe Sache anbietet, bleibt einer übrig. Wer ink nicht kennt, muss es nicht lernen.

Twine ist ein Open-Source-Werkzeug für interaktive, nichtlineare Geschichten. Was eine Geschichte kann und wie man ihre Logik schreibt, hängt dort vom gewählten Story-Format ab: Chapbook, Harlowe, Snowman oder SugarCube.

Beide sind allgemein gedacht, für jede Art verzweigter Erzählung. Eine Regelschicht mit Werten, Gegenständen, Proben und Kämpfen bringt ink nicht mit; wer so etwas will, baut es selbst. Story Weaver ist enger gefasst. Es deckt weniger Arten von Spielen ab, aber für die eine Art, das Abenteuerspielbuch, ist die Regelschicht Teil der Sprache. Ein Kampf braucht keinen eigenen Code.

Wie ein Buch aussieht

Das kleinste Beispielbuch heißt Die Gruft unter dem Weißdorn. So beginnt es, unverändert aus der Quelldatei:

# Am Waldrand {#begin}

Der Pfad teilt sich vor einer Weißdornhecke, rechts von dir hörst du das Gluckern eines kleinen Bachs. {&Ein Krachen|Ein Knirschen|Stille} im Unterholz.

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

+ [Das Dickicht am Ufer untersuchen](#thicket)
+ [Zum Bach gehen](#brook)
+ {has("lantern")} [In den Spalt unter der Hecke klettern](#crypt.crypt) Du zwängst dich hinein, die Laterne voran.

Die Überschrift beginnt einen Knoten und gibt ihm die Kennung begin. Jeder Listenpunkt ist eine Wahl, der Link darin ihr Ziel. Ein Pluszeichen bedeutet, dass man die Wahl mehrfach treffen darf, ein Sternchen, dass sie verschwindet, sobald man sie genommen hat. Was hinter dem Link steht, erscheint erst, nachdem man gewählt hat. Geschweifte Klammern haben mehrere Aufgaben: {gold} setzt einen Wert ein, {&...|...} wechselt bei jedem Besuch reihum die Variante, und {has("lantern")} ist eine Bedingung. Den Weg in den Spalt bekommt nur angeboten, wer eine Laterne dabeihat. Auf GitHub erscheint die Datei als gewöhnliches Markdown, mit Überschrift und Liste.

Die Regelschicht

Werte, Gegenstände und Gegner werden einmal in YAML festgelegt, bei der Gruft in der Datei book.yaml. Der Fließtext ruft sie nur noch auf. Ein Auszug:

stats:
  skill:   { name: { de: Geschick, en: Skill },    start: "roll(1,6) + 6",  max: start }
  stamina: { name: { de: Ausdauer, en: Stamina },  start: "roll(2,6) + 12", max: start }

enemies:
  goblin: { name: { de: Goblin, en: Goblin }, skill: 6, stamina: 6, flee_after: 3 }

death:
  when: "stamina <= 0"
  goto: crypt.death

Daraus baut die Laufzeit den Charakterbogen, würfelt die Startwerte aus und prüft nach jeder Änderung und jeder Kampfrunde, ob die Figur noch lebt. Im Text steht für den Kampf nur noch der Gegner und wohin Sieg, Niederlage und Flucht führen:

!combat goblin
  win  -> chamber
  lose -> death
  flee [Zurück durch den Spalt fliehen](#start.begin) Du lässt mehr als deinen Stolz zurück.

Voreingestellt sind die Regeln von Fighting Fantasy: Eine Probe wirft zwei Würfel und gelingt, wenn die Summe den Wert nicht übersteigt. Fast alles daran ist aber ein Ausdruck, den ein Buch überschreiben kann. Ein W20 gegen einen Schwellenwert wie in heutigen Rollenspielen, Prozentwürfe wie in Rollenspielen der frühen Achtziger oder ein Buch, das fast ohne Würfel auskommt und mit Zuständen und einer Uhr arbeitet: Jede dieser Varianten wurde kompiliert und gespielt.

Zwei Sprachen, eine Struktur

Die meisten Beispielbücher gibt es auf Deutsch und auf Englisch. Dabei gilt eine feste Regel: Übersetzungen enthalten nur Text, keine Logik. Die Struktur, also Knoten, Wahlen, Bedingungen und Ziele, steht allein in der Standardsprache. Jede weitere Sprache ist ein Katalog der Absätze und Wahlen, in derselben Reihenfolge wie im Original. Die englische Fassung des Waldrands enthält deshalb keinen einzigen Link:

# At the Forest Edge {#begin}

The path forks before a thorn hedge; to your right you hear the gurgle of a small brook. {&A crack|A crunch|Silence} in the undergrowth.

You carry {gold} gold pieces and a luck of {luck}.

* Search the thicket by the bank
* Go to the brook
* Climb into the gap under the hedge

You squeeze in, lantern first.

Die Sternchen sind hier nur Listenpunkte. Ob eine Wahl bleibt oder verschwindet, legt die deutsche Fassung fest. Eine Übersetzung kann die Geschichte so nicht versehentlich umbauen. Braucht eine Sprache doch einmal eigene Logik, etwa für einen Plural, darf sie einen ganzen Knoten ersetzen, und das Prüfwerkzeug zeigt jede solche Stelle an.

Prüfen statt hoffen

Ein verzweigtes Buch lässt sich nicht Korrektur lesen wie ein Roman. Dafür gibt es zwei Befehle. lint meldet unerreichbare Knoten, tote Verweise und Sackgassen. simulate spielt Hunderte Partien mit zufälligen Entscheidungen durch und berichtet, wie sie ausgehen. So fiel im Haus hinter dem Moor auf, dass der Angst-Wert jeden zweiten Besuch desselben Raums bestrafte.

Das Werkzeug selbst hat keine Abhängigkeiten und keinen Build-Schritt, Node 20 reicht. Ein Buch lässt sich als eine einzige HTML-Datei exportieren, dazu kommen höchstens seine Bilder. Sie läuft ohne Netzwerkverbindung. Außerdem gibt es eine Erweiterung für VS Code, die das Buch ab dem Knoten abspielt, in dem der Cursor steht, und ein Swift-Paket, mit dem eine iOS-App ein Buch einbetten kann.

Die Bücher auf dieser Seite

Vier Bücher lassen sich hier im Browser spielen:

  • Die Gruft unter dem Weißdorn: das Einstiegsbuch, zwei Kapitel, ein Goblin, zwei Enden, in wenigen Minuten durch.
  • Das Haus hinter dem Moor: 48 Stationen, vier Enden und ein Angst-Wert, der mitzählt.
  • Brüder dunklen Rufes: 69 Stationen, drei Enden, als einziges nur auf Deutsch. Das Abenteuer stammt aus Folge 47 des Rollenspiel-Podcasts Over the Hills. Ich habe es nacherzählt, kein Satz der Folge steht im Buch.
  • The Intercept: ein importiertes Buch, dazu gleich mehr.

Neben jedem Spiel steht der Markdown-Quelltext, schreibgeschützt und immer an der Stelle, an der die Geschichte gerade steht. Man sieht also, welche Zeilen den Absatz erzeugt haben, den man gerade liest. Was hier läuft, ist ein fester Stand des Projekts, nicht zwingend der neueste. Einen Überblick über die Sprache gibt die Seite Die Sprache hinter den Büchern.

The Intercept: ein fremdes Buch als Probe

Wer Sprache und Geschichten gleichzeitig schreibt, biegt eine Geschichte leicht so hin, dass sie passt. Deshalb liegt unter den Beispielen ein Buch, das nicht für Story Weaver geschrieben wurde: The Intercept, ein kleines Demospiel, das inkle für ink gebaut hat. Es steht unter MIT-Lizenz, Copyright 2016 inkle Ltd.

Abgetippt wurde es nicht. Es kam über story-weaver import herein. Der Importer liest eine ink-Datei und schreibt dieselbe Geschichte in Story Weaver. Was eine direkte Entsprechung hat, übernimmt er. Was es in Story Weaver nicht gibt, etwa Threads, Listen und externe Funktionen von ink, meldet er mit Zeilennummer und lässt es weg.

Heraus kam ein Buch mit 133 Stationen und 14 Enden. Jede Station ist erreichbar, eine Sackgasse gibt es nicht. Es ist das einzige Beispiel ohne Regelschicht. Würfel, Kämpfe und Gegenstände fehlen, es gibt nur Zustände, die sich merken, wie man im Verhör geantwortet hat. Damit prüft es die erzählende Hälfte der Sprache an Text, den niemand für sie geschrieben hat. Der englische Originaltext bleibt Wort für Wort unangetastet, die deutsche Fassung liegt als Übersetzung daneben. Auch die Lizenzen bleiben getrennt: Das Buch trägt inkles MIT-Vermerk, die Laufzeit die MPL-2.0 von Story Weaver.

Was bewusst fehlt

Ein Buch in Story Weaver enthält keine Gestaltung. Keine Schriften, keine Farben, keine Beschriftung für den Angriffsknopf, keinen Hinweis, wie ein Wert zu zeichnen ist. Das gehört der Umgebung, die das Buch abspielt, ob Webseite, App oder Terminal. Ein Buch, das sein eigenes Layout mitbringt, lässt sich nicht mehr ohne Weiteres woanders abspielen.

Fertig ist die Sprache nicht. Die Spezifikation ist ein Entwurf in Version 0.8. Wer ein Buch schreiben will, fängt am besten mit der Gruft an und legt die Spezifikation daneben.


Offenlegung: Story Weaver ist mein eigenes Projekt. Dieser Text ist ein Blick hinter die Kulissen, keine neutrale Besprechung.

Quellen

  • Tobias Reithmeier: Story Weaver, Repository mit Spezifikation, Compiler, Laufzeit und Beispielbüchern, MPL-2.0
  • inkle: ink - inkle's narrative scripting language, ink als Erzählsprache für Spiele, MIT-Lizenz, eingesetzt in 80 Days und Sorcery!
  • Twine: Twine, Open-Source-Werkzeug für nichtlineare Geschichten mit den Story-Formaten Chapbook, Harlowe, Snowman und SugarCube
  • inkle: The Intercept, das ink-Demospiel, das in Story Weaver importiert wurde, MIT-Lizenz
  • Over the Hills: #47 Adventure Docs 1: Brüder dunklen Rufes, die Podcastfolge, auf der das gleichnamige Spielbuch beruht