docs

the complete reference for the script language. for a guided start, open the editor: it loads a sample game that uses everything on this page.

the shape of a script

A game is one plain-text file with two regions: declarations at the top (what exists), then passages (what happens). The first passage is where the game begins. Lines starting with # are comments.

@title My Game
@author Me

skill nerve "Nerve" #8fb3a8 = 2
char jekyll "Dr. Jekyll" #f0c987

== start
jekyll: "Ready?"
* "Ready." -> begin

== begin
-> END

declarations

These only work above the first passage. Declaration lines may carry a trailing # comment.

@title / @author

Shown on the play page header and used for the share link preview.

@title Dead Reckoning
@author Fable

@start

Begin at a specific passage instead of the first one defined.

@start cockpit

@points

Shows a build screen before play: the player distributes this many extra points on top of your declared skill values. max caps any one skill at creation. Restarting returns to this screen. Without this line, play begins immediately.

@points 4 max 6

@wardrobe

Whether players may freely equip and unequip items. The default is locked: players can see their gear but only change it when your script allows it (see the ~ wardrobe effect). open leaves it free for the whole game.

@wardrobe open

@reveal

Line pacing on the play page. click (the default) reveals one line per tap, space, or enter. paced reveals lines on a timer, and a tap skips ahead. off shows each new passage at once. The editor preview is always instant.

@reveal paced

@fail

A fail rule: whenever an effect changes state and this condition is true, the run fails. The player sees your message and returns to the last checkpoint (see ~ save), or restarts if there is none. You can declare several rules. A choice can also fail directly with the FAIL target.

@fail resolve <= 0 "The sand is soft as snow, and warm."

@bg / @accent / @font

Restyle the player for your game. @bg takes a six-digit hex color; panel, border, and dim-text shades are derived from it, and light backgrounds get dark text automatically. @accent recolors the highlights. @font is one of book (the default), mono, serif, sans, humanist.

@bg #10141d
@accent #c8a96a
@font serif

skill

A skill is three things at once: a number the player can grow, a voice that can speak lines, and the thing dice checks roll against. The trailing number is its starting value (2 if omitted); the color is used wherever the skill appears.

skill sangfroid "Sang-Froid" #8fb3a8 = 2

char

A character who can speak. The first word is the short id you type in dialogue lines; the quoted name is what readers see. Declaring a you character is a common way to give the protagonist spoken lines.

char marchand "Marchand" #f0c987
char jekyll "Dr. Jekyll" #b8c4cc
char you "You" #e0d6c3

item

Items with skill modifiers are equipment: players can equip them when the wardrobe is open, and the modifiers apply to every roll and total while equipped. Items without modifiers are plain possessions: no equip box, but has(item) still works in conditions.

item jacket "Flying Jacket" sangfroid+1 hands-1
item chart "Soaked Chart"

currency

One per game. Shows at the bottom of the player's status panel and powers the [pay]/[earn] choice tags and ~ pay/~ earn effects. It behaves as a normal variable in conditions. It does not have to be money.

currency water "Water (cups)" = 0

var / stat

Both declare a named value: a number, true/false, or a "string". A stat additionally appears in the player's status panel; a var is hidden bookkeeping.

stat resolve = 3
var knows_drift = false

inside a passage

== name

Starts a passage. Names are single words (letters, digits, underscores). :: also works, for Twine muscle memory.

== night_walk

narration

Any plain line is narration. If a narration line would be mistaken for another kind of line (it starts with a bracket, or a word followed by a colon), start it with | to force it.

The desert at night is black sand under black sky.
| Warning: the well is dry.

dialogue

A declared character or skill id, a colon, and the line. Skills speak in their color with a bold name; using an undeclared name is a compile error (it is usually a typo).

marchand: "I'm not dead. That's the main thing."
sangfroid: Say it plainly and do not say it again.

? passive checks

An interjection that appears only if the skill's current total (including equipment) meets the number. No dice: passives are deterministic, and each fires at most once per run.

? senses 7: Petrol, but faint, and fading. She didn't burn.

-> jumps

Go straight to another passage. END finishes the game; FAIL triggers the fail state. With a line gate in front, a jump becomes conditional, which is how one passage can quietly route to different scenes.

-> dawn
[has(chart)] -> shortcut

line gates: [condition] and [once]

Any non-choice line (narration, dialogue, effects, jumps) can carry gates in front. A condition gate skips the line when false. [once] runs the line at most once per game, however often the passage repeats. This is how one passage varies with state instead of being cloned.

[once] Silence, enormous and sudden.
[knows_drift] reckoning: You are lower than the dial says.
[resolve < 2] ~ set shaky = true

choices

basics

Choices start with * and end with a target. All choices in a passage are offered together after its lines. Choices the player has picked before are shown in red; they stay selectable unless marked [once].

* Wait for dawn -> dawn
* Walk out now, into the dark -> night_walk

bracket gates

Brackets before the text modify the choice, and they combine freely: any number of conditions (all must hold), plus at most one check and one cost, plus [once]. A hidden condition hides the choice entirely; a spent [once] stays visible but locked.

* [has(chart)] Follow the chart's legible corner -> walk_end
* [once] Go through the wreck, pocket by pocket -> salvage
* [once] [mae_trusts] [pay 10] Buy her silence -> quiet

skill checks: [white] and [red]

A check rolls dice when chosen and needs two targets: success, then failure, separated by |. The tag on the choice shows the skill, difficulty, and live success odds. white checks can be retried after the skill itself improves; red checks get one attempt ever, and the whole choice is outlined in red as a warning.

* [white reckoning 10] Run the numbers again -> drift_yes | drift_no
* [red hands 12] Fly her into the ground like a landing -> wreck | wreck_hurt

costs: [pay] and [earn]

A pay choice shows its price, greys out when the player can't afford it, and charges on selection. [earn] is the reverse. A cost and a check can share a choice; the cost applies on the attempt, then the dice decide.

* [pay 1] Drink. One cup. -> drink
* [pay 5] [white sense 9] Ante up and read the table -> win | lose

effects

Effect lines start with ~ and change state as the passage plays. All accept line gates.

~ set

Assign any variable, stat, or skill from an expression. Silent: nothing is shown to the player.

~ set resolve = resolve - 1
~ set knows_drift = true

~ give / take / equip / unequip

Move items in and out of the player's possession. give and take announce themselves; equip also gives the item if needed and puts it on regardless of the wardrobe state.

~ give torch
~ equip jacket
~ take orange

~ pay / earn

Spend or gain currency, with a visible line. The amount can be an expression. Requires a declared currency.

~ earn 2
~ pay toll

~ points

Grant skill points. The player allocates them immediately on a +/− screen, anywhere they like, before play continues.

~ points 1

~ skill

An author-directed change to one specific skill, up or down, announced to the player. Raising a skill this way can reopen its failed white checks; this and ~ points are the two ways through that lock.

~ skill sangfroid -1

~ save

A checkpoint. Progress persists in the reader's browser; returning visitors get CONTINUE or START OVER, and fail states return here. There is no player-initiated saving: you decide where the mercy goes.

~ save

~ wardrobe

Open or close the player's ability to change equipment. Typical rhythm: open during safe scenes, close before commitments.

~ wardrobe open
~ wardrobe close

expressions

Conditions, ~ set, ~ pay/~ earn amounts, and curly interpolation all use the same small language:

Inside narration, dialogue, or choice text, {expression} is replaced with its value. Braces that don't parse are left alone.

* [water >= 2 and not has(chart)] Ration carefully -> morning
You fill your pockets: raisins, the thermos with its {water} cups.

how play works

dice

A check rolls 2d6 and adds the skill's total (base plus equipment). Meet or beat the difficulty to succeed. Double sixes always succeed; double ones always fail. The roll is shown itemized, and choices display their live odds.

Difficulty names, for flavor and calibration:

6 Trivial   8 Easy   10 Medium   12 Challenging
14 Formidable   16 Legendary   18 Heroic   20 Impossible

white checks, red checks, and the lock

A failed white check locks, marked failed, until that skill itself is upgraded past the value it failed at (via ~ points or ~ skill). Equipment improves rolls but cannot reopen a failed check: the mind that failed has to grow. A passed check disappears. A red check is once ever, whatever happens.

checkpoints and failure

When a @fail rule triggers or a choice hits FAIL, the run ends with your message and one button: return to the last ~ save, or start over if none was reached. Checkpoints live in the reader's browser, per game; republishing a game invalidates old checkpoints. Finishing a game clears its checkpoint.

reading flow

By default each tap reveals one line, and everything above the newest line dims so the reader's place is always the bright edge. Choices appear when the passage has fully arrived. Already-picked choices show in red.

publishing and exporting

PUBLISH puts your game at a bare link you can share; readers play in the browser with no account, and you can republish updates to the same link or unpublish it from the same browser you published from. EXPORT downloads a zip holding a self-contained playable index.html (it runs offline, forever, with no dependence on this site) plus your script as source.txt. IMPORT reads that zip, or any plain .txt, back into the editor. The zip is also exactly what itch.io's "HTML project" upload wants, if you'd like to host or sell your game there.

What you publish stays yours. Stories are never used for AI training, sold, or mined for data.