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 Two Wings Good @author Alaska Hoffman, 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, and can also pull a skill below
its starting value (down to zero) to spend those points elsewhere.
max caps any one skill at creation. Skill descriptions appear
here. 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. An optional quoted blurb at the end is shown on the character screen (and as a sidebar tooltip), so players know what they're choosing.
skill sangfroid "Sang-Froid" #8fb3a8 = 2 skill sangfroid "Sang-Froid" #8fb3a8 = 2 "Cold blood. The discipline to do the slow thing while the world goes fast."
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
What an item modifies decides which of three kinds it is:
- Equipment — a skill modifier
(
sangfroid+1). The player equips it from the wardrobe, and the modifier applies to every roll and total while it is worn. With no slot it stacks freely; aslotcaps how many of a kind can be worn (see below). - Consumable — a stat modifier
(
water+1). It sits under ITEMS with its effect shown, and the reader can click it any time to apply the change and spend one. - Key item — no modifier. A plain thing
you carry: nothing to wear or click, but
has(item)still gates on it (a chart, a letter, a key).
An item is one kind, not a mix: equipment or a consumable, never
both. All three stack and can be given in quantity
(~ give water 3); has(item) reads as the count.
item jacket "Flying Jacket" sangfroid+1 hands-1 # equipment (a skill) item cup "Cup of Water" water+1 # consumable (a stat) item chart "Soaked Chart" # key item (no modifier)
slot
A slot is a kind of equipment, and it caps how many of that kind can be
worn at once, so gear forces a choice instead of stacking. Declare a slot
with an id, an optional display name, and an optional limit. Then put items
in it by using the slot's name as the keyword, exactly like item
but slotted.
The limit defaults to 1: a slot that holds one thing, where
equipping a second item swaps the first out. Set a higher limit with
= N for a budget; once it is full, the next item you equip pushes
out the one you put on longest ago. Slots may be declared above or below the
items that use them, and each appears under EQUIPMENT in the sidebar with a
worn/limit tally.
slot hat # one hat at a time (limit defaults to 1) slot charm "Charms" = 3 # a budget: wear any three hat fedora "Felt Fedora" logic+1 esprit-1 charm ring "Brass Ring" physique+1
currency
One per game: the player's money. It sits at the foot of the sidebar and
shows as a float (340.00) so it reads as cash whatever you name
it, and it powers the [pay]/[earn] choice tags and
~ pay/~ earn effects. It behaves as a normal variable
in conditions. For non-money resources like water, ammo, or morale, use a
stat instead.
currency franc "Francs" = 0
var / stat
Both declare a named value: a number, true/false,
or a "string". A stat appears in the player's STATUS
panel; a var is hidden bookkeeping. Give a numeric stat
max N and the panel draws it as a row of filled/empty pips, a
gauge the player sweats toward zero; the value then clamps at that cap (the
floor stays open, so an @fail on <= 0 still
fires).
stat resolve = 3 max 5 # a 5-pip gauge, capped at 5 stat morale = 2 # a plain number 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 20] Slip the guard a few notes -> through * [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. If the item is in a
slot, equipping it obeys that slot's limit, swapping out the longest-worn piece
when the slot is full.
Items stack: give/take may carry a
count, the sidebar shows ×N, and has(item) stays true
while any remain. That makes a consumable — a
[has(water)] choice that does ~ take water plus
whatever the item should do (refill a stat, say).
~ give water 3 ~ take water # removes one; "Item lost" only when the last is gone ~ equip jacket
~ pay / earn
Spend or gain currency, with a visible line. The amount can be an expression. Requires a declared currency.
~ earn 50 ~ 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 how many of it you hold: truthy in a bare gate ([has(cup)]), or compared and printed as a number ([has(cup) > 1],{has(cup)})
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.
reader settings
The settings button in the header lets readers adjust text size or switch to a two-color e-ink view, saved on their device for every game. These sit on top of your theme and never change your file, so the same story stays readable however someone needs to read it. (E-ink mode replaces color-coded meaning with text, so a red check still reads as one even with no color.)
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.
A published game is pinned to the engine version it was made under. When andstar updates, a game you already shared keeps the exact look and behavior it had at publish time, so new features never disturb your back catalog. Republishing moves it to the current engine (which is what you see in the editor).
What you publish stays yours. Stories are never used for AI training, sold, or mined for data.