# `tecs.sequence`
Snapshot-safe programs, waits, ownership, actions, and tween timelines.
Sequences store control flow as data. A snapshot, a rewind, or a reload can
therefore preserve a playback's program, instruction pointer, waits, bindings,
and parameters. A coroutine cannot be serialized, so the sequencer compiles
authored steps into instructions and stores each playback's cursor, wait, and
branch as ordinary data. `nupp.tasks` owns the world's logical update; it
cannot own a playback that has to survive a save file.
## Programs and actions
Register an action on the world, name it from a program, and bind each playback
to the entities it acts on:
```nupp
tecs.sequence.registerAction(world, "game.lockControls", function(_world, _context): nil
controlsLocked = true
end)
local intro = tecs.sequence.define("game.bossIntro", {
tecs.sequence.call("game.lockControls"),
tecs.sequence.wait(1.5),
tecs.sequence.emit("boss.ready"),
})
local playback = tecs.sequence.play(world, intro, {owner = encounter, bindings = {boss = bossEntity}})
```
Program names are a snapshot compatibility surface. Use stable qualified names.
Redefining a name publishes a new version: running playbacks keep the version
they started on, and later `play` calls use the new one. Action bodies resolve
by name when they run, so a reload can replace action code without moving a
live instruction pointer.
Actions run synchronously and cannot suspend. An action that raises faults its
playback after preserving the mutations it already completed.
## Clocks and waits
`"fixed"` advances once per fixed step and serves deterministic gameplay.
`"frame"` advances once per gameplay frame and serves scripted input, which
needs exactly one decision per frame however many fixed steps that frame runs.
`"presentation"` advances once per frame carrying the frame's real elapsed
time, and serves values the simulation never reads.
Durations are seconds. Step and tick values count whole advances of the
program's clock. Every positive duration waits at least one tick, and
`waitSteps(0)` yields until the next tick and gives a loop a fresh instruction
budget.
`ecs.newWorld({nominalFrameTime = seconds})`, or `Application.Config.world`,
sets the duration used to convert frame and presentation waits to ticks. It
is positive and finite and defaults to 1/60 in both windowed and headless
sessions. `setNominalFrameTime(world, seconds)` changes future conversions in
that world only; already scheduled tick deadlines do not move. Restore a saved
playback into a world configured for its intended cadence.
`sourceKey(key, component, fields)` resolves a moving tween destination through
`World.byKey` on each evaluation, including after snapshot load or a new entity
claims the key. `TrackingTarget.key` does the same when its `entity` is zero.
An explicit entity id takes precedence and a stale id does not fall back to the
key. A missing source contributes zero, as other missing tracking sources do.
## Ownership
`owner` ties a playback to an entity, and despawning that entity cancels the
playback. A named `channel` gives one owner a replaceable slot, so starting a
second playback on the same channel cancels the first.
Pause uses named holders, and a playback resumes only after every holder
releases it. A branch inherits owner, bindings, parameters, budget, and pause
state, and cannot outlive its parent.
Each playback receives a bounded instruction budget per tick and faults with
`budgetExceeded` rather than hanging the frame.
## Timelines
A timeline compiles tweens into the same runtime and keeps the same ownership,
clock, channel, pause, and snapshot rules. Targets interpolate component
fields. A parallel block shares a start time, and a sequential block starts
after the one before it ends.
## Program construction
A sequence is written by calling the node constructors. The API has no generic
row decoder or shared data schema. A game that stores sequences as data decodes
its own schema into these constructors.
## Types
### `Action` _type_
```nupp
type Action = function(exclusive world: entityworld.World, ctx: ActionContext): nil
```
Defines a registered effect that runs synchronously and cannot suspend.
### `ActionContext` _record_
```nupp
record ActionContext
handle: Handle
owner: integer
args: {any}
params: {[string]: any}?
cursor: Cursor?
entity: function(borrows self: ActionContext, borrows world: entityworld.World, name: string): integer?
bind: function(exclusive self: ActionContext, name: string, entity: integer?): nil
end
```
Provides the context a registered action receives.
#### Methods
##### `entity`
```nupp
entity: function(borrows self: ActionContext, borrows world: entityworld.World, name: string): integer?
```
Resolves a named binding to a live entity.
The world is a parameter rather than a field of this record, because the
sequencer reuses one context across calls and may not keep a view of the
world the running tick borrows. An action already has the world it ran
under.
###### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `borrows self` | `ActionContext` | the context the running action received |
| `borrows world` | `entityworld.World` | the world the running action received |
| `name` | `string` | the binding name supplied through `PlayOptions.bindings` |
###### Returns
| Type | Description |
| --- | --- |
| `integer?` | the entity id, or nil when the binding is missing or its entity is no longer alive |
##### `bind`
```nupp
bind: function(exclusive self: ActionContext, name: string, entity: integer?): nil
```
Names an entity for the steps that follow, so an action that creates one
can hand it on.
Bindings travel with the playback and survive a snapshot. Passing nil
forgets the name.
###### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `exclusive self` | `ActionContext` | the context the running action received |
| `name` | `string` | the binding name later steps resolve |
| `entity` | `integer?` | the entity id to bind, or nil to forget the name |
###### Returns
| Type | Description |
| --- | --- |
| `nil` | |
#### Fields
##### `handle`
```nupp
handle: Handle
```
Read-only. Identifies the playback, for `status` or `cancel` from
inside an action.
##### `owner`
```nupp
owner: integer
```
Read-only. Reports the `owner` supplied at `play`, or zero.
##### `args`
```nupp
args: {any}
```
Read-only. Carries the `call` node's constants with every entity
reference already resolved to an entity id.
##### `params`
```nupp
params: {[string]: any}?
```
Read-only. Carries the `params` supplied at `play`, or nil.
##### `cursor`
```nupp
cursor: Cursor?
```
Engine-owned. Points at the running cursor. Game code uses `entity`
and `bind` instead of reading this.
### `Awaitable` _record_
```nupp
record Awaitable
isPending: function(borrows world: entityworld.World, entity: integer, key: string?): boolean
setPaused: (function(exclusive world: entityworld.World, entity: integer, key: string?, paused: boolean): nil)?
end
```
Defines the response an `await` step's provider must give.
#### Methods
##### `isPending`
```nupp
isPending: function(borrows world: entityworld.World, entity: integer, key: string?): boolean
```
Caller-writable. Reports whether the work named by `entity` and `key`
is still going. The sequencer calls this at a fixed-step boundary for
every cursor parked on the name, so it must be cheap and must not
mutate the world. Reporting false for work that never started is
correct: a program waiting on an animation that is already over should
carry on rather than hang.
###### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `borrows world` | `entityworld.World` | |
| `entity` | `integer` | |
| `key` | `string?` | |
###### Returns
| Type | Description |
| --- | --- |
| `boolean` | |
#### Fields
##### `setPaused`
```nupp
setPaused: (function(exclusive world: entityworld.World, entity: integer, key: string?, paused: boolean): nil)?
```
Caller-writable. Stops and starts the work when the provider knows
how, so pausing a cutscene stops the animation it waits on. Optional.
### `ClockId` _type_
```nupp
type ClockId = "fixed" | "frame" | "presentation"
```
Selects the clock a program runs against.
### `DefineOptions` _type_
```nupp
type DefineOptions = {clock: ClockId?}
```
Configures `define`.
### `EasingFunction` _type_
```nupp
type EasingFunction = function(t: number): number
```
Maps normalized input progress to eased output progress.
### `EasingName` _type_
```nupp
type EasingName = "linear"
| "quadIn"
| "quadOut"
| "quadInOut"
| "quadOutIn"
| "cubicIn"
| "cubicOut"
| "cubicInOut"
| "cubicOutIn"
| "quartIn"
| "quartOut"
| "quartInOut"
| "quartOutIn"
| "quintIn"
| "quintOut"
| "quintInOut"
| "quintOutIn"
| "sineIn"
| "sineOut"
| "sineInOut"
| "sineOutIn"
| "expoIn"
| "expoOut"
| "expoInOut"
| "expoOutIn"
| "backIn"
| "backOut"
| "backInOut"
| "backOutIn"
| "elasticIn"
| "elasticOut"
| "elasticInOut"
| "elasticOutIn"
| "bounceIn"
| "bounceOut"
| "bounceInOut"
| "bounceOutIn"
```
Names a built-in easing curve.
### `Emission` _record_
```nupp
record Emission
name: string
args: {any}
handle: Handle
end
```
`@derive(events.Event)` `@event(name="SequenceEmission")`
The payload an `emit` step delivers at address zero.
#### Fields
##### `name`
```nupp
name: string
```
Read-only. Carries the name supplied to `sequence.emit`.
##### `args`
```nupp
args: {any}
```
Read-only. Carries the emitted constants with bindings resolved. This
list is built per emission and is the observer's to keep.
##### `handle`
```nupp
handle: Handle
```
Read-only. Identifies the playback that emitted it.
### `EntityRef` _record_
```nupp
record EntityRef
bindName: string
isBinding: boolean
end
```
References an entity supplied at `play` time.
#### Fields
##### `bindName`
```nupp
bindName: string
```
Read-only. Names the binding this reference resolves.
##### `isBinding`
```nupp
isBinding: boolean
```
Read-only. Marks this table apart from an ordinary table argument.
### `Evaluator` _record_
```nupp
record Evaluator
resolve: (function(data: any): any)?
newState: (function(program: Program, data: any, cursor: Cursor): any)?
step: function(exclusive world: entityworld.World, cursor: Cursor, dt: number): boolean
save: (function(state: any): any)?
load: (function(program: Program, data: any, saved: any): any)?
end
```
Defines the evaluator an `eval` step runs every tick.
#### Methods
##### `step`
```nupp
step: function(exclusive world: entityworld.World, cursor: Cursor, dt: number): boolean
```
Caller-writable. Advances one cursor by `dt` and returns true once the
cursor should move on to the next instruction.
###### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `exclusive world` | `entityworld.World` | |
| `cursor` | `Cursor` | |
| `dt` | `number` | |
###### Returns
| Type | Description |
| --- | --- |
| `boolean` | |
#### Fields
##### `resolve`
```nupp
resolve: (function(data: any): any)?
```
Caller-writable. Turns the constant an `eval` step carries into the
form that is cheapest to read every tick. Runs once per program
constant and the result is shared by every playback of it.
##### `newState`
```nupp
newState: (function(program: Program, data: any, cursor: Cursor): any)?
```
Caller-writable. Builds per-cursor working state, or nil when the
evaluator needs none.
##### `save`
```nupp
save: (function(state: any): any)?
```
Caller-writable. Turns working state into something a snapshot can
carry. Without both `save` and `load` an evaluating playback comes back
at the start of its state rather than where it was.
##### `load`
```nupp
load: (function(program: Program, data: any, saved: any): any)?
```
Caller-writable. Rebuilds working state from what `save` produced.
### `FaultReason` _type_
```nupp
type FaultReason = "unregisteredAction"
| "actionError"
| "budgetExceeded"
| "branchFaulted"
| "unregisteredQuery"
| "unregisteredEvaluator"
| "unregisteredAwaitable"
| "unregisteredTween"
```
Explains why a cursor stopped running.
### `Handle` _type_
```nupp
type Handle = integer
```
Identifies one playback through a generation-checked reference that remains
meaningful across a snapshot load.
### `Node` _record_
```nupp
record Node
kind: string
text: string?
number: number?
count: integer?
args: any
nodes: {Node}?
blocks: {{Node}}?
end
```
Represents one authored step produced by a node constructor.
#### Fields
##### `kind`
```nupp
kind: string
```
Read-only. Names the step this node compiles to.
##### `text`
```nupp
text: string?
```
Read-only. Carries the step's name argument, when it takes one.
##### `number`
```nupp
number: number?
```
Read-only. Carries the step's numeric argument, when it takes one.
##### `count`
```nupp
count: integer?
```
Read-only. Carries the step's integer argument, when it takes one.
##### `args`
```nupp
args: any
```
Read-only. Carries the step's constant, when it takes one. Most steps
carry a list; an evaluating step carries whatever its evaluator reads.
##### `nodes`
```nupp
nodes: {Node}?
```
Read-only. Carries the step's nested block, when it takes one.
##### `blocks`
```nupp
blocks: {{Node}}?
```
Read-only. Carries one block per branch for a `parallel` step.
### `PlaybackMode` _type_
```nupp
type PlaybackMode = "once" | "loop" | "pingPong"
```
Selects how a timeline repeats.
### `PlaybackState` _type_
```nupp
type PlaybackState = "running" | "paused" | "completed" | "canceled" | "faulted"
```
Describes the lifecycle state of one playback.
### `PlayOptions` _type_
```nupp
type PlayOptions = {
owner: integer?,
bindings: {[string]: integer}?,
params: {[string]: any}?,
budget: integer?,
channel: string?
}
```
Configures `play`.
### `Program` _record_
```nupp
record Program
name: string
version: integer
clock: ClockId
code: {integer}
consts: {any}
loopCounts: {[integer]: integer}
bindingArgs: {[integer]: boolean}
evalResolved: {[integer]: any}?
end
```
Represents a compiled, immutable program shared by every playback of it.
#### Fields
##### `name`
```nupp
name: string
```
Read-only. Reports the name passed to `define`.
##### `version`
```nupp
version: integer
```
Read-only. Reports the monotonic version, starting at one.
##### `clock`
```nupp
clock: ClockId
```
Read-only. Reports the clock this program's waits count.
##### `code`
```nupp
code: {integer}
```
Engine-owned. Holds the flat instruction array. Game code reads it
through `disassemble` rather than directly.
##### `consts`
```nupp
consts: {any}
```
Engine-owned. Holds the constant pool the instructions index.
##### `loopCounts`
```nupp
loopCounts: {[integer]: integer}
```
Engine-owned. Maps a jump's address to the iteration count it seeds.
##### `bindingArgs`
```nupp
bindingArgs: {[integer]: boolean}
```
Engine-owned. Marks the constant indexes whose argument list holds an
entity reference, so a call with plain constants copies nothing.
##### `evalResolved`
```nupp
evalResolved: {[integer]: any}?
```
Engine-owned. Caches one resolved constant per evaluating instruction.
### `QueryCondition` _type_
```nupp
type QueryCondition = "any" | "empty"
```
Describes the condition awaited by a `waitQuery` step.
### `RunOptions` _type_
```nupp
type RunOptions = {
mode: PlaybackMode?,
count: integer?
}
```
Configures a nested `tweenRun` operation.
### `Status` _record_
```nupp
record Status
state: PlaybackState
program: string
version: integer
pc: integer
wakeAt: integer?
waitingFor: string?
waitingQuery: string?
waitingCondition: QueryCondition?
waitingAwaitable: string?
waitingAwaitableEntity: integer?
waitingTween: Handle?
tweenOutcome: TweenOutcome?
branches: integer
joining: boolean
fault: FaultReason?
faultMessage: string?
end
```
Reports a playback's current state.
#### Fields
##### `state`
```nupp
state: PlaybackState
```
Read-only. Reports the lifecycle state.
##### `program`
```nupp
program: string
```
Read-only. Names the program this playback runs.
##### `version`
```nupp
version: integer
```
Read-only. Reports the program version this playback runs.
##### `pc`
```nupp
pc: integer
```
Read-only. Reports the instruction index.
##### `wakeAt`
```nupp
wakeAt: integer?
```
Read-only. Reports the tick this playback next runs on, or nil when it
is blocked on something other than a time.
##### `waitingFor`
```nupp
waitingFor: string?
```
Read-only. Names the signal this playback is blocked on.
##### `waitingQuery`
```nupp
waitingQuery: string?
```
Read-only. Names the query this playback is blocked on.
##### `waitingCondition`
```nupp
waitingCondition: QueryCondition?
```
Read-only. Reports the query condition this playback waits for.
##### `waitingAwaitable`
```nupp
waitingAwaitable: string?
```
Read-only. Names the awaitable provider this playback is blocked on.
##### `waitingAwaitableEntity`
```nupp
waitingAwaitableEntity: integer?
```
Read-only. Names the entity this playback's awaitable is asked about.
##### `waitingTween`
```nupp
waitingTween: Handle?
```
Read-only. Identifies the playback this one is blocked on.
##### `tweenOutcome`
```nupp
tweenOutcome: TweenOutcome?
```
Read-only. Reports how the last awaited playback ended.
##### `branches`
```nupp
branches: integer
```
Read-only. Counts live branches this playback forked and has not
joined.
##### `joining`
```nupp
joining: boolean
```
Read-only. Reports whether this playback waits at a `join`.
##### `fault`
```nupp
fault: FaultReason?
```
Read-only. Explains a faulted playback.
##### `faultMessage`
```nupp
faultMessage: string?
```
Read-only. Reports the message accompanying a fault.
### `Step` _record_
```nupp
record Step
ticks: integer
kind: string
name: string
args: {any}
end
```
Describes one step a playback reaches without branching.
#### Fields
##### `ticks`
```nupp
ticks: integer
```
Read-only. Counts ticks of the program's clock from the reference point
until this step runs.
##### `kind`
```nupp
kind: string
```
Read-only. Holds `"call"` or `"emit"`.
##### `name`
```nupp
name: string
```
Read-only. Names the action for a call or the event for an emit.
##### `args`
```nupp
args: {any}
```
Read-only. Carries the step's constants, unresolved. This list is the
program's own rather than a copy, so read it and do not write to it.
### `Target` _record_
```nupp
record Target
id: string
componentName: string
component: components.Component?
fields: {string}
mode: TargetMode
end
```
Describes the component and one to four numeric fields a timeline
operation writes.
#### Fields
##### `id`
```nupp
id: string
```
Read-only. Identifies this target in a compiled slot. A built-in
carries its `TargetName`; one built from a component carries the
component name joined to its fields.
##### `componentName`
```nupp
componentName: string
```
Read-only. Names the component whose fields move.
##### `component`
```nupp
component: components.Component?
```
Engine-owned. Caches the resolved component, which a target restored
from a snapshot looks up on first use.
##### `fields`
```nupp
fields: {string}
```
Read-only. Names the fields written, in the order the destinations
line up with them.
##### `mode`
```nupp
mode: TargetMode
```
Read-only. Selects how the destinations are interpreted.
### `TargetName` _type_
```nupp
type TargetName = "transform.x"
| "transform.y"
| "transform.xy"
| "transform.rotation"
| "transform.rotationShortest"
| "transform.scaleX"
| "transform.scaleY"
| "transform.scaleXY"
| "color.a"
| "color.rgba"
```
Names a built-in component-field target.
### `TimelineNode` _record_
```nupp
record TimelineNode
kind: OperationKind
duration: number?
easingName: EasingName?
target: Target?
source: TrackSource?
t1: number?
t2: number?
t3: number?
t4: number?
name: string?
nested: {TimelineNode}?
mode: PlaybackMode?
count: integer?
branches: {{TimelineNode}}?
end
```
Represents one authored timeline operation.
#### Fields
##### `kind`
```nupp
kind: OperationKind
```
Read-only. Names the operation.
##### `duration`
```nupp
duration: number?
```
Read-only. Reports the seconds this operation occupies.
##### `easingName`
```nupp
easingName: EasingName?
```
Read-only. Names the curve an interpolation follows.
##### `target`
```nupp
target: Target?
```
Read-only. Selects the component fields an interpolation writes.
##### `source`
```nupp
source: TrackSource?
```
Read-only. Selects where a tracking interpolation reads its
destination.
##### `t1`
```nupp
t1: number?
```
Read-only. Carries the destination for the target's first field.
##### `t2`
```nupp
t2: number?
```
Read-only. Carries the destination for the second field.
##### `t3`
```nupp
t3: number?
```
Read-only. Carries the destination for the third field.
##### `t4`
```nupp
t4: number?
```
Read-only. Carries the destination for the fourth field.
##### `name`
```nupp
name: string?
```
Read-only. Names the event an `emit` operation fires.
##### `nested`
```nupp
nested: {TimelineNode}?
```
Read-only. Carries the nested spec a `run` operation plays.
##### `mode`
```nupp
mode: PlaybackMode?
```
Read-only. Selects how a `run` operation repeats.
##### `count`
```nupp
count: integer?
```
Read-only. Counts the passes a repeating `run` operation makes.
##### `branches`
```nupp
branches: {{TimelineNode}}?
```
Read-only. Carries one block per concurrent branch of a `parallel`
operation.
### `TimelineOptions` _type_
```nupp
type TimelineOptions = {clock: ClockId?}
```
Configures `timeline`.
### `TrackingTarget` _record_
```nupp
record TrackingTarget
entity: integer
key: string
end
```
Selects a dynamic tracking-source entity.
#### Fields
##### `entity`
```nupp
entity: integer
```
Caller-writable. Names the source entity directly, or zero for none.
##### `key`
```nupp
key: string
```
Caller-writable. Names the source entity by world key when `entity` is
zero. Resolution follows the current live claimant on every evaluation.
This persisted field name is a compatibility surface.
### `TrackSource` _record_
```nupp
record TrackSource
kind: TrackSourceKind
key: string?
relationshipName: string?
relationship: components.Component?
componentName: string
component: components.Component?
fields: {string}
end
```
Provides a live component-field tracking source.
#### Fields
##### `kind`
```nupp
kind: TrackSourceKind
```
Read-only. Selects which entity the source reads from.
##### `key`
```nupp
key: string?
```
Read-only. Names the world key a keyed source resolves on every evaluation.
##### `relationshipName`
```nupp
relationshipName: string?
```
Read-only. Names the relationship traversed by a `related` source.
##### `relationship`
```nupp
relationship: components.Component?
```
Engine-owned. Caches the resolved relationship component.
##### `componentName`
```nupp
componentName: string
```
Read-only. Names the component the source reads.
##### `component`
```nupp
component: components.Component?
```
Engine-owned. Caches the resolved component.
##### `fields`
```nupp
fields: {string}
```
Read-only. Names the fields read, lined up with the target's own.
### `TweenOutcome` _type_
```nupp
type TweenOutcome = "completed" | "canceled" | "replaced" | "targetLost"
```
Reports how the playback awaited by `waitTween` ended.
## Functions
### `activeCount` _function_
```nupp
function activeCount(exclusive world: ecs.World): integer
```
Returns the number of live playbacks, for tests and diagnostics.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `exclusive world` | `ecs.World` | the world that owns the playbacks |
#### Returns
| Type | Description |
| --- | --- |
| `integer` | the count, with branches and `playTween`-started playbacks counted individually |
### `await` _function_
```nupp
function await(provider: string, target: EntityRef, key: string?): Node
```
Builds a step that waits for work outside the sequencer to finish.
A subsystem registers a provider under a name and answers whether the work
is still going; this parks the playback until it is not. The sequencer never
learns what the work is, which is how a program waits on a sprite animation
without the sequencer requiring the renderer. A binding that is missing or
dead is not a fault, and neither is a provider reporting work that never
started.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `provider` | `string` | the registered provider name, checked before the binding; an unregistered name faults the playback with `unregisteredAwaitable` |
| `target` | `EntityRef` | a `bind` reference and nothing else |
| `key` | `string?` | handed to the provider unread, for a provider that answers about more than one thing per entity |
#### Returns
| Type | Description |
| --- | --- |
| `Node` | a step for `define`, not to be put in a second program |
#### Raises
- when the provider name is empty or the target is not a `bind` reference
### `bind` _function_
```nupp
function bind(name: string): EntityRef
```
References an entity supplied through `PlayOptions.bindings`.
The reference resolves when the instruction using it runs rather than at
`play`, so a binding may name an entity that does not exist yet. A missing
binding resolves to nothing instead of faulting.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `name` | `string` | the binding name, which must not be empty |
#### Returns
| Type | Description |
| --- | --- |
| `EntityRef` | a reference to put in a `call` or `emit` argument list, or to hand to `playTween` or `await` |
#### Raises
- when the name is empty
### `call` _function_
```nupp
function call(action: string, ...: any): Node
```
Builds a step that runs a registered action.
The action name resolves per world when the instruction runs, so a program
may name an action registered later. A name still unregistered when the
step runs faults the playback with `unregisteredAction`. The step costs no
tick.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `action` | `string` | the registered action name |
| `...` | `any` | the constants the action receives, which are the same values for every playback of this program; put anything that differs between two playbacks in `PlayOptions.params` instead |
#### Returns
| Type | Description |
| --- | --- |
| `Node` | a step for `define`, not to be put in a second program |
#### Raises
- when the action name is empty
### `cancel` _function_
```nupp
function cancel(exclusive world: ecs.World, handle: Handle): boolean
```
Stops a playback and releases its cursor.
This is safe on a finished handle. Cancelling takes the branches the
playback forked with it, and a playback parked in a `waitTween` on the one
canceled is told `canceled` and resumes. What a `playTween` started is a
playback in its own right and is not canceled with the one that started it,
unlike a pause, which cascades to it; stop it through its owner with
`cancelOwnedBy`.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `exclusive world` | `ecs.World` | the world that owns the playback |
| `handle` | `Handle` | the playback to stop, read against this world's cursor arena |
#### Returns
| Type | Description |
| --- | --- |
| `boolean` | false when the handle names nothing running, whether it already finished or was already canceled |
### `cancelOwnedBy` _function_
```nupp
function cancelOwnedBy(exclusive world: ecs.World, owner: integer, reason: TweenOutcome?): integer
```
Cancels every playback owned by an entity.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `exclusive world` | `ecs.World` | the world that owns the playbacks |
| `owner` | `integer` | an entity id; nothing owns a playback started without an owner, so no argument reaches one and only `cancel` on its handle stops it |
| `reason` | `TweenOutcome?` | what a playback parked in a `waitTween` on one of these is told, defaulting to `canceled` |
#### Returns
| Type | Description |
| --- | --- |
| `integer` | the number of canceled playbacks, counting each cursor once and reaching branches through their inherited owner |
### `currentStep` _function_
```nupp
function currentStep(exclusive world: ecs.World, clock: ClockId?): integer
```
Returns a clock's current tick as counted by the sequencer.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `exclusive world` | `ecs.World` | the world that owns the clock counters |
| `clock` | `ClockId?` | which of the three counters to read, defaulting to `"fixed"` |
#### Returns
| Type | Description |
| --- | --- |
| `integer` | the ticks of that one clock, counted from when this world's sequencer state was created and comparable only against another reading of the same clock |
### `define` _function_
```nupp
function define(name: string, nodes: {Node}, options: DefineOptions?): Program
```
Compiles a program under a stable symbolic name.
Defining over a name already in use publishes a new version rather than
replacing the old one: playbacks already running keep the version they
started on, and only later `play` calls see the new one.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `name` | `string` | the stable symbolic name, which is a snapshot compatibility surface |
| `nodes` | `{Node}` | the authored steps, which may be empty, in which case the program completes on its first tick |
| `options` | `DefineOptions?` | the clock the program's waits count, defaulting to `"fixed"` |
#### Returns
| Type | Description |
| --- | --- |
| `Program` | the compiled program, immutable and shared by every playback of it, so the same value plays on any number of worlds |
#### Raises
- when the name is empty, the clock is not one of the three names, or an entry is not a step
### `disassemble` _function_
```nupp
function disassemble(value: Program, pc: integer?): string
```
Renders a program as readable instructions.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `value` | `Program` | a program from `define` or `timeline` |
| `pc` | `integer?` | the instruction to mark, as a playback's `status` reports it, or nil for an unmarked listing |
#### Returns
| Type | Description |
| --- | --- |
| `string` | a header naming the program and its version, then one line per instruction, newline separated, for reading rather than for parsing |
### `easing` _function_
```nupp
function easing(name: EasingName): EasingFunction?
```
Returns a built-in easing curve by name.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `name` | `EasingName` | the curve name |
#### Returns
| Type | Description |
| --- | --- |
| `EasingFunction?` | the curve, or nil when the name names no built-in |
### `emit` _function_
```nupp
function emit(event: string, ...: any): Node
```
Builds a step that emits a sequence event at address zero.
The step occupies no tick, so the step after it runs in the same one. Each
emission copies its argument list and sends it with the event, so an
observer may keep it, unlike the list an action receives.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `event` | `string` | the name carried on the emission |
| `...` | `any` | the constants delivered on the emission with every entity reference already resolved |
#### Returns
| Type | Description |
| --- | --- |
| `Node` | a step for `define`, not to be put in a second program |
#### Raises
- when the event name is empty
### `eval` _function_
```nupp
function eval(evaluator: string, data: any): Node
```
Builds a step that evaluates a registered evaluator every tick until it
finishes.
Unlike every other step this one does not hand the tick back: the playback
joins its clock's active set and the runtime steps it each tick. Values
that move every frame need this behavior.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `evaluator` | `string` | the registered evaluator name, resolved when the instruction runs; an unregistered name faults the playback with `unregisteredEvaluator` |
| `data` | `any` | the constant the evaluator receives, passed through its `resolve` once per program constant and shared by every playback, so it must remain plain data and the evaluator must not write per-playback state into it |
#### Returns
| Type | Description |
| --- | --- |
| `Node` | a step for `define`, not to be put in a second program |
#### Raises
- when the evaluator name is empty
### `fork` _function_
```nupp
function fork(nodes: {Node}): Node
```
Builds a step that starts a branch alongside the rest of the program.
The branch is a playback of its own running the same program at a different
instruction, inheriting the owner, bindings, parameters, and instruction
budget of the playback that forked it. It starts once that playback next
waits, joins, or ends, within the same tick. A branch never outlives its
parent, and a branch that faults takes its parent with it, faulted
`branchFaulted`, rather than leaving a join one branch short forever.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `nodes` | `{Node}` | the branch body, which must not be empty and which reads and writes the forking playback's own bindings table rather than a copy |
#### Returns
| Type | Description |
| --- | --- |
| `Node` | a step for `define`, not to be put in a second program |
#### Raises
- when the block is empty
### `hasAction` _function_
```nupp
function hasAction(exclusive world: ecs.World, name: string): boolean
```
Reports whether a world has registered an action name.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `exclusive world` | `ecs.World` | the world that owns the action registry |
| `name` | `string` | the action name to find |
#### Returns
| Type | Description |
| --- | --- |
| `boolean` | false for a name this world never registered, including one another world has |
### `hasQuery` _function_
```nupp
function hasQuery(exclusive world: ecs.World, name: string): boolean
```
Reports whether a world has registered a query name.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `exclusive world` | `ecs.World` | the world that owns the query registry |
| `name` | `string` | the query name to find |
#### Returns
| Type | Description |
| --- | --- |
| `boolean` | false for a name this world never registered |
### `join` _function_
```nupp
function join(): Node
```
Builds a step that waits for every branch not yet joined.
It falls straight through when there are none, and when the last branch
finishes the waiting playback resumes within that same tick.
#### Returns
| Type | Description |
| --- | --- |
| `Node` | a step for `define`, not to be put in a second program |
### `loop` _function_
```nupp
function loop(count: integer?, nodes: {Node}): Node
```
Builds a step that repeats a block.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `count` | `integer?` | the iterations, or nil to repeat until canceled |
| `nodes` | `{Node}` | the block, which must not be empty and which is run in order and started again from its first node |
#### Returns
| Type | Description |
| --- | --- |
| `Node` | a step for `define`, not to be put in a second program |
#### Raises
- when the count is not a positive whole number, or the block is empty
### `parallel` _function_
```nupp
function parallel(blocks: {{Node}}): Node
```
Builds a step that forks several blocks and waits for all of them.
This is a `fork` per block followed by one `join`. Blocks start in argument
order, and each shares the playback's bindings table as a `fork` does.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `blocks` | `{{Node}}` | one non-empty block per branch |
#### Returns
| Type | Description |
| --- | --- |
| `Node` | a step for `define`, not to be put in a second program |
#### Raises
- when no block is supplied or one of them is empty
### `pause` _function_
```nupp
function pause(exclusive world: ecs.World, handle: Handle, holder: string?): boolean
```
Suspends a playback, its branches, and anything it started.
Pause is holder counted: two systems can hold the same playback for
unrelated reasons, and it runs again only when the last one lets go, so
whichever resumes first cannot undo the other. Its wait, if any, resumes
from where it paused, and what it is waiting on stops with it when the
awaitable provider knows how.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `exclusive world` | `ecs.World` | the world that owns the playback |
| `handle` | `Handle` | the playback to pause |
| `holder` | `string?` | any string, treated as a set rather than a count, so two pauses under the same holder are one hold; it defaults to `"user"` |
#### Returns
| Type | Description |
| --- | --- |
| `boolean` | whether the playback stopped, which is false when another holder already had it or the handle names nothing running |
### `play` _function_
```nupp
function play(exclusive world: ecs.World, value: Program, options: PlayOptions?): Handle
```
Starts a program.
The first instruction runs on the next tick of the program's own clock,
never inside this call.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `exclusive world` | `ecs.World` | the world that owns the new playback |
| `value` | `Program` | a program from `define` or `timeline`, not a name; the playback runs this version for its whole life |
| `options` | `PlayOptions?` | the owner, bindings, parameters, budget, and channel; taking a channel another playback on the same owner holds cancels that one first, reporting `replaced` to anything waiting on it |
#### Returns
| Type | Description |
| --- | --- |
| `Handle` | a handle to the new playback, carrying a generation so one whose playback has ended never names a later playback that took the same slot |
### `playbacks` _function_
```nupp
function playbacks(exclusive world: ecs.World): {Handle}
```
Returns handles for every live playback in a stable order.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `exclusive world` | `ecs.World` | the world that owns the playbacks |
#### Returns
| Type | Description |
| --- | --- |
| `{Handle}` | a caller-owned table ordered by cursor slot, which is stable within a run but differs from creation order because new playbacks reuse free slots |
### `playTween` _function_
```nupp
function playTween(timeline: string, target: EntityRef, params: {[string]: any}?): Node
```
Builds a step that plays a registered timeline on a bound entity.
The step costs no tick. It starts a separate playback owned by the bound
entity, running on the named program's clock and using this playback's
instruction budget. A binding that is missing or dead is not a fault:
nothing plays, and a following `waitTween` resumes at once reporting
`targetLost`.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `timeline` | `string` | the timeline name, resolved when the instruction runs and always to the newest version; an undefined name faults the playback with `unregisteredTween` |
| `target` | `EntityRef` | a `bind` reference and nothing else |
| `params` | `{\[string\]: any}?` | the started playback's parameters, so `mode`, `count`, `speed`, `delay` and `channel` shape it as they do for `play` |
#### Returns
| Type | Description |
| --- | --- |
| `Node` | a step for `define`, not to be put in a second program |
#### Raises
- when the timeline name is empty or the target is not a `bind` reference
### `plugin` _function_
```nupp
function plugin(exclusive world: ecs.World): nil
```
Installs the sequencer into a world.
Installing twice on the same world does nothing, so a world that scripts
input may install the sequencer itself rather than relying on the
application having done it.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `exclusive world` | `ecs.World` | the world receiving sequencer state, systems, and the snapshot handler |
#### Returns
| Type | Description |
| --- | --- |
| `nil` | |
### `program` _function_
```nupp
function program(name: string, version: integer?): Program?
```
Returns the newest version of a defined program, or a requested version.
Every version a playback still runs stays reachable, and the newest version
of a name is never dropped.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `name` | `string` | a name previously passed to `define` or `timeline` |
| `version` | `integer?` | the version to look up, starting at one, or nil for the newest |
#### Returns
| Type | Description |
| --- | --- |
| `Program?` | the program, or nil when the name was never defined or that version has been dropped |
### `programNames` _function_
```nupp
function programNames(): {string}
```
Returns the names of every defined program, sorted.
#### Returns
| Type | Description |
| --- | --- |
| `{string}` | a caller-owned list; registration is process-wide, so this spans every world in the process |
### `registerAction` _function_
```nupp
function registerAction(exclusive world: ecs.World, name: string, action: Action): nil
```
Registers an action a `call` step can name.
Actions must obey the deterministic-action contract to keep replay and
rewind meaningful: no wall-clock reads, no file or network access, and
randomness only from a generator whose state travels with the snapshot.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `exclusive world` | `ecs.World` | the world that owns the action registry |
| `name` | `string` | the action name, which is per world unlike an evaluator or an awaitable; registering it twice replaces the action, and a playback resolves the name at each `call`, so one already running picks the new one up |
| `action` | `Action` | the body, which faults its playback with `actionError` when it raises, leaving whatever it already wrote to the world written |
#### Returns
| Type | Description |
| --- | --- |
| `nil` | |
#### Raises
- when the name is empty
### `registerAwaitable` _function_
```nupp
function registerAwaitable(name: string, provider: Awaitable): nil
```
Registers a provider an `await` step can name.
Registration is process-wide, like an evaluator, because a provider is code.
Registering a name twice replaces the provider, so a playback already parked
on the name asks the new one at the next fixed step.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `name` | `string` | the provider name |
| `provider` | `Awaitable` | the provider, which must carry `isPending`; without `setPaused` it leaves its work running when a pause stops the waiting playback |
#### Returns
| Type | Description |
| --- | --- |
| `nil` | |
#### Raises
- when the name is empty or the provider has no `isPending`
### `registerEvaluator` _function_
```nupp
function registerEvaluator(name: string, evaluator: Evaluator): nil
```
Registers an evaluator an `eval` step can name.
Registration is process-wide, like a program: an evaluator is code, and two
worlds evaluating the same name run the same thing. Registering a name
twice replaces it.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `name` | `string` | the evaluator name |
| `evaluator` | `Evaluator` | the evaluator, which must carry `step`; without `save` and `load` a playback evaluating this name comes back from a snapshot at the start of its state rather than where it was |
#### Returns
| Type | Description |
| --- | --- |
| `nil` | |
#### Raises
- when the name is empty or the evaluator has no `step`
### `registerQuery` _function_
```nupp
function registerQuery(exclusive world: ecs.World, name: string, descriptor: ecs.QueryDescriptor): nil
```
Registers a query a `waitQuery` step can name.
Registering a name again re-tests every playback already parked on it,
against the new query, at the next fixed step.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `exclusive world` | `ecs.World` | the world that owns the query registry |
| `name` | `string` | the query name |
| `descriptor` | `ecs.QueryDescriptor` | the include and exclude constraints |
#### Returns
| Type | Description |
| --- | --- |
| `nil` | |
#### Raises
- when the name is empty
### `resume` _function_
```nupp
function resume(exclusive world: ecs.World, handle: Handle, holder: string?): boolean
```
Releases one holder's claim on a paused playback.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `exclusive world` | `ecs.World` | the world that owns the playback |
| `handle` | `Handle` | the paused playback |
| `holder` | `string?` | the string that took the hold, defaulting to `"user"`; releasing one that never held it changes nothing |
#### Returns
| Type | Description |
| --- | --- |
| `boolean` | whether the playback started running again, which is true only for the last holder to let go; a wake time that passed while it was held runs it on the next tick rather than immediately |
### `setInstructionBudget` _function_
```nupp
function setInstructionBudget(exclusive world: ecs.World, instructions: integer): nil
```
Sets the per-tick instruction budget for playbacks that ask for none.
The budget caps how many instructions one playback runs per tick, and
exceeding it faults the playback with `budgetExceeded` rather than deferring
the rest, so it guards against a loop with no wait in it rather than acting
as a scheduler. It applies to playbacks started after this call.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `exclusive world` | `ecs.World` | the world the budget applies to |
| `instructions` | `integer` | the budget, which must be at least one |
#### Returns
| Type | Description |
| --- | --- |
| `nil` | |
#### Raises
- when the budget is less than one
### `setNominalFrameTime` _function_
```nupp
function setNominalFrameTime(exclusive world: ecs.World, seconds: number): nil
```
Sets the nominal frame duration a `frame` or `presentation` wait converts
seconds against.
The nominal duration is used rather than a frame's measured time because a
wake is a tick number fixed when the wait runs and never revisited.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `exclusive world` | `ecs.World` | the world whose future waits use this duration. |
| `seconds` | `number` | the positive finite nominal duration in seconds. |
#### Returns
| Type | Description |
| --- | --- |
| `nil` | |
#### Raises
- when the duration is not positive and finite.
### `signal` _function_
```nupp
function signal(exclusive world: ecs.World, name: string): integer
```
Raises a named signal and wakes every playback blocked on it.
Delivery happens on the next fixed step. Raising a signal nothing waits on
is not an error and is not remembered: a playback that reaches `waitSignal`
afterwards keeps waiting.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `exclusive world` | `ecs.World` | the world that owns the signal state |
| `name` | `string` | the signal name, registered nowhere |
#### Returns
| Type | Description |
| --- | --- |
| `integer` | the number of playbacks waiting on the name now, which may differ from the set the next fixed step wakes |
#### Raises
- when the name is empty
### `signalOnEvent` _function_
```nupp
function signalOnEvent(exclusive world: ecs.World, name: string, event: Type): nil
```
Raises a signal whenever an event emits at address zero.
An ECS event is an edge, like a signal, so this wires one to the other
rather than adding a separate kind of wait. Delivery follows the ordinary
signal rule and waiters wake on the next fixed step.
#### Type parameters
| Name | Description |
| --- | --- |
| `E` | |
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `exclusive world` | `ecs.World` | the world that owns the observer and the signal state |
| `name` | `string` | the signal to raise, once per emission |
| `event` | `Type\` | the event definition, observed at address zero and only there; the observer lasts for the life of the world |
#### Returns
| Type | Description |
| --- | --- |
| `nil` | |
#### Raises
- when the name is empty
### `sourceKey` _function_
```nupp
function sourceKey(key: string, component: ecs.Component, fields: {string}): TrackSource
```
Reads a moving destination from the live entity holding a world key.
Missing or despawned sources contribute zero until a live entity claims the key.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `key` | `string` | the non-empty key resolved on every evaluation. |
| `component` | `ecs.Component` | the component to read from that entity. |
| `fields` | `{string}` | the fields aligned with the target's fields. |
#### Returns
| Type | Description |
| --- | --- |
| `TrackSource` | the keyed tracking source. |
#### Raises
- when the key is empty.
### `sourceOwn` _function_
```nupp
function sourceOwn(component: ecs.Component, fields: {string}): TrackSource
```
Reads a moving destination from the animated entity itself.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `component` | `ecs.Component` | the component read |
| `fields` | `{string}` | the fields read, lined up with the target's own |
#### Returns
| Type | Description |
| --- | --- |
| `TrackSource` | the source |
### `sourceRelated` _function_
```nupp
function sourceRelated(relationship: ecs.Component, component: ecs.Component, fields: {string}): TrackSource
```
Reads a moving destination from the entity a relationship points at.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `relationship` | `ecs.Component` | the relationship traversed from the animated entity |
| `component` | `ecs.Component` | the component read on the target entity |
| `fields` | `{string}` | the fields read, lined up with the target's own |
#### Returns
| Type | Description |
| --- | --- |
| `TrackSource` | the source |
### `sourceTracking` _function_
```nupp
function sourceTracking(component: ecs.Component, fields: {string}): TrackSource
```
Reads a moving destination from the entity named by the animated entity's
`TrackingTarget`.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `component` | `ecs.Component` | the component read |
| `fields` | `{string}` | the fields read, lined up with the target's own |
#### Returns
| Type | Description |
| --- | --- |
| `TrackSource` | the source |
### `status` _function_
```nupp
function status(exclusive world: ecs.World, handle: Handle): Status?
```
Returns a playback's status.
A finished playback still answers, with `state` saying how it ended, until
a later `play` takes its slot. The waiting fields are filled only while the
playback lives.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `exclusive world` | `ecs.World` | the world that owns the playback |
| `handle` | `Handle` | the playback to inspect, read against this world's cursor arena |
#### Returns
| Type | Description |
| --- | --- |
| `Status?` | a caller-owned status, or nil for a handle this world never issued |
### `targetAngle` _function_
```nupp
function targetAngle(component: ecs.Component, fieldName: string): Target
```
Interpolates one field as an angle, taking the short way round.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `component` | `ecs.Component` | the component whose field moves |
| `fieldName` | `string` | the radian-valued field name |
#### Returns
| Type | Description |
| --- | --- |
| `Target` | the target |
### `targetField` _function_
```nupp
function targetField(component: ecs.Component, fieldName: string): Target
```
Interpolates one numeric field of a component.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `component` | `ecs.Component` | the component whose field moves |
| `fieldName` | `string` | the field name |
#### Returns
| Type | Description |
| --- | --- |
| `Target` | the target, which holds no per-playback state and is safe to share |
### `targetField2` _function_
```nupp
function targetField2(component: ecs.Component, first: string, second: string): Target
```
Interpolates two numeric fields of a component together.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `component` | `ecs.Component` | the component whose fields move |
| `first` | `string` | the field the first destination lines up with |
| `second` | `string` | the field the second destination lines up with |
#### Returns
| Type | Description |
| --- | --- |
| `Target` | the target |
### `timeline` _function_
```nupp
function timeline(name: string, spec: {TimelineNode}, options: TimelineOptions?): Program
```
Compiles a tween timeline into a program under a stable name.
The compiled slots travel in the program's constant pool, so a timeline is
snapshot safe for the same reason every other program is. Play it with
`play`, giving the entity it animates as the `owner`: a playback with no
owner has nothing to write to and completes on its first tick.
A playback reads four parameters, all optional: `mode` is `"once"`,
`"loop"`, or `"pingPong"`; `count` is the passes a finite repeat makes;
`speed` is a playback multiplier defaulting to one; and `delay` is the
seconds to wait before the first frame. They are read when the playback
builds its state, so a speed of zero or less, a negative delay, or a repeat
of a zero-length timeline faults the playback with `actionError` rather
than raising from `play`.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `name` | `string` | the stable symbolic name, sharing `define`'s namespace and versioning |
| `spec` | `{TimelineNode}` | the timeline operations in execution order |
| `options` | `TimelineOptions?` | the clock the timeline is evaluated against, defaulting to `"presentation"`; `"fixed"` makes it deterministic from a snapshot alone at the cost of stepping at the simulation's rate |
#### Returns
| Type | Description |
| --- | --- |
| `Program` | the compiled program, also reachable by name through `program` |
#### Raises
- when the clock is neither `"fixed"` nor `"presentation"`, or an operation is invalid
### `tweenAdjust` _function_
```nupp
function tweenAdjust(duration: number, curve: EasingName | EasingFunction, target: TargetName | Target, t1: number, t2: number?, t3: number?, t4: number?): TimelineNode
```
Builds a timeline operation that interpolates by a delta from the starting
value.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `duration` | `number` | the seconds it occupies, which must be greater than zero |
| `curve` | `EasingName | EasingFunction` | a name from the built-in curves, or one of those curve values |
| `target` | `TargetName | Target` | which component fields move and in which order |
| `t1` | `number` | the signed change applied to the target's first field |
| `t2` | `number?` | the change applied to the second field |
| `t3` | `number?` | the change applied to the third field |
| `t4` | `number?` | the change applied to the fourth field |
#### Returns
| Type | Description |
| --- | --- |
| `TimelineNode` | an operation for a timeline spec |
#### Raises
- when the curve names no built-in
### `tweenEmit` _function_
```nupp
function tweenEmit(name: string): TimelineNode
```
Builds a timeline operation that emits a named sequence event.
It occupies no time, so what follows it starts at the same instant. The
emission carries the entity the timeline is animating as its one argument
and the timeline's own playback as its handle. It fires as the cursor
passes the point going forward, so a ping-pong return leg does not fire it
a second time.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `name` | `string` | the name carried on the emission |
#### Returns
| Type | Description |
| --- | --- |
| `TimelineNode` | an operation for a timeline spec |
### `tweenParallel` _function_
```nupp
function tweenParallel(blocks: {{TimelineNode}}): TimelineNode
```
Builds a timeline operation that runs blocks concurrently and ends with the
longest.
Every block starts where the operation sits, and what follows starts after
the last of them ends. Two blocks writing the same component field is not
an error, and the later one in argument order wins each tick.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `blocks` | `{{TimelineNode}}` | one block per concurrent branch, each run in sequence within itself |
#### Returns
| Type | Description |
| --- | --- |
| `TimelineNode` | an operation for a timeline spec |
### `tweenRun` _function_
```nupp
function tweenRun(spec: {TimelineNode}, options: RunOptions?): TimelineNode
```
Builds a timeline operation that runs a nested timeline from its own spec.
The nested timeline occupies a window of the parent equal to its own length
times its pass count, so a repeating nested run needs a finite `count`. Its
operations keep their per-playback state separately from the parent's.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `spec` | `{TimelineNode}` | the nested operations, which this call reads rather than rewrites |
| `options` | `RunOptions?` | omit to run the nested timeline once; `"loop"` and `"pingPong"` need a `count` here |
#### Returns
| Type | Description |
| --- | --- |
| `TimelineNode` | an operation for a timeline spec |
#### Raises
- when a repeating nested run carries no finite count
### `tweenTo` _function_
```nupp
function tweenTo(duration: number, curve: EasingName | EasingFunction, target: TargetName | Target, t1: number, t2: number?, t3: number?, t4: number?): TimelineNode
```
Builds a timeline operation that interpolates to an absolute destination.
The operation reads its starting values from the entity on its first tick
rather than during compilation, so the same timeline played on two entities
starts from wherever each of them is.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `duration` | `number` | the seconds it occupies, which must be greater than zero |
| `curve` | `EasingName | EasingFunction` | a name from the built-in curves, or one of those curve values |
| `target` | `TargetName | Target` | which component fields move and in which order the destinations line up with them |
| `t1` | `number` | the destination for the target's first field, in that field's own units: pixels for a translate, radians for a rotation, zero through one for a color channel |
| `t2` | `number?` | the destination for the second field |
| `t3` | `number?` | the destination for the third field |
| `t4` | `number?` | the destination for the fourth field, with anything past the target's field count ignored and an omitted field treated as zero |
#### Returns
| Type | Description |
| --- | --- |
| `TimelineNode` | an operation for a timeline spec |
#### Raises
- when the curve names no built-in
### `tweenTrack` _function_
```nupp
function tweenTrack(duration: number, curve: EasingName | EasingFunction, target: TargetName | Target, from: TrackSource): TimelineNode
```
Builds a timeline operation that interpolates toward a destination that
keeps moving.
The first tick fixes the start as `tweenTo` does, and each later tick reads
the destination again while the operation remains inside its window. Once
the window ends the operation holds its last destination. A source whose
entity or component is missing reads as zero rather than faulting.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `duration` | `number` | the seconds it occupies, which must be greater than zero |
| `curve` | `EasingName | EasingFunction` | a name from the built-in curves, or one of those curve values |
| `target` | `TargetName | Target` | which component fields move and which fields of the source line up with them |
| `from` | `TrackSource` | where the destination is read each tick |
#### Returns
| Type | Description |
| --- | --- |
| `TimelineNode` | an operation for a timeline spec |
#### Raises
- when the curve names no built-in
### `tweenWait` _function_
```nupp
function tweenWait(duration: number): TimelineNode
```
Builds a timeline operation that advances the cursor without changing
anything.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `duration` | `number` | the seconds it occupies, where zero performs no work |
#### Returns
| Type | Description |
| --- | --- |
| `TimelineNode` | an operation for a timeline spec |
### `upcoming` _function_
```nupp
function upcoming(exclusive world: ecs.World, handle: Handle, withinTicks: integer?): {Step}
```
Returns the actions and emissions a playback will certainly perform next,
and their timing.
The walk covers the straight-line run ahead of where the playback sits,
accumulating waits, and stops at the first instruction whose successor
requires execution.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `exclusive world` | `ecs.World` | the world that owns the playback |
| `handle` | `Handle` | the playback to inspect |
| `withinTicks` | `integer?` | report only what is due within this many ticks of the playback's own clock, or nil for everything the walk can reach |
#### Returns
| Type | Description |
| --- | --- |
| `{Step}` | a caller-owned list of the calls and emissions ahead, in order; empty for a handle that names nothing running and for one parked on a signal, a query, a join, a tween, or an evaluator, since none of those has a predictable start. A wait written in seconds also ends the walk. |
### `wait` _function_
```nupp
function wait(seconds: number): Node
```
Builds a step that waits a duration in seconds.
The duration converts to whole ticks when the instruction runs, rounded to
nearest, and any non-zero duration waits at least one tick. Zero still costs
a tick: the cursor resumes on the program's next tick rather than carrying
on within this one.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `seconds` | `number` | the non-negative duration |
#### Returns
| Type | Description |
| --- | --- |
| `Node` | a step for `define`, not to be put in a second program |
#### Raises
- when the duration is negative
### `waitingOn` _function_
```nupp
function waitingOn(exclusive world: ecs.World, name: string): integer
```
Returns how many playbacks currently wait on a signal name.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `exclusive world` | `ecs.World` | the world that owns the waiting playbacks |
| `name` | `string` | the signal name to count |
#### Returns
| Type | Description |
| --- | --- |
| `integer` | zero for a name nothing waits on; a signal raised during this step leaves its waiters in the count until the next step delivers it |
### `waitQuery` _function_
```nupp
function waitQuery(name: string, condition: QueryCondition): Node
```
Builds a step that blocks until a registered query matches or stops
matching.
Unlike a signal, which is an edge, this is a condition on the world: a wait
whose condition already holds resumes rather than waiting for a transition
that has already happened. The condition is evaluated at the start of a
fixed step rather than at the instruction, so a query wait costs at least
one step.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `name` | `string` | the registered query name, resolved per world when the instruction runs |
| `condition` | `QueryCondition` | `"any"` to wait for a match or `"empty"` to wait for none |
#### Returns
| Type | Description |
| --- | --- |
| `Node` | a step for `define`, not to be put in a second program |
#### Raises
- when the name is empty or the condition is neither value
### `waitSignal` _function_
```nupp
function waitSignal(name: string): Node
```
Builds a step that blocks until `signal` raises a named signal.
The next fixed step delivers signals after `signal` runs, so a signal one
sequence raises never runs another within the same step. A signal raised
before the wait is not remembered.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `name` | `string` | the signal name, which is registered nowhere |
#### Returns
| Type | Description |
| --- | --- |
| `Node` | a step for `define`, not to be put in a second program |
#### Raises
- when the name is empty
### `waitSteps` _function_
```nupp
function waitSteps(steps: integer): Node
```
Builds a step that waits a whole number of ticks of the program's clock.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `steps` | `integer` | the non-negative tick count, where zero yields until the next tick |
#### Returns
| Type | Description |
| --- | --- |
| `Node` | a step for `define`, not to be put in a second program |
#### Raises
- when the count is negative or not a whole number
### `waitTween` _function_
```nupp
function waitTween(): Node
```
Builds a step that waits for the playback the most recent `playTween`
started.
It resumes when that specific playback completes, is canceled, loses its
channel, or loses its entity, so it never waits forever, and `status`
reports the outcome as `tweenOutcome`. A `waitTween` that no `playTween`
preceded falls straight through without costing a tick.
#### Returns
| Type | Description |
| --- | --- |
| `Node` | a step for `define`, not to be put in a second program |
## Values
### `DEFAULT_BUDGET` _variable_
```nupp
const DEFAULT_BUDGET: integer
```
The per-tick instruction budget a world gives a playback that asks for
none.
### `TrackingTarget` _variable_
```nupp
const TrackingTarget: components.TableComponent
```
The process-wide component a `tweenTrack` tracking source reads.