On this page
- tecs.sequence
- Programs and actions
- Clocks and waits
- Ownership
- Timelines
Types
- Action
- ActionContext
- Argument
- Awaitable
- ClockId
- DefineOptions
- EasingFunction
- EasingName
- EntityRef
- Evaluator
- FaultReason
- Handle
- Node
- PlaybackMode
- PlaybackState
- PlayOptions
- Program
- QueryCondition
- RunOptions
- Status
- Step
- Target
- TargetName
- TimelineNode
- TimelineOptions
- TimelineSpec
- TrackSource
- TweenOutcome
Functions
- activeCount
- await
- bind
- call
- cancel
- cancelOwnedBy
- currentStep
- dataOps
- define
- defineData
- disassemble
- emit
- eval
- fork
- hasAction
- hasQuery
- join
- loop
- parallel
- pause
- play
- playbacks
- playTween
- plugin
- program
- programNames
- registerAction
- registerAwaitable
- registerEvaluator
- registerQuery
- resume
- setInstructionBudget
- signal
- signalOnEvent
- status
- timeline
- tweenAdjust
- tweenEmit
- tweenParallel
- tweenRun
- tweenTo
- tweenTrack
- tweenWait
- upcoming
- wait
- waitingOn
- waitQuery
- waitSignal
- waitSteps
- waitTween
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
endtecs.sequence.ActionContext.world field
Read-only. The world this playback belongs to.
tecs.sequence.ActionContext.world: Worldtecs.sequence.ActionContext.handle field
Read-only. The playback, for status or cancel from inside an action.
tecs.sequence.ActionContext.handle: Handletecs.sequence.ActionContext.owner field
Read-only. The owner supplied at play, or 0 for a world-scoped sequence.
tecs.sequence.ActionContext.owner: integertecs.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): integerArguments
| 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 = anytecs.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)
endtecs.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.
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.
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"
endtecs.sequence.DefineOptions record
Configures define.
tecs.sequence.DefineOptions.clock field
Caller-writable. Selects the clock counted by program waits and defaults to "fixed".
tecs.sequence.DefineOptions.clock: ClockIdtecs.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): numbertecs.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"
endtecs.sequence.EntityRef record
References an entity supplied at play time and resolves it when the instruction that uses it runs.
tecs.sequence.EntityRef.bindName field
Read-only. Name of the binding this reference resolves.
tecs.sequence.EntityRef.isBinding field
Read-only. Marker distinguishing a reference from an ordinary table argument.
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
endtecs.sequence.Evaluator.load Static
function tecs.sequence.Evaluator.load(ProgramImpl, any, any): anyArguments
| 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.
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): anyArguments
| 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): anyArguments
| 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.
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"
endtecs.sequence.Handle type
Identifies one playback through a generation-checked reference that remains meaningful across a snapshot load.
type tecs.sequence.Handle = seqtypes.Handletecs.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
endtecs.sequence.PlaybackMode enum
Selects how a timeline repeats.
enum tecs.sequence.PlaybackMode
"loop"
"once"
"pingPong"
endtecs.sequence.PlaybackState enum
Describes the lifecycle state of one playback.
enum tecs.sequence.PlaybackState
"canceled"
"completed"
"faulted"
"paused"
"running"
endtecs.sequence.PlayOptions record
Configures play.
record tecs.sequence.PlayOptions
owner: integer
bindings: {string: integer}
params: {string: any}
budget: integer
channel: string
endtecs.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: integertecs.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: integertecs.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: stringtecs.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.
tecs.sequence.Program.name field
Read-only. The name passed to define.
tecs.sequence.Program.version field
Read-only. Monotonic version, starting at 1. Incremented per redefinition.
tecs.sequence.QueryCondition enum
Describes the condition awaited by a waitQuery step.
enum tecs.sequence.QueryCondition
"any"
"empty"
endtecs.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
endtecs.sequence.RunOptions.mode field
Caller-writable. Nested timeline playback mode. Defaults to "once".
tecs.sequence.RunOptions.mode: PlaybackModetecs.sequence.RunOptions.count field
Caller-writable. Pass count for the nested timeline.
tecs.sequence.RunOptions.count: integertecs.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
endtecs.sequence.Status.state field
Read-only.
tecs.sequence.Status.state: PlaybackStatetecs.sequence.Status.program field
Read-only. Program name this playback is running.
tecs.sequence.Status.version field
Read-only. Program version this playback is running.
tecs.sequence.Status.pc field
Read-only. Instruction index, for disassembly and debugging.
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.waitingFor field
Read-only. Signal name this playback is blocked on, when it is.
tecs.sequence.Status.waitingFor: stringtecs.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: stringtecs.sequence.Status.waitingCondition field
Read-only. Query condition this playback is waiting for.
tecs.sequence.Status.waitingCondition: QueryConditiontecs.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: stringtecs.sequence.Status.waitingAwaitableEntity field
Read-only. Entity this playback's awaitable is waiting on.
tecs.sequence.Status.waitingAwaitableEntity: integertecs.sequence.Status.waitingTween field
Read-only. Tween playback token this playback is blocked on, when it is.
tecs.sequence.Status.waitingTween: integertecs.sequence.Status.tweenOutcome field
Read-only. How the last tween it waited on ended.
tecs.sequence.Status.tweenOutcome: TweenOutcometecs.sequence.Status.branches field
Read-only. Live branches this playback forked and has not joined.
tecs.sequence.Status.joining field
Read-only. Whether it is parked at a join waiting for those branches.
tecs.sequence.Status.fault field
Read-only. Set when state is "faulted".
tecs.sequence.Status.fault: FaultReasontecs.sequence.Status.faultMessage field
Read-only. Error message set when state is "faulted".
tecs.sequence.Status.faultMessage: stringtecs.sequence.Step record
Describes one step a playback will reach without branching.
tecs.sequence.Step.ticks field
Read-only. Ticks of the program's clock from the reference point until it runs.
tecs.sequence.Step.kind field
Read-only. "call" or "emit".
tecs.sequence.Step.name field
Read-only. Action name for a call, event name for an emit.
tecs.sequence.Step.args field
Read-only. Constants the step carries, unresolved.
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
endtecs.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"
endtecs.sequence.TimelineNode type
Represents one authored timeline operation.
type tecs.sequence.TimelineNode = {any}tecs.sequence.TimelineOptions record
Configures timeline.
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.TimelineOptions.clock: ClockIdtecs.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
endtecs.sequence.TweenOutcome enum
Reports how the tween awaited by waitTween ended.
enum tecs.sequence.TweenOutcome
"canceled"
"completed"
"replaced"
"targetLost"
endFunctions
tecs.sequence.activeCount Static
Returns the number of live playbacks for tests and diagnostics.
function tecs.sequence.activeCount(world: World): integerArguments
| 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")),
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): EntityRefArguments
| 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.
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.
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
): integerArguments
| 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.
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
): ProgramArguments
| 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, stringArguments
| 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
): stringArguments
| 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.
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): NodeArguments
| 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.
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): booleanArguments
| 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): booleanArguments
| 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(): NodeArguments
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.
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.
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.
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
): HandleArguments
| 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.
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}
): NodeArguments
| 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
): ProgramArguments
| 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.
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.
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): integerArguments
| 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.
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.
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
): ProgramArguments
| 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
): TimelineNodeArguments
| 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): TimelineNodeArguments
| 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): TimelineNodeArguments
| 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
): TimelineNodeArguments
| 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
): TimelineNodeArguments
| 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
): TimelineNodeArguments
| 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): TimelineNodeArguments
| 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.
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): NodeArguments
| 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): integerArguments
| 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
): NodeArguments
| 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): NodeArguments
| 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): NodeArguments
| 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(): NodeArguments
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.Easingstecs.sequence.Event variable
Read-only. Exposes the event emitted by an emit step at address zero.
tecs.sequence.source variable
Read-only. Exposes sources from which tweenTrack reads changing values: sequence.source.own(Transform2D, "x").
tecs.sequence.source: tweeneval.Sourcestecs.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.Targetstecs.sequence.TrackingTarget variable
Read-only. Exposes the component that selects a dynamic tracking-source entity.
tecs.sequence.TrackingTarget: tweeneval.TrackingTarget