Wit

An interactive script

Author a branching game or gamebook page where character stats, a wounded-check, and an inventory are data and logic in the document — not hand-edited for every state. This whole file builds green.

Step 1 — Character state as data

A comma-free single-line record holds the scalars; a separate collection holds the inventory, because list items can't live inside a record field (the commas would split them).

#hero: { name - Vera, gold - 12, status - wounded } !!
#pack: [torch, rope, a letter you should have burned] !!

Step 2 — Scene vocabulary as definitions

Block-form definitions with captures. Pass display text as a capture, not as a body splice — a splice wraps inline content in stray paragraphs inside your list items.

#scene ||title||
@h2 ::title:: h2@
scene#

#warn ||text||
@aside::text:: aside@
warn#

#choice ||goto, text||
@li::text:: (to ::goto::) li@
choice#

Step 3 — Scene heading and prose

Splice a stat into a sentence with dotted access.

@scene |title The Crossroads|

@hero.name, the road forks beneath a broken signpost. You are carrying @hero.gold gold.

Step 4 — A conditional beat

Compare a string field to a literal with is.

(if @hero.status is wounded)
@warn |text You are wounded — the dark path may kill you.|
(end)

Step 5 — Choices and inventory

Build the choices from the choice definition, then iterate the pack.

@strong Choose: strong@
@ul
  @choice |goto village| |text Take the lit path|
  @choice |goto tower| |text Take the dark path|
ul@

@strong Pack: strong@
@ul
(each @pack as item)
@li @item li@
(end)
ul@

Build

wit build scene.wit --fragment
Result.

The heading and prose splice Vera and 12 into place; the wounded-check fires and prints the warning aside; the two choices render as list items; and the pack iterates to three items — all verified.

Pitfalls

  • Conditionals compare strings only. The operators are is and equals (synonyms) — there is no less-than, greater-than, not, and, or, or contains.
  • Model status as a string, not a number. A check for low compares against the literal text low; it will not match the number 8. Use a status string like wounded, or an existence flag that fires when a field is present.
  • Prose interpolation is a mirage. A capture hole written in ordinary prose renders literally. Use dotted access (@hero.name) in prose; a capture hole is live only inside a definition body.
  • Pass display text as a capture. Feeding it through a body splice fragments it into paragraphs inside your list items — a |text …| capture stays clean.

Variations

Use an existence-flag conditional; emit several scenes from a master file, as in A manuscript in chapters; group the choices in a wrapper definition.

See also

Creative writing

covers flat scenes without logic; Core vocabulary lists the nodes used here.