# Steps

Reading the world is an [expression](/docs/expressions). **Changing** it is a **step**, and
a rule body is a list of steps.

```js
$.adjustField({ field: "satiety", by: -1 })
$.damage({ amount: 3 })
$.narrate("the wound closes over")
```

## The vocabulary

| Step | What it does |
|---|---|
| `$.adjustField({ field, by })` | Move a field **by** an amount |
| `$.setField({ field, to })` | Set a field **to** a value |
| `$.adjustStat({ stat, by })` | Move a stat by an amount |
| `$.setStat({ stat, to })` | Set a stat to a value |
| `$.damage({ amount })` | Deal damage |
| `$.heal({ amount })` | Heal |
| `$.applyEffect({ effect })` | Apply a status effect by name |
| `$.give({ item, quantity })` | Give an item |
| `$.grantXp(n)` | Award experience |
| `$.setWorldState({ key, value })` | Write a world flag |
| `$.passTime(minutes)` | Advance the clock |
| `$.narrate(text)` | Tell the narrator something happened |
| `$.refuse(reason)` | Stop the player's action |
| `$.veto(reason)` | Stop one proposed event |

Most steps take an optional `target` — `"subject"`, `"player"`, `"target"` — defaulting to
whoever the rule is about.

## by vs to

`adjustField` moves a value **by** an amount. `setField` sets it **to** one.

```js
$.adjustField({ field: "fever", by: 1 })   // one worse than before
$.setField({ field: "fever", to: 1 })      // exactly 1, whatever it was
```

Same pair for stats: `adjustStat` / `setStat`. Getting these backwards is a quiet bug —
a fever that never climbs past 1 rather than one that never stops climbing.

## refuse vs veto

**`refuse`** stops the action the player attempted.
**`veto`** stops one specific *event* that was proposed.

If you are answering another plugin's event — `rest:sleep`, say — use `veto`. Using
`refuse` there tells a player standing still that hunger clawed them out of a sleep they
never started.

## Narration never sees numbers

```js
$.narrate("the fever's grip loosens")   // good
$.narrate("fever reduced by 2")         // wrong shape
```

The narrator is told what happened in prose, never the mechanics. Numbers, cooldowns and
turn counts do not reach it — that is deliberate, and it is why the writing stays in voice.
Write the sentence you want a player to read.

## Zero-rate damage still costs a point

`$.damage({ amount: 0 })` does not do nothing — damage floors at 1. If a dial can legitimately
be tuned to zero, branch around the step rather than passing zero into it:

```js
if ($.dial('starvationDamagePerHour') > 0) {
  $.damage({ amount: $.dial('starvationDamagePerHour') })
}
```

## Next

[Rule bodies](/docs/rule-bodies) — the syntax rules a body must obey, which are stricter
than they look.
