ExcitingPress ReviewInteractive fiction · gamebooks

Tools & Platforms

Knots, Diverts and Stitches: A Reader's Guide to Ink Scripts

You do not need to program to read an ink script. Here are the four marks that carry almost all of its structure, explained from the official writer's manual.

Some games ship their narrative source. Others publish it, or you meet it in a tutorial. Either way the file extension is .ink, and the first reaction is usually that it looks like code. It mostly is not. Ink describes itself on its own project page as “markup, not programming”: text comes first, and logic is inserted inside it. That ordering is the whole reading strategy.

Start with the asterisk

The single mark that does the most work is *, which offers the player a choice. The manual’s smallest example is two lines:

Hello world!
*	Hello back!
	Nice to hear from you!

Play it and the choice is offered, and if you take it, the text of the choice appears again in the output before the reply. By default ink echoes what you picked.

Then comes the bracket. If the choice text is written inside square brackets — * [Hello back!] — the phrase is not printed into the response. The manual calls this suppressing choice text, and describes the purpose plainly: some games want to separate what you clicked from what happens.

Read a script with this in view and every asterisk becomes a question you can answer: is this choice spoken aloud or only executed?

Knots are paragraphs with names

The manual reaches for the gamebook analogy itself when introducing knots: sections are marked so the game can branch, “as an old-fashioned gamebook does with its ‘Paragraph 18’, and the like.” A knot begins with two or more equals signs and a single-word name:

=== back_in_london ===

Everything after that line belongs to the knot, until the next one. In a long script this is the only structural scaffolding you need to navigate: the file is a list of named chunks, and the names are chosen by the author to describe content.

One practical wrinkle the manual flags: content outside any knot runs automatically at the start, while knots do not. So a script made of knots needs an explicit way in, or nothing happens.

Diverts are the connective tissue

-> is a divert. The manual describes diverts as immediate movements that happen “without any user input” and are “invisible” to the player — they can even happen in the middle of a sentence:

=== hurry_home ===
We hurried home to Savile Row -> as_fast_as_we_could

This explains a reading experience that otherwise feels like a flaw. A paragraph that turns on a sixpence, a scene change with no transition, a sentence that finishes inside a different location: those are usually diverts. The author wrote the seam on purpose and trusted the reader to feel it as prose.

When you read a divert in a script, you are reading a decision about invisibility. The same content could have been a choice point. The author decided you should not be asked.

Branching and rejoining

The manual’s basic branching example is exactly what a gamebook reader would expect: three options at paragraph_1, each diverting to a different knot.

The more interesting example is the joining one. Three different routes — two spoken lines and one silent choice — all divert to knots that eventually reach the same as_fast_as_we_could knot, which continues the same sentence with glue. In play, you cannot see that the paths merged. You only see that each route had its own flavour and then the story continued.

That is the central craft lesson in the manual, and it is stated directly: with knots, options and diverts you get the basic structure of a choose-your-own game, and with diverts you can branch the flow and join it back up “without showing the player that the flow has rejoined.”

Why the flow is described as flat

The manual is unusually candid about the resulting shape. The flow is flat: no call stack, diverts are not returned from, and most scripts “bounce around in a spaghetti-like mess” until they reach an ending. In exchange, writers do not need boilerplate to add a branch, and they do not need to track state while writing.

For a reader, that has one immediate consequence. You cannot reconstruct the intended reading order from the file’s layout, because the file’s layout is the order the author typed, not the order you will experience. The paths live in the diverts, and the paths only make sense as a graph.

The ends matter

Finally, the ending marker. The manual notes that ink does not like loose ends and warns when flow runs out without a choice or divert. -> END is both a marker for the writer and an instruction to the compiler.

If you are reading a script to see how a game ends, -> END is where to look. It tells you where the author intended a story to stop being the player’s problem. If the ink form of a story has a form of the ending you experienced, that is where you will find it.

A four-mark reading pass

For a first pass through an unfamiliar ink script, do only this:

  1. Find the entry point — the text outside knots, or the first divert.
  2. List the knots by name and guess what each holds.
  3. Mark every * as a question and note whether it is bracketed or echoed.
  4. Follow diverts as edges; stop at -> END.

That is enough to sketch a story map on one page. Everything else — variables, sequences, functions — adds detail to a picture you already have.

Sources

This article is written for: A reader who found an .ink script online or in a game's files and wants to follow the story through the source without learning a programming language first.

AI assistance recorded as: AI draft, not edited. Review status: approved.