On this page
  1. tecs.sequence
  2. Programs and actions
  3. Clocks and waits
  4. Ownership
  5. Timelines
  6. Module contents
    1. Types
    2. Functions
    3. Values
  7. Types
    1. Action
    2. ActionContext
    3. Argument
    4. Awaitable
    5. ClockId
    6. DefineOptions
    7. EasingFunction
    8. EasingName
    9. EntityRef
    10. Evaluator
    11. FaultReason
    12. Handle
    13. Node
    14. PlaybackMode
    15. PlaybackState
    16. PlayOptions
    17. Program
    18. QueryCondition
    19. RunOptions
    20. Status
    21. Step
    22. Target
    23. TargetName
    24. TimelineNode
    25. TimelineOptions
    26. TimelineSpec
    27. TrackSource
    28. TweenOutcome
  8. Functions
    1. activeCount
    2. await
    3. bind
    4. call
    5. cancel
    6. cancelOwnedBy
    7. currentStep
    8. dataOps
    9. define
    10. defineData
    11. disassemble
    12. emit
    13. eval
    14. fork
    15. hasAction
    16. hasQuery
    17. join
    18. loop
    19. parallel
    20. pause
    21. play
    22. playbacks
    23. playTween
    24. plugin
    25. program
    26. programNames
    27. registerAction
    28. registerAwaitable
    29. registerEvaluator
    30. registerQuery
    31. resume
    32. setInstructionBudget
    33. signal
    34. signalOnEvent
    35. status
    36. timeline
    37. tweenAdjust
    38. tweenEmit
    39. tweenParallel
    40. tweenRun
    41. tweenTo
    42. tweenTrack
    43. tweenWait
    44. upcoming
    45. wait
    46. waitingOn
    47. waitQuery
    48. waitSignal
    49. waitSteps
    50. waitTween
  9. Values
    1. easing
    2. Event
    3. source
    4. target
    5. TrackingTarget

tecs.sequence

Snapshot-safe programs, waits, ownership, actions, and tween timelines.

Sequences store control flow as data. Snapshots, rewind, and hot reload can therefore preserve a playback's program, instruction pointer, waits, bindings, and parameters.

Programs and actions

Register an action on the world, name it from a program, and bind each playback to the entities it acts on:

local sequence <const> = tecs.sequence

sequence.registerAction(
    world,
    "game.lockControls",
    function(_world, _ctx) controlsLocked = true end
)

local intro <const> = sequence.define(
    "game.bossIntro",
    {
        sequence.call("game.lockControls"),
        sequence.wait(1.5),
        sequence.emit("boss.ready"),
    }
)

local playback <const> = sequence.play(
    world,
    intro,
    {
        owner = encounter,
        bindings = {boss = bossEntity},
    }
)

Program names form a snapshot compatibility surface. Use stable, qualified names for game and plugin programs. Redefining a name creates a new version. Running playbacks keep their original instructions, while later calls to play use the new program. Action bodies resolve by name when they run, so a reload can replace action code without moving a live program counter.

Actions run synchronously and cannot yield. An action that raises faults its playback after preserving mutations it already completed. Keep wall-clock, file, and network access outside deterministic actions.

Clocks and waits

"fixed" advances once per fixed step and serves deterministic gameplay. "frame" advances once per gameplay frame. "presentation" advances with display time and serves values simulation never reads.

Durations use seconds. Step and tick values count whole advances of the program's clock. Every positive duration waits at least one tick. waitSteps(0) yields until the next tick and gives a loop a fresh instruction budget.

Ownership

owner ties a playback to an entity. 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. The playback resumes only after every holder releases it. Branches inherit owner, bindings, parameters, budget, and pause state. A branch cannot outlive its parent.

Each playback receives a bounded instruction budget per tick. Exceeding it faults with budgetExceeded instead of hanging the frame.

Timelines

Timelines compile tweens into the same runtime and retain the same ownership, clock, channel, pause, and snapshot rules. Targets interpolate component fields. Parallel blocks share a start time, while sequential blocks start after the previous block ends.

Module contents

Types

Type Kind Description
Action type Defines a registered effect that runs synchronously and cannot yield.
ActionContext record Provides the context received by a registered action.
Argument type Represents constants passed from call to its action.
Awaitable record Defines the response required from an awaitable provider.
ClockId enum Selects the clock against which a program runs.
DefineOptions record Configures define.
EasingFunction type Maps normalized input progress to eased output progress.
EasingName enum Names a built-in easing curve and describes the shape of any curve.
EntityRef record References an entity supplied at play time and resolves it when the instruction that uses it runs.
Evaluator record Defines the evaluator run by an eval step every tick.
FaultReason enum Explains why a cursor stopped running.
Handle type Identifies one playback through a generation-checked reference that remains meaningful across a snapshot load.
Node interface Represents one authored step produced by the node constructors below.
PlaybackMode enum Selects how a timeline repeats.
PlaybackState enum Describes the lifecycle state of one playback.
PlayOptions record Configures play.
Program interface Represents a compiled, immutable program produced by define and shared by every playback of it.
QueryCondition enum Describes the condition awaited by a waitQuery step.
RunOptions record Configures how tweenRun plays its nested timeline.
Status record Reports a playback's current state.
Step record Describes one step a playback will reach without branching.
Target interface Describes the component and one to four numeric fields written by a timeline operation.
TargetName enum Names a built-in component-field target.
TimelineNode type Represents one authored timeline operation.
TimelineOptions record Configures timeline.
TimelineSpec type Lists timeline operations in execution order.
TrackSource interface Provides a live component-field tracking source.
TweenOutcome enum Reports how the tween awaited by waitTween ended.

Functions

Function Kind Description
activeCount Static Returns the number of live playbacks for tests and diagnostics.
await Static Waits for work outside the sequencer to finish.
bind Static References an entity supplied through PlayOptions.bindings.
call Static Runs a registered action.
cancel Static Stops a playback and releases its cursor.
cancelOwnedBy Static Cancels every playback owned by an entity.
currentStep Static Returns a clock's current tick as counted by the sequencer.
dataOps Static Returns the step names accepted by defineData, sorted.
define Static Compiles a program under a stable symbolic name.
defineData Static Compiles a program written as plain data instead of node calls.
disassemble Static Renders a program as readable instructions.
emit Static Emits an ECS event at address zero.
eval Static Evaluates a registered evaluator every tick until it finishes.
fork Static Starts a branch that runs alongside the rest of the program.
hasAction Static Returns whether this world has registered an action name.
hasQuery Static Returns whether this world has registered a query name.
join Static Waits for every branch that has not yet joined.
loop Static Repeats a block.
parallel Static Forks several blocks and waits for all of them.
pause Static Suspends a playback, its branches, and anything it started.
play Static Starts a program.
playbacks Static Returns handles for every live playback, branches included, in a stable order.
playTween Static Plays a registered tween preset on a bound entity.
plugin Static Installs the sequencer.
program Static Returns the newest version of a defined program or a requested version.
programNames Static Returns the names of every defined program, sorted.
registerAction Static Registers an action that a call node can name.
registerAwaitable Static Registers a provider that an await step can name.
registerEvaluator Static Registers an evaluator that an eval step can name.
registerQuery Static Registers a query that a waitQuery step can name.
resume Static Releases one holder's claim.
setInstructionBudget Static Sets the per-step instruction budget for playbacks without their own.
signal Static Raises a named signal and wakes every playback blocked on it.
signalOnEvent Static Raises a signal whenever an event emits at address zero.
status Static Returns playback status, or nil for a handle this world never issued.
timeline Static Compiles a tween timeline into a program under a stable name.
tweenAdjust Static Interpolates by a relative delta from the starting value.
tweenEmit Static Emits a named sequence.Event when the cursor reaches this point.
tweenParallel Static Runs timeline nodes concurrently and ends with the longest.
tweenRun Static Runs a nested timeline from its own spec.
tweenTo Static Interpolates to an absolute destination.
tweenTrack Static Interpolates toward a destination that keeps moving.
tweenWait Static Advances the timeline cursor without changing anything.
upcoming Static Returns the actions a playback will certainly perform next and their timing.
wait Static Waits for a duration in seconds.
waitingOn Static Returns how many playbacks currently wait on a signal name.
waitQuery Static Blocks until a registered query matches or stops matching.
waitSignal Static Blocks until signal raises the named signal.
waitSteps Static Waits for a whole number of ticks of the program's clock.
waitTween Static Waits for the tween started by the most recent playTween.

Values

Value Type Description
easing Easings Read-only. Exposes built-in easing curves such as sequence.easing.quadOut.
Event Event Read-only. Exposes the event emitted by an emit step at address zero.
source Sources Read-only. Exposes sources from which tweenTrack reads changing values: sequence.source.own(Transform2D, "x").
target Targets Read-only. Exposes built-in targets and constructors for new ones: sequence.target.translateX,...
TrackingTarget TrackingTarget Read-only. Exposes the component that selects a dynamic tracking-source entity.

Types

tecs.sequence.Action type

Defines a registered effect that runs synchronously and cannot yield.

type tecs.sequence.Action = function(World, ActionContext)

tecs.sequence.ActionContext record

Provides the context received by a registered action. The context and its args belong to the sequencer, which reuses them for the next call.

record tecs.sequence.ActionContext
    world: World
    handle: Handle
    owner: integer
    args: {any}
    params: {string: any}

    bind: function(self, string, integer)
    entity: function(self, string): integer
end

tecs.sequence.ActionContext.world field

Read-only. The world this playback belongs to.

tecs.sequence.ActionContext.world: World

tecs.sequence.ActionContext.handle field

Read-only. The playback, for status or cancel from inside an action.

tecs.sequence.ActionContext.handle: Handle

tecs.sequence.ActionContext.owner field

Read-only. The owner supplied at play, or 0 for a world-scoped sequence.

tecs.sequence.ActionContext.owner: integer

tecs.sequence.ActionContext.args field

Read-only. Constants supplied by the call node, with any bind references already resolved to entity ids.

tecs.sequence.ActionContext.args: {any}

tecs.sequence.ActionContext.params field

Read-only. The params supplied at play, or nil. Unlike args, this is the playback's own table rather than borrowed scratch, and it is the same one every step of the playback sees.

tecs.sequence.ActionContext.params: {string: any}

tecs.sequence.ActionContext:bind Instance

Name 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.

function tecs.sequence.ActionContext.bind(self, string, integer)
Arguments
Name Type Description
self ActionContext
#2 string
#3 integer
Returns

None.

tecs.sequence.ActionContext:entity Instance

Resolve a named binding. Returns nil when the binding was not supplied or its entity is no longer alive.

function tecs.sequence.ActionContext.entity(self, string): integer
Arguments
Name Type Description
self ActionContext
#2 string
Returns
Type Description
integer

tecs.sequence.Argument type

Represents constants passed from call to its action.

type tecs.sequence.Argument = any

tecs.sequence.Awaitable record

Defines the response required from an awaitable provider.

record tecs.sequence.Awaitable
    isPending: function(World, integer, string): boolean
    setPaused: function(World, integer, string, boolean)
end

tecs.sequence.Awaitable.isPending Static

Whether the work named by entity and key is still going.

Called at a step boundary for every cursor parked on this name, so it must be cheap and must not mutate the world. Returning false for something that never started is correct: a program waiting for an animation that is already over should carry on, not hang.

function tecs.sequence.Awaitable.isPending(
    World, integer, string
): boolean
Arguments
Name Type Description
#1 World
#2 integer
#3 string
Returns
Type Description
boolean

tecs.sequence.Awaitable.setPaused Static

Stop and start the work, when the provider knows how.

Called when the playback parked on it is paused or resumed, so a cutscene that is waiting for an animation stops it rather than leaving it running underneath. Optional: a provider that cannot pause its work simply does not offer this.

function tecs.sequence.Awaitable.setPaused(
    World, integer, string, boolean
)
Arguments
Name Type Description
#1 World
#2 integer
#3 string
#4 boolean
Returns

None.

tecs.sequence.ClockId enum

Selects the clock against which a program runs.

enum tecs.sequence.ClockId
    "fixed"
    "frame"
    "presentation"
end

tecs.sequence.DefineOptions record

Configures define.

record tecs.sequence.DefineOptions
    clock: ClockId
end

tecs.sequence.DefineOptions.clock field

Caller-writable. Selects the clock counted by program waits and defaults to "fixed".

tecs.sequence.DefineOptions.clock: ClockId

tecs.sequence.EasingFunction type

Maps normalized input progress to eased output progress.

Easing shapes the value, not the schedule: the argument is how far through its own window the interpolation is, clamped to [0, 1], and the result is the fraction of the way from start to destination to place the target at. A curve that leaves [0, 1] overshoots the destination rather than the duration, which is what backOut and elasticOut are for. Compilation fixes the window, so no curve can make a timeline longer or shorter or move what follows it.

type tecs.sequence.EasingFunction = function(number): number

tecs.sequence.EasingName enum

Names a built-in easing curve and describes the shape of any curve.

enum tecs.sequence.EasingName
    "backIn"
    "backInOut"
    "backOut"
    "backOutIn"
    "bounceIn"
    "bounceInOut"
    "bounceOut"
    "bounceOutIn"
    "cubicIn"
    "cubicInOut"
    "cubicOut"
    "cubicOutIn"
    "elasticIn"
    "elasticInOut"
    "elasticOut"
    "elasticOutIn"
    "expoIn"
    "expoInOut"
    "expoOut"
    "expoOutIn"
    "linear"
    "quadIn"
    "quadInOut"
    "quadOut"
    "quadOutIn"
    "quartIn"
    "quartInOut"
    "quartOut"
    "quartOutIn"
    "quintIn"
    "quintInOut"
    "quintOut"
    "quintOutIn"
    "sineIn"
    "sineInOut"
    "sineOut"
    "sineOutIn"
end

tecs.sequence.EntityRef record

References an entity supplied at play time and resolves it when the instruction that uses it runs.

record tecs.sequence.EntityRef
    bindName: string
    isBinding: boolean
end

tecs.sequence.EntityRef.bindName field

Read-only. Name of the binding this reference resolves.

tecs.sequence.EntityRef.bindName: string

tecs.sequence.EntityRef.isBinding field

Read-only. Marker distinguishing a reference from an ordinary table argument.

tecs.sequence.EntityRef.isBinding: boolean

tecs.sequence.Evaluator record

Defines the evaluator run by an eval step every tick.

record tecs.sequence.Evaluator
    load: function(ProgramImpl, any, any): any
    newState: function(ProgramImpl, any, Cursor): any
    resolve: function(any): any
    save: function(any): any
    step: function(World, Cursor, number): boolean
end

tecs.sequence.Evaluator.load Static

function tecs.sequence.Evaluator.load(ProgramImpl, any, any): any
Arguments
Name Type Description
#1 ProgramImpl
#2 any
#3 any
Returns
Type Description
any

tecs.sequence.Evaluator.newState Static

Per-cursor working state, or nil when it needs none. data is what the eval step carried, resolved; the cursor is there for what belongs to the playback rather than the program, chiefly its owner and its params.

function tecs.sequence.Evaluator.newState(ProgramImpl, any, Cursor): any
Arguments
Name Type Description
#1 ProgramImpl
#2 any
#3 Cursor
Returns
Type Description
any

tecs.sequence.Evaluator.resolve Static

Turn the constants an eval step carries into whatever form is cheapest to read every tick: functions bound, names resolved.

Called once per program constant and the result shared by every playback of it, so this is where work that does not depend on the playback belongs. Omit it to hand the constants over as authored.

function tecs.sequence.Evaluator.resolve(any): any
Arguments
Name Type Description
#1 any
Returns
Type Description
any

tecs.sequence.Evaluator.save Static

Turn working state into something a snapshot can carry, and back. Without both, an evaluating playback comes back at the start of its state rather than where it was.

function tecs.sequence.Evaluator.save(any): any
Arguments
Name Type Description
#1 any
Returns
Type Description
any

tecs.sequence.Evaluator.step Static

Advance one cursor by dt. Returns true when it is finished and the cursor should move on to the next instruction.

function tecs.sequence.Evaluator.step(World, Cursor, number): boolean
Arguments
Name Type Description
#1 World
#2 Cursor
#3 number
Returns
Type Description
boolean

tecs.sequence.FaultReason enum

Explains why a cursor stopped running.

enum tecs.sequence.FaultReason
    "actionError"
    "branchFaulted"
    "budgetExceeded"
    "unregisteredAction"
    "unregisteredAwaitable"
    "unregisteredEvaluator"
    "unregisteredQuery"
    "unregisteredTween"
end

tecs.sequence.Handle type

Identifies one playback through a generation-checked reference that remains meaningful across a snapshot load.

type tecs.sequence.Handle = seqtypes.Handle

tecs.sequence.Node interface

Represents one authored step produced by the node constructors below. Treat the returned value as opaque and do not reuse a node across programs.

interface tecs.sequence.Node
end

tecs.sequence.PlaybackMode enum

Selects how a timeline repeats.

enum tecs.sequence.PlaybackMode
    "loop"
    "once"
    "pingPong"
end

tecs.sequence.PlaybackState enum

Describes the lifecycle state of one playback.

enum tecs.sequence.PlaybackState
    "canceled"
    "completed"
    "faulted"
    "paused"
    "running"
end

tecs.sequence.PlayOptions record

Configures play.

record tecs.sequence.PlayOptions
    owner: integer
    bindings: {string: integer}
    params: {string: any}
    budget: integer
    channel: string
end

tecs.sequence.PlayOptions.owner field

Caller-writable. Entity whose lifetime governs the playback. When it despawns, the playback is canceled. Omit for a world-scoped sequence.

tecs.sequence.PlayOptions.owner: integer

tecs.sequence.PlayOptions.bindings field

Caller-writable. Entities the program acts on, addressed by sequence.bind(name).

tecs.sequence.PlayOptions.bindings: {string: integer}

tecs.sequence.PlayOptions.params field

Caller-writable. Constants this playback runs with, readable by its actions and its evaluators. A program is shared by every playback of it, so anything that differs between two of them belongs here rather than in the program. Plain data, for the same reason a call argument is: it travels with a snapshot.

tecs.sequence.PlayOptions.params: {string: any}

tecs.sequence.PlayOptions.budget field

Caller-writable. Per-step instruction budget for this playback. Defaults to the world's configured budget. See setInstructionBudget.

tecs.sequence.PlayOptions.budget: integer

tecs.sequence.PlayOptions.channel field

Caller-writable. Names a slot this playback occupies on its owner. Starting another playback on the same owner and channel cancels this one, which is how a second fade replaces the first rather than fighting it.

tecs.sequence.PlayOptions.channel: string

tecs.sequence.Program interface

Represents a compiled, immutable program produced by define and shared by every playback of it. See internal/types for the full contract.

interface tecs.sequence.Program
    name: string
    version: integer
end

tecs.sequence.Program.name field

Read-only. The name passed to define.

tecs.sequence.Program.name: string

tecs.sequence.Program.version field

Read-only. Monotonic version, starting at 1. Incremented per redefinition.

tecs.sequence.Program.version: integer

tecs.sequence.QueryCondition enum

Describes the condition awaited by a waitQuery step.

enum tecs.sequence.QueryCondition
    "any"
    "empty"
end

tecs.sequence.RunOptions record

Configures how tweenRun plays its nested timeline.

Omitting it runs the nested timeline once. A nested "loop" or "pingPong" must set count, because a parent has to know how long its own window is; only the root timeline of a sequence.timeline, through params, may repeat without one.

record tecs.sequence.RunOptions
    mode: PlaybackMode
    count: integer
end

tecs.sequence.RunOptions.mode field

Caller-writable. Nested timeline playback mode. Defaults to "once".

tecs.sequence.RunOptions.count field

Caller-writable. Pass count for the nested timeline.

tecs.sequence.RunOptions.count: integer

tecs.sequence.Status record

Reports a playback's current state.

record tecs.sequence.Status
    state: PlaybackState
    program: string
    version: integer
    pc: integer
    wakeAt: integer
    waitingFor: string
    waitingQuery: string
    waitingCondition: QueryCondition
    waitingAwaitable: string
    waitingAwaitableEntity: integer
    waitingTween: integer
    tweenOutcome: TweenOutcome
    branches: integer
    joining: boolean
    fault: FaultReason
    faultMessage: string
end

tecs.sequence.Status.state field

Read-only.

tecs.sequence.Status.state: PlaybackState

tecs.sequence.Status.program field

Read-only. Program name this playback is running.

tecs.sequence.Status.program: string

tecs.sequence.Status.version field

Read-only. Program version this playback is running.

tecs.sequence.Status.version: integer

tecs.sequence.Status.pc field

Read-only. Instruction index, for disassembly and debugging.

tecs.sequence.Status.pc: integer

tecs.sequence.Status.wakeAt field

Read-only. Fixed step this playback next runs on. Nil when it is blocked on a signal rather than a time.

tecs.sequence.Status.wakeAt: integer

tecs.sequence.Status.waitingFor field

Read-only. Signal name this playback is blocked on, when it is.

tecs.sequence.Status.waitingFor: string

tecs.sequence.Status.waitingQuery field

Read-only. Query name this playback is blocked on, when it is, and the condition it is waiting for.

tecs.sequence.Status.waitingQuery: string

tecs.sequence.Status.waitingCondition field

Read-only. Query condition this playback is waiting for.

tecs.sequence.Status.waitingAwaitable field

Read-only. Awaitable provider this playback is blocked on, when it is, and the entity it is waiting on.

tecs.sequence.Status.waitingAwaitable: string

tecs.sequence.Status.waitingAwaitableEntity field

Read-only. Entity this playback's awaitable is waiting on.

tecs.sequence.Status.waitingAwaitableEntity: integer

tecs.sequence.Status.waitingTween field

Read-only. Tween playback token this playback is blocked on, when it is.

tecs.sequence.Status.waitingTween: integer

tecs.sequence.Status.tweenOutcome field

Read-only. How the last tween it waited on ended.

tecs.sequence.Status.branches field

Read-only. Live branches this playback forked and has not joined.

tecs.sequence.Status.branches: integer

tecs.sequence.Status.joining field

Read-only. Whether it is parked at a join waiting for those branches.

tecs.sequence.Status.joining: boolean

tecs.sequence.Status.fault field

Read-only. Set when state is "faulted".

tecs.sequence.Status.fault: FaultReason

tecs.sequence.Status.faultMessage field

Read-only. Error message set when state is "faulted".

tecs.sequence.Status.faultMessage: string

tecs.sequence.Step record

Describes one step a playback will reach without branching.

record tecs.sequence.Step
    ticks: integer
    kind: string
    name: string
    args: {any}
end

tecs.sequence.Step.ticks field

Read-only. Ticks of the program's clock from the reference point until it runs.

tecs.sequence.Step.ticks: integer

tecs.sequence.Step.kind field

Read-only. "call" or "emit".

tecs.sequence.Step.kind: string

tecs.sequence.Step.name field

Read-only. Action name for a call, event name for an emit.

tecs.sequence.Step.name: string

tecs.sequence.Step.args field

Read-only. Constants the step carries, unresolved.

tecs.sequence.Step.args: {any}

tecs.sequence.Target interface

Describes the component and one to four numeric fields written by a timeline operation. numeric fields of it to interpolate.

Opaque, and built only through sequence.target: a built-in such as sequence.target.translateXY, or sequence.target.field(C, "hp") for a component of your own. Every operation that takes one also accepts a TargetName naming the same built-in, which is the form that survives defineData. Safe to share between timelines: a target holds no per-playback state.

interface tecs.sequence.Target
end

tecs.sequence.TargetName enum

Names a built-in component-field target.

enum tecs.sequence.TargetName
    "color.a"
    "color.rgba"
    "transform.rotation"
    "transform.rotationShortest"
    "transform.scaleX"
    "transform.scaleXY"
    "transform.scaleY"
    "transform.x"
    "transform.xy"
    "transform.y"
end

tecs.sequence.TimelineNode type

Represents one authored timeline operation.

type tecs.sequence.TimelineNode = {any}

tecs.sequence.TimelineOptions record

Configures timeline.

record tecs.sequence.TimelineOptions
    clock: ClockId
end

tecs.sequence.TimelineOptions.clock field

Caller-writable. Selects the clock used to evaluate the timeline. It defaults to "presentation", which moves at the display's rate. "fixed" makes it deterministic from a snapshot alone, at the cost of stepping at the simulation's rate: the renderer interpolates only Transform2D between fixed steps, so a fixed-clock tween of anything else visibly steps. If the simulation can observe the value, put it on "fixed".

tecs.sequence.TimelineSpec type

Lists timeline operations in execution order.

Entries run one after the next, each starting where the one before it ended, except that a tweenParallel runs its arguments from a shared start. A nested list is read as a block and behaves the same as one.

timeline and tweenRun compile the resolved form into the same table, consuming the spec. Pass a fresh spec to each timeline.

type tecs.sequence.TimelineSpec = {TimelineNode}

tecs.sequence.TrackSource interface

Provides a live component-field tracking source.

interface tecs.sequence.TrackSource
end

tecs.sequence.TweenOutcome enum

Reports how the tween awaited by waitTween ended.

enum tecs.sequence.TweenOutcome
    "canceled"
    "completed"
    "replaced"
    "targetLost"
end

Functions

tecs.sequence.activeCount Static

Returns the number of live playbacks for tests and diagnostics.

function tecs.sequence.activeCount(world: World): integer

Arguments

Name Type Description
world World The world owns the playbacks.

Returns

Type Description
integer Branches counted individually, since a branch is a playback of its own, and so are the playbacks a playTween started.

tecs.sequence.await Static

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: there is nothing to wait for and the program carries on. So is a provider reporting a thing that never started.

sequence.call("game.playTag", sequence.bind("hero"), "hurt"), sequence.await("game.spriteAnimation", sequence.bind("hero")),

function tecs.sequence.await(
    provider: string, target: EntityRef, key: string
): Node

Arguments

Name Type Description
provider string Resolved globally when the instruction runs, and checked before the binding: a name no build registered faults the playback with unregisteredAwaitable. The runtime asks the provider again at each fixed step boundary while the playback waits. An error faults the playback with actionError.
target EntityRef A bind reference and nothing else, as playTween's is. An entity that dies while the playback waits releases it rather than stranding it for the life of the world.
key string Handed to the provider unread, for a provider that answers about more than one thing per entity. Nil when omitted, which is what a provider with one answer per entity sees.

Returns

Type Description
Node A node for define, and not to be put in a second program.

tecs.sequence.bind Static

References an entity supplied through PlayOptions.bindings.

Resolved when the instruction using it runs, not at play, so a binding may name an entity that does not exist yet.

function tecs.sequence.bind(name: string): EntityRef

Arguments

Name Type Description
name string Must be non-empty, and an empty one raises here rather than at define. The runtime matches it against PlayOptions.bindings. A missing binding resolves to nothing instead of faulting.

Returns

Type Description
EntityRef A reference to put in a call or emit argument list, or to hand to playTween or await. The program interns it in the const pool, and each playback resolves it against its own bindings.

tecs.sequence.call Static

Runs a registered action.

function tecs.sequence.call(action: string, ...: Argument): Node

Arguments

Name Type Description
action string Resolved per world when the instruction runs, not at define, so a program may name an action registered later. A name still unregistered when the step runs faults the playback.
... Argument Compiled into the program's const pool, so they are the same values for every playback of it. Put anything that differs between two playbacks in PlayOptions.params instead.

Returns

Type Description
Node A node for define, and not to be put in a second program.

tecs.sequence.cancel Static

Stops a playback and releases its cursor. This remains safe on a finished handle.

It takes the branches it 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.

function tecs.sequence.cancel(world: World, handle: Handle): boolean

Arguments

Name Type Description
world World The world owns the playback.
handle Handle Read against this world's cursor arena, so one issued by another world is meaningless here rather than reliably ignored.

Returns

Type Description
boolean false when the handle names nothing running, whether it already finished or was already canceled.

tecs.sequence.cancelOwnedBy Static

Cancels every playback owned by an entity.

reason is what anything waiting on one of them is told. The owner despawning reports targetLost, which lets a waiter distinguish cancellation from target loss.

function tecs.sequence.cancelOwnedBy(
    world: World, owner: integer, reason: TweenOutcome
): integer

Arguments

Name Type Description
world World The world owns the playbacks.
owner integer An entity id. A playback started without an owner is nothing owns a playback started without an owner, rather than entity 0, 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, and what its status reports afterwards as tweenOutcome. Omitted, a waiter is told canceled.

Returns

Type Description
integer Returns the number of canceled playbacks, or zero when the entity owns none. The call reaches branches through their inherited owner and counts each cursor once.

tecs.sequence.currentStep Static

Returns a clock's current tick as counted by the sequencer. It defaults to the fixed clock.

function tecs.sequence.currentStep(
    world: World, clock: ClockId
): integer

Arguments

Name Type Description
world World The world owns the clock counters.
clock ClockId Which of the three counters to read. Omitted, "fixed".

Returns

Type Description
integer Ticks of that one clock, rising by one each time the sequencer advances it and by nothing else. It counts from when this world's the world created its sequencer state, not when the process started. A snapshot load puts back the count the snapshot carried. Comparable only against another reading of the same clock.

tecs.sequence.dataOps Static

Returns the step names accepted by defineData, sorted.

function tecs.sequence.dataOps(): {string}

Arguments

None.

Returns

Type Description
{string} A fresh table each call, which the caller owns. It is narrower than the node constructors: await and eval have no data form and are not among them.

tecs.sequence.define Static

Compiles a program under a stable symbolic name.

options.clock picks what the program's waits count. "fixed", the default, counts fixed steps and is what gameplay logic wants. "frame" counts gameplay frames, one tick per frame however many fixed steps that frame runs, which is what scripted input needs. "presentation" also ticks once per gameplay frame carrying the frame's real elapsed time.

function tecs.sequence.define(
    name: string, nodes: {Node}, options: DefineOptions
): Program

Arguments

Name Type Description
name string 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.
nodes {Node} Accepts an empty list, which compiles to a program that completes on its first tick.
options DefineOptions Omitted, the program counts fixed steps. A clock that is none of the three names raises here.

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.

tecs.sequence.defineData Static

Compiles a program written as plain data instead of node calls.

The same authoring surface as a list of steps, for callers that cannot invoke Lua: a tool over MCP, a file on disk, a hand-written table. Returns nil plus the path to the first bad entry.

sequence.defineData("game.intro", { {op = "call", action = "game.lockControls"}, {op = "wait", seconds = 1.5}, })

function tecs.sequence.defineData(
    name: string, rows: {any}, options: DefineOptions
): Program, string

Arguments

Name Type Description
name string As define's, and sharing its namespace and its versioning.
rows {any} One table per step, keyed by op and the fields that step takes. dataOps lists the step names. This function rejects an empty list, unlike define, because it has nothing to run.
options DefineOptions As define's.

Returns

Type Description
Program The compiled program, or nil when a row is bad.
string nil on success; on failure the path to the first bad entry, as program[2].loop[1], and what it was missing. That is why the two are never both set. A row whose shape is right and whose value is not, a negative wait among them, raises instead: the path covers what this decoder checks, not what the node constructors do.

tecs.sequence.disassemble Static

Renders a program as readable instructions.

function tecs.sequence.disassemble(
    program: Program, pc: integer
): string

Arguments

Name Type Description
program Program A value from define or timeline; anything else raises.
pc integer Mark this instruction, as a playback's status reports it. Omit for an unmarked listing. One past the end, or any other address the program does not hold, marks nothing.

Returns

Type Description
string A header naming the program and its version, then one line per instruction, newline separated. For reading and not for parsing: the format is free to change.

tecs.sequence.emit Static

Emits an ECS event at address zero.

Occupies no tick: the step after it runs in the same one.

function tecs.sequence.emit(event: string, ...: Argument): Node

Arguments

Name Type Description
event string Carried as the sequence.Event's name. Observers watch sequence.Event itself and filter on this, rather than each name being an event type of its own.
... Argument Const-pool values, as call's are, delivered on the event's args with any bind reference already resolved to an entity id. Each emit copies the list and sends it with the event, so an observer may keep it, unlike the one an action receives.

Returns

Type Description
Node A node for define, and not to be put in a second program.

tecs.sequence.eval Static

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.

Compilation stores data beside the evaluator's name in the program, so it travels with a snapshot and must remain plain data for the same reason a call argument does. What the evaluator makes of it is its own business.

function tecs.sequence.eval(evaluator: string, data: any): Node

Arguments

Name Type Description
evaluator string Resolved globally when the instruction runs, so a program may name an evaluator registered later. A name still unregistered when the step runs faults the playback with unregisteredEvaluator, and an evaluator that raises while resolving the data or building its state faults it with actionError.
data any Passed through the evaluator's resolve once per program constant and the answer shared by every playback of it, so an evaluator must not write per-playback state into what it gets back. Omit it for an evaluator that needs none.

Returns

Type Description
Node A node for define, and not to be put in a second program.

tecs.sequence.fork Static

Starts a branch that runs alongside the rest of the program.

The branch is a playback of its own running the same program at a different instruction, and it inherits the owner, bindings, params 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 the playback that forked it: finishing or canceling that playback cancels the branches it has not joined. A branch that faults takes its parent with it, faulted branchFaulted, rather than leaving a join one branch short forever.

function tecs.sequence.fork(nodes: {Node}): Node

Arguments

Name Type Description
nodes {Node} The branch body, run in order. Must be non-empty. It reads and writes the forking playback's own bindings table rather than a copy, so both see any name an action binds.

Returns

Type Description
Node A node for define, and not to be put in a second program.

tecs.sequence.hasAction Static

Returns whether this world has registered an action name.

function tecs.sequence.hasAction(world: World, name: string): boolean

Arguments

Name Type Description
world World The world owns the action registry.
name string The caller supplies the action name to find.

Returns

Type Description
boolean false for a name this world never registered, including one another world has: actions are per world.

tecs.sequence.hasQuery Static

Returns whether this world has registered a query name.

function tecs.sequence.hasQuery(world: World, name: string): boolean

Arguments

Name Type Description
world World The world owns the query registry.
name string The caller supplies the query name to find.

Returns

Type Description
boolean false for a name this world never registered, including one another world has: queries are per world.

tecs.sequence.join Static

Waits for every branch that has not yet joined.

Falls straight through when there are none. When the last branch finishes, the waiting playback resumes within that same tick.

function tecs.sequence.join(): Node

Arguments

None.

Returns

Type Description
Node A node for define, and not to be put in a second program.

tecs.sequence.loop Static

Repeats a block.

function tecs.sequence.loop(count: integer, nodes: {Node}): Node

Arguments

Name Type Description
count integer Iterations, or nil to repeat until canceled. A positive whole number. This function rejects zero and fractions.
nodes {Node} The block, run in order and started again from its first node. Must be non-empty. A block with no wait in it spends the playback's per-step instruction budget within one tick and faults it with budgetExceeded, which is what that budget is for.

Returns

Type Description
Node A node for define, and not to be put in a second program.

tecs.sequence.parallel Static

Forks several blocks and waits for all of them.

Sugar for a fork per block followed by one join. Blocks start in argument order.

function tecs.sequence.parallel(...: {Node}): Node

Arguments

Name Type Description
... {Node} Supplies at least one non-empty node list, one per branch. Each shares the playback's bindings table, as a fork does.

Returns

Type Description
Node A node for define, and not to be put in a second program.

tecs.sequence.pause Static

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. holder names who is holding it and defaults to "user".

Its wait, if any, resumes from where it paused. What it is waiting on stops with it when the awaitable provider knows how.

function tecs.sequence.pause(
    world: World, handle: Handle, holder: string
): boolean

Arguments

Name Type Description
world World The world owns the playback.
handle Handle The caller supplies the playback to pause.
holder string Any string, and a set rather than a count: two pauses under the same holder are one hold, and one resume under it releases both. Two callers that both leave it at the default therefore share a single hold.

Returns

Type Description
boolean Whether the playback stopped. A second holder taking a hold on one that is already paused registers the hold and returns false, because nothing observable changed. So does a handle that names nothing running.

tecs.sequence.play Static

Starts a program. The first instruction runs on the next tick of the program's own clock, never inside this call.

function tecs.sequence.play(
    world: World, program: Program, options: PlayOptions
): Handle

Arguments

Name Type Description
world World The world owns the new playback.
program Program A value from define or timeline, not a name. The playback runs this version for its whole life, even if another define replaces the name. Anything other than a compiled program raises.
options PlayOptions Omitted, the playback has no owner, no bindings, no params, no channel, and the world's instruction budget. 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, valid until it ends. A handle carries a generation, so one whose playback has ended never names a later playback that took the same slot.

tecs.sequence.playbacks Static

Returns handles for every live playback, branches included, in a stable order. For diagnostics and the debugger, not for hot paths.

function tecs.sequence.playbacks(world: World): {Handle}

Arguments

Name Type Description
world World The world owns the playbacks.

Returns

Type Description
{Handle} Returns a fresh table ordered by cursor slot. Slot order remains stable within a run but differs from creation order because new playbacks reuse free slots. The table also includes playbacks started by playTween.

tecs.sequence.playTween Static

Plays a registered tween preset on a bound entity.

Needs the sequencer, which tecs.newApplication installs. A binding that is missing or dead is not a fault: nothing plays, and a following waitTween resumes at once reporting targetLost.

The step itself 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.

function tecs.sequence.playTween(
    timeline: string, target: EntityRef, params: {string: any}
): Node

Arguments

Name Type Description
timeline string Resolved when the instruction runs, and always to the newest version of the name; any program defined under it will do, though timeline is what normally publishes one. A name that is not defined faults the playback with unregisteredTween.
target EntityRef A bind reference and nothing else: an entity id raises here, for the same reason define rejects one as a constant.
params {string : any} The started playback's params, so mode, count, speed and delay shape it as they do for play. A channel in it names the slot the playback takes on that entity, canceling whatever held the slot and reporting replaced to anything waiting on it.

Returns

Type Description
Node A node for define, and not to be put in a second program.

tecs.sequence.plugin Static

Installs the sequencer. tecs.newApplication installs it automatically, and it remains safe to call again: a second install on the same world does nothing.

function tecs.sequence.plugin(world: World)

Arguments

Name Type Description
world World The world receives sequencer state and systems.

Returns

None.

tecs.sequence.program Static

Returns the newest version of a defined program or a requested version. Every version a playback still runs stays reachable.

function tecs.sequence.program(
    name: string, version: integer
): Program

Arguments

Name Type Description
name string The caller supplies a name previously passed to define or timeline.
version integer Versions start at 1 and rise by one per define of the same name. Omit it for the newest.

Returns

Type Description
Program nil when the name was never defined, or when that version was after a newer definition replaces it and its last playback ends. The newest version of a name is never dropped.

tecs.sequence.programNames Static

Returns the names of every defined program, sorted.

function tecs.sequence.programNames(): {string}

Arguments

None.

Returns

Type Description
{string} A fresh table each call, which the caller owns. Registration is global, so this spans every world in the process.

tecs.sequence.registerAction Static

Registers an action that a call node 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.

function tecs.sequence.registerAction(
    world: World, name: string, action: Action
)

Arguments

Name Type Description
world World The world owns the action registry.
name string 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. An empty name raises.
action Action Must be a function, or this raises. Raising when it runs faults the playback with actionError, and whatever it already wrote to the world stays written: the sequencer rolls nothing back.

Returns

None.

tecs.sequence.registerAwaitable Static

Registers a provider that an await step can name. Registration remains global, like an evaluator, because a provider is code.

function tecs.sequence.registerAwaitable(
    name: string, provider: Awaitable
)

Arguments

Name Type Description
name string Registering a name twice replaces the provider, which is what a hot reload wants: a playback already parked on the name asks the new one at the next step. An empty name raises.
provider Awaitable Must carry isPending, or this raises. setPaused is optional. Without it, the provider leaves its work running when a pause stops the waiting playback.

Returns

None.

tecs.sequence.registerEvaluator Static

Registers an evaluator that an eval step can name.

Registration is global, like a program: an evaluator is code, and two worlds evaluating the same name run the same thing.

function tecs.sequence.registerEvaluator(
    name: string, evaluator: Evaluator
)

Arguments

Name Type Description
name string Registering a name twice replaces it. An empty name raises.
evaluator Evaluator Must carry step, or this raises. The rest are optional, and 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

None.

tecs.sequence.registerQuery Static

Registers a query that a waitQuery step can name.

The query subscribes to archetype transitions, so a wait on it stays event driven rather than polling. Registration is startup work: a name registered twice keeps the newer query, and the replaced one holds its subscriptions for the life of the world.

function tecs.sequence.registerQuery(
    world: World, name: string, descriptor: types.Query.Descriptor
)

Arguments

Name Type Description
world World The world owns the query registry.
name string Empty raises. Registering it again re-tests every playback already parked on the name, against the new query, at the next fixed step.
descriptor types.Query.Descriptor The function copies this descriptor and wraps its onEntitiesAdded and onEntitiesRemoved callbacks. It marks the name before calling the supplied callbacks. A non-table raises.

Returns

None.

tecs.sequence.resume Static

Releases one holder's claim.

function tecs.sequence.resume(
    world: World, handle: Handle, holder: string
): boolean

Arguments

Name Type Description
world World The world owns the playback.
handle Handle The caller supplies the paused playback.
holder string Must be the string that took the hold; releasing one that never held it changes nothing. Defaults to "user", as pause's does.

Returns

Type Description
boolean Whether the playback started running again, which is only true 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.

tecs.sequence.setInstructionBudget Static

Sets the per-step instruction budget for playbacks without their own.

function tecs.sequence.setInstructionBudget(
    world: World, instructions: integer
)

Arguments

Name Type Description
world World The world applies the budget to new playbacks.
instructions integer Must be at least 1. It caps how many instructions one playback runs per tick, and exceeding it faults the playback with budgetExceeded rather than deferring the rest, so it is a guard against a loop with no wait in it, not a scheduler. Applies to playbacks started after this call; a running one keeps the budget it started with.

Returns

None.

tecs.sequence.signal Static

Raises a named signal and wakes every playback blocked on it.

Delivery happens on the next fixed step. Raising a signal nothing is waiting on is not an error and is not remembered: a playback that reaches waitSignal afterwards keeps waiting.

function tecs.sequence.signal(world: World, name: string): integer

Arguments

Name Type Description
world World The world owns the signal state.
name string Any string, registered nowhere. An empty one raises.

Returns

Type Description
integer Returns the number of playbacks waiting on the name now. The next fixed step wakes the set waiting then, which may differ.

tecs.sequence.signalOnEvent Static

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: waiters wake on the next fixed step.

function tecs.sequence.signalOnEvent<T is events.Event>(
    world: World, name: string, event: T
)

Type Parameters

Name Constraint Description
T events.Event

Arguments

Name Type Description
world World The world owns the event observer and signal state.
name string The signal to raise, once per emission. An empty one raises.
event T Observed at address 0, and only there. The observer lasts for the life of the world; wiring the same pair twice observes it twice, and there is nothing that unwires one.

Returns

None.

tecs.sequence.status Static

Returns playback status, or nil for a handle this world never issued.

function tecs.sequence.status(world: World, handle: Handle): Status

Arguments

Name Type Description
world World The world owns the playback.
handle Handle Read against this world's cursor arena, as cancel's is.

Returns

Type Description
Status A fresh table each call, which the caller owns. A finished playback still answers, with state saying how it ended, until its a later play takes its slot. The runtime fills waiting fields only while the playback lives, so a finished playback reports its program, the pc it stopped at, how it ended and its last tween outcome, with the rest nil.

tecs.sequence.timeline Static

Compiles a tween timeline into a program under a stable name.

The compiled slots travel in the program's const 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.

It reads four params, all optional:

mode "once" (default), "loop", or "pingPong" count passes for a finite loop or ping-pong; endless without it speed playback multiplier, defaulting to 1 delay seconds to wait before the first frame

local fade = sequence.timeline("game.fade", { sequence.tweenTo(0.4, "quadOut", "color.a", 0), }) sequence.play(world, fade, {owner = e, params = {delay = 0.2}})

function tecs.sequence.timeline(
    name: string, spec: TimelineSpec, options: TimelineOptions
): Program

Arguments

Name Type Description
name string Shared with define's namespace, and versioned the same way: compiling over a live name publishes a new version and leaves playbacks of the old one running it.
spec TimelineSpec The compiler consumes this table in place. Do not compile it again.
options TimelineOptions Omitted, the timeline runs on the presentation clock. "fixed" and "presentation" are the only two accepted; "frame" raises, though define takes it.

Returns

Type Description
Program The compiled program, also reachable by name through program. Play it on an entity: a playback with no owner has nothing to write to and completes on its first tick without animating anything. The params above are read when that 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.

tecs.sequence.tweenAdjust Static

Interpolates by a relative delta from the starting value.

Identical to tweenTo except that t1 through t4 are the amount to move by rather than where to end up, so the destination depends on the entity's value when the operation evaluates its first tick.

function tecs.sequence.tweenAdjust(
    duration: number,
    curve: EasingName | EasingFunction,
    target: TargetName | Target,
    t1: number,
    t2: number,
    t3: number,
    t4: number
): TimelineNode

Arguments

Name Type Description
duration number Seconds, and strictly positive.
curve EasingName | EasingFunction As tweenTo's, and built in for the same reason.
target TargetName | Target Which component fields move, and in which order t1 through t4 line up with them.
t1 number Change applied to the target's first field, in that field's own units, and signed: negative moves the other way.
t2 number Change applied to the second field.
t3 number Change applied to the third field.
t4 number Change applied to the fourth field. An argument past the The compiler ignores arguments past the target's field count and treats an omitted argument as zero.

Returns

Type Description
TimelineNode Returns a node for a TimelineSpec. Its compiling timeline consumes it.

tecs.sequence.tweenEmit Static

Emits a named sequence.Event when the cursor reaches this point.

Occupies no time, so what follows it starts at the same instant. The event 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 pingPong's return leg does not fire it a second time.

function tecs.sequence.tweenEmit(name: string): TimelineNode

Arguments

Name Type Description
name string Carried on the event as its name; the sequencer attaches no meaning to it.

Returns

Type Description
TimelineNode Returns a node for a TimelineSpec.

tecs.sequence.tweenParallel Static

Runs timeline nodes concurrently and ends with the longest.

Every argument starts at the point the tweenParallel sits at, and what follows starts after the last of them ends. Two arguments writing the same component field is not an error and the later one in argument order wins each tick.

function tecs.sequence.tweenParallel(...: TimelineNode): TimelineNode

Arguments

Name Type Description
... TimelineNode One node per concurrent operation. A list of nodes counts as one argument and runs in sequence within it, which describes a branch longer than one operation.

Returns

Type Description
TimelineNode Returns a node for a TimelineSpec.

tecs.sequence.tweenRun Static

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 own operations keep their per-playback state separately from the parent's.

function tecs.sequence.tweenRun(
    spec: TimelineSpec, options: RunOptions
): TimelineNode

Arguments

Name Type Description
spec TimelineSpec Compiled in place if it has not been already, so the table given here belongs to this node afterwards.
options RunOptions Omit to run the nested timeline once. "loop" and "pingPong" need a count here, and compiling raises without one.

Returns

Type Description
TimelineNode Returns a node for a TimelineSpec.

tecs.sequence.tweenTo Static

Interpolates to an absolute destination.

The operation reads starting values from the entity on its first tick, not during compilation, so the same timeline played on two entities starts from wherever each of them is.

function tecs.sequence.tweenTo(
    duration: number,
    curve: EasingName | EasingFunction,
    target: TargetName | Target,
    t1: number,
    t2: number,
    t3: number,
    t4: number
): TimelineNode

Arguments

Name Type Description
duration number Supplies a strictly positive number of seconds. The compiler rejects zero. Use tweenWait for a gap that moves nothing.
curve EasingName | EasingFunction A name from sequence.easing, or one of those functions itself. The compiler rejects a custom curve: a compiled slot carries the curve's name so it can travel in a const pool, and a function it cannot name has none.
target TargetName | Target Which component fields move, and in which order t1 through t4 line up with them.
t1 number Destination for the target's first field, in that field's own units: pixels for a translate, radians for a rotation, 0 to 1 for a color channel. A shortest-path rotation target still takes an absolute angle and picks the short way round to it.
t2 number Destination for the second field, for a target that has one.
t3 number Destination for the third field, for a four-field target.
t4 number Destination for the fourth field, for a four-field target. The compiler ignores arguments past the target's field count and treats each omitted target field as zero.

Returns

Type Description
TimelineNode Returns a node for a TimelineSpec. Its compiling timeline consumes it.

tecs.sequence.tweenTrack Static

Interpolates toward a destination that keeps moving.

The first tick fixes the start, as with tweenTo, but each later tick reads the destination again from from while the operation remains inside its window, so the entity chases a value that is still changing. Once the window ends, the operation holds its last destination.

function tecs.sequence.tweenTrack(
    duration: number,
    curve: EasingName | EasingFunction,
    target: TargetName | Target,
    from: TrackSource
): TimelineNode

Arguments

Name Type Description
duration number Seconds, and strictly positive.
curve EasingName | EasingFunction As tweenTo's. It shapes how far toward the current destination the value sits, and that destination keeps moving underneath it.
target TargetName | Target Which component fields move, and which fields of from line up with them: the source is read into the same one to four numbers the target writes.
from TrackSource Where the destination is read each tick. A source whose entity or component is missing reads as zero rather than faulting, so an entity chasing something that despawned drifts to the origin. A source named by world key is the exception and requires the key to be set.

Returns

Type Description
TimelineNode Returns a node for a TimelineSpec. Its compiling timeline consumes it.

tecs.sequence.tweenWait Static

Advances the timeline cursor without changing anything.

function tecs.sequence.tweenWait(duration: number): TimelineNode

Arguments

Name Type Description
duration number Supplies seconds. Zero performs no work.

Returns

Type Description
TimelineNode Returns a node for a TimelineSpec.

tecs.sequence.upcoming Static

Returns the actions a playback will certainly perform next and their timing.

Walks the straight-line run ahead of where it sits, accumulating waits, and stops at the first instruction whose successor requires execution. It counts ticks in the playback's own clock, from now.

function tecs.sequence.upcoming(
    world: World, handle: Handle, withinTicks: integer
): {Step}

Arguments

Name Type Description
world World The world owns the playback.
handle Handle The caller supplies the playback to inspect.
withinTicks integer Report only what is due within this many ticks. Counted in the playback's own clock, from now. Omit for everything the walk can reach.

Returns

Type Description
{Step} A fresh table each call, holding the calls and emits ahead in order. Empty for a handle that names nothing running, and also 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, because converting it needs a clock the program does not carry. Each step's args is the program's own constant list rather than a copy of it, so read it and do not write to it. A paused playback still answers, counted as though it were running.

tecs.sequence.wait Static

Waits for a duration in seconds.

Converted to whole ticks when the instruction runs, rounded to nearest, with any non-zero duration waiting at least one tick. A program on the fixed clock divides the duration by the world's fixed timestep; the frame and presentation clocks both tick once per frame, so both divide by the loop's nominal frame dt. Programs therefore stay independent of any one world's timing, and the same duration is the same wall-clock wait on all three. Use waitSteps when the exact tick count matters more than the wall-clock duration.

function tecs.sequence.wait(seconds: number): Node

Arguments

Name Type Description
seconds number Supplies a non-negative duration. This function rejects a negative value. Zero still costs a tick: the cursor resumes on the program's next tick rather than carrying on within this one, so no duration makes wait free.

Returns

Type Description
Node A node for define, and not to be put in a second program.

tecs.sequence.waitingOn Static

Returns how many playbacks currently wait on a signal name.

function tecs.sequence.waitingOn(world: World, name: string): integer

Arguments

Name Type Description
world World The world owns the waiting playbacks.
name string The caller supplies the signal name to count.

Returns

Type Description
integer 0 for a name nothing waits on, including one never signaled. Counts current waiters. A signal raised during this step remains in the count until the next step delivers it.

tecs.sequence.waitQuery Static

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 runtime evaluates the condition at the start of the next fixed step, never at the instruction itself, so it never reads a world that a spawn or the world has not committed a current-step despawn yet. A query wait therefore costs at least one step.

function tecs.sequence.waitQuery(
    name: string, condition: QueryCondition
): Node

Arguments

Name Type Description
name string Resolved per world when the instruction runs, not at define, so a program may name a query registered later. A name still unregistered when the step runs faults the playback with unregisteredQuery.
condition QueryCondition Rejected here, not at compile time, when it is neither "any" nor "empty".

Returns

Type Description
Node A node for define, and not to be put in a second program.

tecs.sequence.waitSignal Static

Blocks until signal raises the named signal.

The next fixed step delivers signals after signal runs, so a signal raised by one sequence never runs another within the same step. That bounds a chain of signals to one link per step and keeps delivery order independent of which cursor happened to run first. Delivery runs on the fixed clock whatever clock the program is on, so a frame or presentation program wakes at its own clock's next tick after the fixed step that delivered it.

function tecs.sequence.waitSignal(name: string): Node

Arguments

Name Type Description
name string Matched by value against signal's, and registered nowhere: any string names a channel. A name nothing raises parks the playback until something cancels it, because a signal raised before the wait is not remembered.

Returns

Type Description
Node A node for define, and not to be put in a second program.

tecs.sequence.waitSteps Static

Waits for a whole number of ticks of the program's clock.

waitSteps(0) yields: the cursor resumes on its program's next tick rather than continuing within the current one.

function tecs.sequence.waitSteps(steps: integer): Node

Arguments

Name Type Description
steps integer Ticks of the program's own clock, so a program defined against "frame" or "presentation" counts those and not fixed steps. This function requires a non-negative whole number.

Returns

Type Description
Node A node for define, and not to be put in a second program.

tecs.sequence.waitTween Static

Waits for the tween started by the most recent playTween.

Resumes when that specific playback completes, gets canceled, loses its channel, or loses its entity, so it never waits forever. status reports the outcome as tweenOutcome.

A waitTween that no playTween in this playback preceded falls straight through without costing a tick.

function tecs.sequence.waitTween(): Node

Arguments

None.

Returns

Type Description
Node A node for define, and not to be put in a second program.

Values

tecs.sequence.easing variable

Read-only. Exposes built-in easing curves such as sequence.easing.quadOut.

tecs.sequence.easing: tweeneval.Easings

tecs.sequence.Event variable

Read-only. Exposes the event emitted by an emit step at address zero.

tecs.sequence.Event: seqtypes.Event

tecs.sequence.source variable

Read-only. Exposes sources from which tweenTrack reads changing values: sequence.source.own(Transform2D, "x").

tecs.sequence.source: tweeneval.Sources

tecs.sequence.target variable

Read-only. Exposes built-in targets and constructors for new ones: sequence.target.translateX, sequence.target.field(C, "hp").

tecs.sequence.target: tweeneval.Targets

tecs.sequence.TrackingTarget variable

Read-only. Exposes the component that selects a dynamic tracking-source entity.

tecs.sequence.TrackingTarget: tweeneval.TrackingTarget