Run-time
This chapter describes the observable behavior of a running script: how
return, break, continue, and the handler guards propagate; how a
script can span game ticks; the limits that bound an execution; and the
determinism a script can rely on.
Control-flow propagation
return, break, and continue do not merely end the current block —
they propagate outward through the constructs that invoked it until a
construct catches them. Ordinary fall-through off the end of a block, or
a return value once it reaches its catch site, simply yields that value
to the caller.
| Statement | Passes through | Caught by |
|---|---|---|
return [value] |
if, each, select, every, some, randomly |
the [block …] or bareword call site that invoked the block, or the handler invocation — yielding value there |
break / continue |
if, randomly |
the nearest enclosing each/select/every/some |
a failed require / satisfied unless |
(top-level handler statements) | handler processing, which advances to the next matching handler (Program initialization and execution) |
Within a loop, continue skips to the next element and break ends the
iteration; a return in the body unwinds out of the loop to its caller.
select produces its filtered elements on demand, so a break in the
predicate ends the filtered sequence and a continue drops the current
candidate.
break/continue do not cross into an outer loop: an inner
each/select catches them, so an inner break ends only the inner
iteration. To escape several levels at once, set a flag and test it. A
break or continue with no enclosing loop to catch it propagates out and
terminates the script.
Suspension and cross-tick execution
A script runs to completion within a single game tick unless it suspends
itself with pause n, which suspends the running script for n ticks
and then resumes where it left off, with its locals intact.
after enter {
do "bow $actor"
pause 3
do "emote points to a sign."
}
Execution limits
Every execution is bounded so that no single script can stall the game:
- The total amount of work one execution may do is capped; exceeding the cap terminates the script with an error.
- Recursion depth and expression-nesting depth are bounded; exceeding either terminates the script with an error.
These bounds are the only limit on iteration and recursion — there are no
unbounded loops. A script may invoke other scripts re-entrantly (for
example, a do that triggers another entity's handler); each such
execution is bounded by the same limits
(Error conditions).
Determinism
A script runs to a stopping point — its
normal end, an error, a pause, or the execution budget — without being
preempted. The randomized builtins (random, randrange, choose,
randomly) are the only source of non-determinism; apart from those,
an execution's behavior is determined entirely by the world state at the
moment it begins. The one subtlety is that an after handler
observes a later world state than the before/handle handlers of the
same event, because it runs after the event's effects are applied.