# Expressions

An **expression** is a small piece of code that reads the game and produces a value. Every
rule you write is expressions: one to decide *whether* something should happen, others to
decide *how much*.

They appear anywhere the editor shows a formula box — a condition on a quest, a damage
amount, a field's maximum, the body of a hook.

```js
$.stat('might') * 2 + 5
```

That is a complete expression. It reads a stat and does arithmetic. There is no `return`,
no function wrapper, and no semicolon needed.

## Everything hangs off `$`

`$` is the only thing in scope. It carries the whole readable world:

```js
$.subject.name          // who this rule is about
$.subject.health        // their current hit points
$.player.fields.satiety // a declared field on the host player
$.turn                  // which turn it is
$.timed                 // whether this world has a clock at all
```

Reading something that does not exist gives you nothing back rather than an error — which
matters more than it sounds. See [Missing values](/docs/missing-values), because it is the
single most common way a rule silently never fires.

## The two halves

Reading the world splits into **paths** and **questions**.

- **[Reading values](/docs/reading-values)** — `$.subject.health`, `$.event.minutes`,
  `$.stat()`, `$.field()`. Things that give you a number or a name.
- **[Asking questions](/docs/questions)** — `$.hasItem()`, `$.alive()`, `$.hasPlugin()`.
  Things that give you true or false.

## Where expressions run

In a sandbox with a fuel budget and frozen globals. Three consequences worth knowing:

**An infinite loop is killed, not hung.** The turn survives; your rule stops.

**There is no channel between two expressions.** One rule cannot leave a variable lying
around for another to pick up. If two rules need to share state, that state is a
[field](/docs/fields).

**An expression that throws evaluates to nothing.** The caller falls back to its default
rather than the turn crashing. This is why a broken rule looks like a rule that does not
fire, instead of an error message.

## Next

Start with [Reading values](/docs/reading-values). If you are writing a hook body rather
than a single formula, read [Rule bodies](/docs/rule-bodies) first — the rules are
different and the differences are where people get stuck.
