Narratomidocs
Writing

Set

The beat that writes a variable: assign, toggle, add, and remove.

A set beat writes one variable. It has no text and the reader never sees it fire; it is the beat that makes the story remember something.

Declare the variables first, or declare one from inside the beat. Either way, see Variables for scopes and types.

Fields

FieldTypeRequiredWhat it does
idstringyesStable beat id.
kind"set"yesThe discriminator.
variablestringyesThe variable's name, not its id.
valuevalueyesThe value to write. Its type must match the declaration.
op"assign" | "add" | "remove" | "toggle"noAbsent means assign.

The beat row reads left to right as a sentence: variable, operator, value. The operators offered depend on the variable's declared type.

Declared typeOperators offered
flag=, toggle
number=, + add, − subtract
list, or multi-select options=, + add, − remove
text, single-select options, cast, asset=

Subtract is a face, not a stored op. It saves as add with a negated value, so a bundle only ever contains assign, add, remove and toggle.

What each operator does at play time

assign overwrites, whatever the current value is.

toggle flips a flag. It ignores value entirely. If the flag has never been set (or is somehow holding a non-boolean), toggle does nothing rather than inventing a starting side.

add on a number increments it, and only when both the current value and the written value are numbers.

add and remove on a list move exactly one entry, and the list is a set, not a tally. Adding an entry that is already there does nothing; removing one that is not there does nothing. Both directions are idempotent, so two scenes that both grant the same clue leave one clue, and count(bag) agrees with what the reader can see. New entries append, so order is the order you added them.

Wanting five arrows in a quiver is a number variable, not five entries in a list. The list type is "the things you are carrying", one of each.

Declaring a variable without leaving the beat

The variable picker ends with + new variable…. Pick it, type a name, choose a type and a scope, and press the confirm button. The declaration is routed to the same place the variables panel would put it: project and persistent scopes go on the project, chapter and scene scopes go on the open chapter.

A stored name that matches nothing stays visible in the picker as "name (missing)" rather than being silently cleared, so you can see what broke and rebind it.

Errors

ErrorCause
UNDECLARED_VARIABLEvariable names nothing declared anywhere in the project.
SET_TYPE_MISMATCHAssigning a literal of the wrong type (set coins = "many"), toggling something that is not a flag, or adding a non-number to a number.
LIST_TYPE_MISMATCHAdding or removing an entry on a non-list variable, assigning a list to a scalar, or a scalar to a list.
UNKNOWN_OPTIONS_CHOICEA value aimed at an options variable that is not one of its declared choices.
UNKNOWN_LOOK_NAMEA value aimed at a cast member's look variable naming none of that member's looks. "" (back to untinted) stays legal.

Every one of these describes the same failure: code that runs and quietly does nothing. A set coins = "many" compiles fine as JSON and then walks the story into a state no condition can ever match. That is why they are errors rather than warnings.

Where set beats can live

At the top level of a scene, and inside a choice option's inline body. The inline case is the usual one: an option that grants an item is a one-line reply plus a set beat, with no new scene and no new edge.

choice
  1. "Take the crowbar"   inline body:
       set  bag  + add  "crowbar"
       line  You slip it into your coat.
  2. "Leave it"           inline body:
       line  Someone else's problem.

A worked pair

The walkthrough's beats chapter does this in four beats: a set beat writes flag wtKey = true, and the choice two beats later carries an option conditioned on wtKey == true. Without the set beat the option is hidden or greyed out, depending on the option's lock setting. That is the whole variables system in one trick, and it is worth building once by hand.

To see the value while you write, put the variable on the HUD or drop a {token} into a line: see Tokens and the HUD.

On this page