Curly-brace blocks ({...}) handle variables, conditionals, and loops directly inside chapter content. Default variables are declared in the Variables Manager, but more variables can be added by your code during runtime.
Printing a variable
{$playerName}
Shorthand for printing a single variable. For more control, use print:
{print($playerName)}
{print($playerName, "the traveler")}
{print($playerName, fallback="the traveler")}
{print($playerName, fallback="the traveler", cap=true)}
- The first form prints the variable, or nothing if it's
undefined/null. - A second positional argument (or
fallback=) is shown instead when the variable is unset. cap=truecapitalizes the first letter of the result.
Setting a variable
{set($relationship, $relationship + 1)}
{set($playerName, "Sam")}
Writes straight through to the project's variable store (Store.Set, see Coding), so a Store.Register listener in a scene script sees the change immediately, and {$var} prints elsewhere reflect it on their next render.
For an object variable, add the field after a dot to change only that field:
{set($player.hp, $player.hp - 1)}
Conditionals
{if ($metAlice == true)
Alice waves at you from across the room.
} else {
A stranger glances at you, then looks away.
}
The else block is optional. Conditions are evaluated as JS-like expressions (see "Expression syntax" below): comparisons, boolean logic, arithmetic, and ternaries all work.
To check more than one condition, add else if blocks between the if and the else:
{if ($gold >= 100)
The merchant bows and shows you the back room.
} else if ($gold >= 10) {
The merchant points you to the cheaper shelf.
} else {
The merchant waves you out of the shop.
}
The conditions are checked from top to bottom and only the first true one is shown, so put the strictest condition first. Each else if needs its condition on the same line as the else if, and its content inside { }. You can add as many as you like, and the final else is still optional.
Loops
{for ($i in range(0,3))
Item number {$i}
}
range(start, end)expands tostart, start+1, ..., end-1.- You can also loop over an actual array variable:
{for ($item in $inventory) ... }. - Looping over a plain number counts from
0up to, but not including, that number.
Character variables
Characters and their variants can have their own variables, set up in the Character Manager. Logic blocks run before any [SetCharacter(...)] in the node, so logic picks its character separately, with character:
{character(alice)}
{character(alice, variant=smiling)}
The first targets Alice, and the second targets Alice and her smiling variant. The target lasts until another character block changes it, even across nodes and chapters, and {character()} clears it. It doesn't change the character on screen, so use [SetCharacter(...)] for that.
Once a character is targeted, $char holds its variables and $variant holds its variant's variables. They work like any other variable:
{character(alice, variant=smiling)}
Alice's trust is {$char.trust}.
{set($char.trust, $char.trust + 1)}
{if ($variant.blushing)
Alice looks away.
}
To use a character or variant without targeting it, put its key in brackets:
| Expression | Variables of |
|---|---|
$char |
the target character |
$char(bob) |
Bob |
$variant |
the target variant |
$variant(angry) |
the target character's angry variant |
$variant(bob, angry) |
Bob's angry variant |
{print($char(bob).trust, 0)}
{set($variant(bob, angry).mood, "calm")}
setneeds the variable's name after the dot, like$char.trust. A variable that doesn't exist yet is created.- If there's no target, or the character or variant doesn't exist, reading a variable gives nothing (so
printshows its fallback) and a warning is logged. - Changes are saved with the game, and scene scripts see them in
Assets.GetCharacter(key).variables. charandvariantare reserved, so project variables and loop variables can't use these names.
Random numbers
randomInt picks a random whole number and random picks a random decimal number. Both ends of the range can be picked.
| Expression | Result |
|---|---|
randomInt() |
0 or 1 |
randomInt(6) |
a whole number from 0 to 6 |
randomInt(4, 6) |
a whole number from 4 to 6 |
random() |
a decimal number from 0.0 to 1.0 |
random(6) |
a decimal number from 0.0 to 6.0 |
random(4, 6) |
a decimal number from 4.0 to 6.0 |
They work anywhere an expression does, and variables can be used for the numbers:
{if (randomInt(1, 4) == 1)
A bird lands on the fence.
}
{set($gold, randomInt($minGold, $maxGold))}
Each call picks a new number. To use the same number more than once, store it with set first:
{set($roll, randomInt(1, 6))}
You rolled a {$roll}.
{if ($roll == 6)
A perfect roll!
}
The Insert Random Integer and Insert Random Float buttons in the editor toolbar add a random if block for you.
Logging from content
{log($someVariable)}
Prints the evaluated value to the console via the runtime logger. Handy for debugging a chapter without needing to jump into a scene script.
Expression syntax
Expressions (conditions, set values, loop ranges) support a restricted, JS-like grammar: arithmetic (+ - * /), comparisons (< > <= >= == !=), boolean logic (&& ||), ternaries (? :), and string/array/object literals. $varName anywhere in an expression is substituted with that variable's current value before evaluating, and so are $char and $variant from Character variables above. The random() and randomInt() functions from Random numbers above can be used in any expression.