Variables

A variable is a named binding holding a value. Variables live in the variable namespace, read with the $ sigil, and are distinct from the command namespace (Declarations and scope). They are also distinct from persistent entity state, which is not a variable at all and is reached only through store / recall (below).

What a variable can be

A variable holds a single value of any type (Types). All variables are lexical: read with $name (or ${name}) and resolved to the nearest enclosing binding of that name. Bindings come from block parameters, let/const locals, handler-injected names, and top-level const; the full resolution rules are in Declarations and scope.

Reading a variable

$name (or ${name}) evaluates to the value of the nearest binding of name in the lexical chain.

$actor          # the creature that triggered the current handler
$self           # the script's owner
${count}         # braced form, identical meaning
$room           # a let/const local or a block parameter

A name with no binding anywhere in the chain is a compile-time error ("undefined variable $name"). A handler-injected name whose event does not provide it (e.g. $actor for a tick) is unbound, and reading it is a run-time error.

Declaring and mutating locals — let and set

let name value      # introduce a new local in the current scope
set name value      # mutate an existing binding, searching outward
let counter 0
set counter [+ $counter 1]      # mutates the let above

The name in let/set/const is written without the $ sigil — the sigil appears only when reading.

Because set searches outward, an inner block can mutate a binding owned by an enclosing scope — the basis of the closure-counter idiom (Declarations and scope).

Locals do not persist across invocations

Locals are fresh per invocation; cross-invocation state belongs in persistent entity state. See Scope lifetime.

Persistent entity state — store and recall

Persistent state is a set of string-keyed values (slots) attached to a game entity (mobile, object, or room). It is not part of the variable namespace and is never found by $name lookup.

store entity slot value     # write a slot
recall entity slot          # read a slot (null if never stored)
forget entity slot          # delete a slot (recall returns null again)
store $self 'state' 'gossip'
require [eq [recall $self 'state'] 'gossip']

store/recall is how scripts keep state between invocations (Locals do not persist across invocations). store/recall operate only on these script-defined slots; they do not touch the creature's actual game attributes (hp, position, vnum, weight, …), which are exposed read-only through builtins (Built-in functions). A store $target "hp" 50 writes a slot named hp unrelated to the creature's actual hit points.

A companion forget $entity slot deletes a slot; a subsequent recall returns null again. The tag/untag/hastag builtins (Built-in functions) are independent of store/recall.