No active sessions yet.

No games yet.

No conversations yet.

No characters yet.

Reading values

Paths and readers that give you a number or a name — $.subject, $.stat(), $.field().

These give you a value. Compare them, add them, feed them to a step.

Stats: read by role, never by name

$.stat('might')

This is the one convention worth learning first. Stats are read by their role, not their display name. A game might call its strength stat "Might", "Brawn" or "Thew" — all three answer to might.

$.stat('brawn')       // breaks the moment someone renames the stat
$.stat('might')  // keeps working

A stat nobody has reads as 0.

Worked example: a damage bonus

A heavy weapon that hits harder in strong hands:

5 + $.stat('might') * 1.5

Fields: your own declared values

A field is a value you declared on an entity — satiety, infection, mana. Read one with $.field():

$.field('satiety')            // on the subject of this rule
$.field('satiety', 'player')  // explicitly on the host player
$.field('infection', 'target')

The second argument is 'player' or 'target'. Leave it off and you get the subject — whoever the rule is currently about.

A field nobody has reads as null, not 0. That difference decides whether your rule fires; see Missing values.

Worked example: a fever that worsens

Inside an onTimePasses hook, climbing faster the sicker you already are:

$.field('fever') * 0.1 + 0.2

Carried totals

$.carried('weight')

Sums a carryable field across everything the subject is holding. This is how encumbrance works, and it is the only reader that walks an inventory for you.

Dials: your plugin's tuning numbers

$.dial('foodDrainPerHour')

Reads one of your own plugin's dials — the numbers exposed in its editor panel so they can be tuned without editing code.

Never freeze a dial's value as a literal. Writing 0.4 where you meant $.dial('foodDrainPerHour') works perfectly until someone retunes the dial, at which point you have two numbers that disagree and no error anywhere. See Formulas and dials.

Time, and whether there is any

$.event.minutes   // how long this stretch was
$.timed           // whether this world has a clock at all

$.timed exists because not every game runs a clock, and a rule that charges an hourly rate in a clockless game is charging against the narrator's guess at how long the prose took — which has varied from 3 to 22 minutes for comparable turns. The safe shape:

$.timed ? $.dial('drainPerHour') * ($.event.minutes / 60) : $.dial('drainPerTurn')

See Minutes are not time for why this matters more than it looks.

Everything readable

Path Answers
$.subject The entity this rule is about.
$.subject.name The subject's name.
$.subject.location Where the subject is.
$.subject.health Current health.
$.subject.maxHealth Maximum health.
$.subject.dead Whether the subject is dead.
$.subject.fields The subject's declared fields, by key.
$.subject.bonds The subject's NPC bonds.
$.source Who caused it — attacker, user, emitter.
$.player The HOST player only. Use $.party for everyone.
$.player.name The host player's name.
$.player.health The host player's health.
$.player.fields The host player's declared fields.
$.party Every player — host and guests.
$.location Where this is happening.
$.world World state flags.
$.here What is in the current location.
$.mobs Creatures present.
$.turn The turn number.
$.timeMinutes Minutes on the world clock. Advances once per tick.
$.minutesPerDay Minutes in one day under this world's calendar (Earth: 1440).
$.timed Whether this world has a clock. Charge per hour where true, per turn where false — in a clockless game $.event.minutes is the narrator's estimate, not a measurement.
$.setting The game's setting.
$.killCount Kills so far.
$.event What the firing trigger carried. {} outside a hook, so a read there is undefined rather than an error.
$.item The item in play. Null outside the item-use path.
$.item.name The item's name.
$.item.state Shorthand for the item's state variable. Any other variable reads through $.item.tags.
$.item.fields The item's number variables.
$.item.tags The item's word variables, by key — $.item.tags.mood.
$.target The aimed-at entity.
$.target.name The target's name.
$.target.state Shorthand for the target's state variable.
$.target.fields The target's declared fields.

Payload fields ($.event.*) are listed per trigger on Hooks, because which ones exist depends on what fired.

Next

Asking questions — the true/false half of the API.