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:
- arithmetic
+ - * /, comparison== != > < >= <=, logicand or not(or&& || !), parentheses - numbers,
true/false,"strings" - any declared var, stat, or currency by name
- a skill name means its current total, including equipped items
has(item)is true while the player holds the item
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.