Expressions
The $ object, and how a rule reads the world before it decides anything.
An expression is a small piece of JavaScript that reads the game and gives back a value. You'll use them anywhere the editor shows a formula box: a quest condition, a damage amount, a field's maximum, a hook body.
$.stat('might') * 2 + 5
That's a complete expression. No return, no function wrapper.
Everything is on $
$ is the only thing in scope:
$.subject.name // who this rule is about
$.subject.health // their current hit points
$.player.fields.satiety // a field on the host player
$.turn // the turn number
$.timed // does this world have a clock?
Reads come in two kinds:
- Values:
$.subject.health,$.stat(),$.field(),$.dial(). - Questions:
$.hasItem(),$.alive(),$.hasPlugin(). True or false.
Reading something that doesn't exist gives you undefined or null, not an error. That's the
number one reason a rule silently never fires. Read Missing values.
The sandbox
Expressions run in a sandbox with a time budget:
- An infinite loop is stopped, not hung. The turn carries on; your rule doesn't.
- Expressions can't talk to each other. No variable survives from one rule to the next. If two rules need to share something, put it in a field.
- An expression that throws gives nothing back, and the engine uses its default. So a broken rule looks like a rule that didn't fire, not an error message.
Dice
$.random(), $.rollDie(6) and $.pick(weights) only work in a rule body (a hook, an
item rule). In a condition or an amount they return null.
The reason: conditions and amounts are worked out once per turn and reused. A roll there would be the same roll every time it was read. A body runs when things actually happen, so a roll there is a real roll.
Roll in the body, then act on it:
var rows = $.table('affixes')
var weights = {}
for (var i = 0; i < rows.length; i++) weights[rows[i].key] = rows[i].weight
var picked = $.pick(weights)
if (picked !== null) {
$.setField({ field: 'edge', to: $.row('affixes', picked).power })
}
$.pick takes a map of key to weight (zero or less is never picked), or a plain array to pick
from evenly.
A target that needs a random number, like "kill three to seven of them", should roll once when the quest opens and store the result. A gate that re-rolled every turn would never be reachable.
Next
Reading values. If you're writing hook bodies, read Rule bodies too.