tecs.ecs

The entity component system shared by game code and engine systems.

The ECS exposes staged entity lifetime, tag and scalar components, dense archetype storage, and reusable queries. A spawn reserves its id immediately, and commit publishes structural changes.

Declaring components#

Derive tecs.ecs.Component on a record or struct, use its declaration in queries, and supply ordinary new values to mutations. Structs select native columns; records select managed columns. Names default to the module-qualified declaration name. @component(name = "game.Velocity") pins a persisted name across declaration or namespace changes; @component(transient = true) omits snapshot values.

Native components store Nupp structs inline in contiguous native columns. Nupp owns the struct layout and methods. Tecs owns column capacity, publication and dirty tracking. There is no generated parallel C schema and no row wrapper in the query loop. A native column grows geometrically with a single memory copy; bulk spawns reserve the whole destination range before calling their writer.

@derive(tecs.ecs.Component, nupp.derive.Debug)
local struct Velocity
    x: number = 0
    y: number = 0
end
local world = tecs.ecs.newWorld()
world:batchSpawn(1000, {Velocity})
world:commit()
for candidate, count in world:newQuery({include = {Velocity}}):iter() do
    local column = assert(candidate:getMut(Velocity))
    @unsafe do
        for row = 1, assert(count) do column[row].x += 1 end
    end
end

Built-in transforms, tint, shape material, camera, lights, animation, sound, physics values and numeric UI components use this storage and derive nupp.derive.Debug, whose methods work on constructed values and borrowed rows without changing column layout. Serialization needs no derive: nupp.serde.binding(Velocity) selects the declaration's fields for nupp.serde.json.encode and decode. That generic encoding describes physical component fields, whereas world snapshots use the component's registered codecs. Asset-bearing built-ins keep their custom name-based codecs and never persist process-local IDs as assets.

get and getMut return T[?] for a native component, and the existing managed array for a table or scalar component. Native rows use the same one-based indices as the query's entity list; row zero is padding. Use the query count, not #column, pairs, ipairs, or table library operations on a native column. Direct C-array indexing requires a Nupp @unsafe scope. world:get still returns one typed struct value, and world:getMut marks the owning column dirty first.

Native column assignments copy bytes, including inline fixed arrays. Entities never share these inline rows, even when they receive the same constructed input or requirement. Struct values returned by reads are live row references, not owned copies. Column views and row references expire at the next structural publication, compaction, clear, or snapshot restore. Reacquire them afterwards. Never retain a native row reference across such a boundary or use commit inside its loop.

Automatic codecs support numeric and boolean fields and fixed arrays of those types. Nested structs and pointers are also supported with custom codecs or transient = true; their owners must keep pointed-to storage alive. Unions, bitfields and variable arrays are rejected. Never persist process-local pointer addresses. Table snapshots have automatic field codecs; arrays are saved one-based and signed/unsigned 64-bit integers are saved as exact decimal strings. Optional save and either load or world-aware deserialize hooks must be supplied together. They replace automatic codecs and disable native raw encoding in both directions so custom behavior is never silently bypassed. Transient and required components follow the ordinary ECS rules. Binary snapshots copy eligible native columns directly and migrate older scalar layouts using their saved field fingerprints.

Derive tecs.ecs.Relationship on a target-bearing record or struct. Optional @relationship settings configure its name, exclusivity, sparse placement, reverse indexing, cascades and transient snapshot policy. Use tecs.ecs.targeting(EdgeType, target) for a dense target-specific selector. Native relationships use the same field policy and support exclusive or multiple targets, reverse lookup, cascades and sparse or dense edge placement. Its struct must contain a target: number field. Dense targeting() selectors return native columns. A wildcard relationship column is a managed array of references to its first native edge, not another copy of that edge. Sparse edge lists likewise retain native values. Changes through wildcard, target-specific and relationship-iteration access therefore reach the same payload. Sparse relationships retain constructed edge objects. Reusing one edge instance for several sources shares that payload; construct separate instances for independent values and mark every affected source dirty after mutating a deliberately shared payload.

Component requirements#

Every component factory accepts requires, including scalar components and both relationship factories. A requirement is a component definition or a constructed tecs.ecs.ComponentInput. Definitions use their default value when a missing column is initialized; record default factories run separately for each entity. Constructed instances supply shared values instead, including across bulk operations. Their outer records are not copied. Treat these shared records as immutable or explicitly mark every affected entity dirty after an external write.

local health = tecs.ecs.newScalarComponent({
    name = "game.Health", kind = "number", default = 100,
})
local enemy = tecs.ecs.newTagComponent({
    name = "game.Enemy", requires = {health(50), tecs.ecs.Transform2D},
})
local world = tecs.ecs.newWorld()
local id = world:spawn(enemy)
world:commit()
assert(world:get(id, health) == 50)

Requirements expand transitively into the same staged archetype transition. spawn, spawnAt, bundles, bulk spawns, set and batchSet all apply them. They are initialized before membership callbacks and bulk writers observe the new columns. Explicit spawn inputs and already-present components keep their values, including values staged earlier in the same transaction. A definition explicitly passed to spawn uses its own default instead of a required instance.

Tecs copies requirement lists at registration and caches their transitive closures. Traversal is breadth-first in declaration order and deduplicates by component identity; the first encountered requirement for a component wins. Cycles terminate without repeating the root component. Multiple explicit spawn components expand in argument order after all explicit inputs are collected.

Requirements are addition rules, not permanent invariants. Replacing a value, adding an unrelated component, or adding another target to an existing relationship does not restore deliberately removed requirements. Removing a component leaves its requirements in place. Removing and re-adding it expands its closure again. Snapshot restore follows spawnAt: it reapplies requirements missing from saved data, including defaults for omitted transient components.

A required relationship must be a constructed, target-bearing instance, not a bare relationship definition. It participates in dense target matching, reverse lookup and cascade deletion just like an explicitly added edge. Target ids in a process-wide requirement must be meaningful in every world using that component. All requirements of an edge apply to its source, not its target. An existing relationship takes precedence over a required edge to that relationship.

Query membership#

Queries exclude Disabled unless their include list explicitly requests it. Setting type = "logic" also excludes Paused, with the same explicit-include override. include requires every component, includeAny requires at least one, and exclude rejects any listed component. The world copies these lists.

local moving = world:newQuery({
    type = "logic",
    include = {tecs.ecs.Transform2D},
    exclude = {tecs.ecs.ChildOf},
})
for candidate, count, entities in moving:iter() do
    local transforms = assert(candidate:getMut(tecs.ecs.Transform2D))
    @unsafe do
        for row = 1, count do
            transforms[row].x = transforms[row].x + 1
        end
    end
end

groupBy assigns an integer group once per matching archetype. iter() visits groups in ascending order, groups() yields nonempty groups, and group(id) visits one group's archetypes. count() and getGroupCount(id) read current entity counts. Iterators are independent and can be nested.

onEntitiesAdded receives the initial matching rows and subsequent entries. onEntitiesRemoved receives departing rows before removal. Both callbacks take (archetype, firstRow, lastRow, count) with one-based inclusive bounds. Moves between two matching archetypes do not fire either callback. A callback may stage mutations; the active commit drains them after the current publication. Changing fields on an existing component is not a membership change.

temp = true freezes the matched archetype set at construction, while reading its live rows. Temporary queries do not subscribe to new archetypes and cannot declare membership callbacks. Structural changes remain staged until a barrier, so leaving an iterator early requires no cleanup. Do not call commit inside an active query iteration.

Relationship storage#

newRelationship constructs target-only edges. Relationships are non-exclusive and dense by default. exclusive = true replaces a source's previous edge. Otherwise setting an existing target replaces that edge and preserves the others. sparse = true stores edges by entity without creating a distinct archetype for each target set. Dense relationships expose relationship:targeting(entity) for include/exclude constraints and direct access to one target's column.

local follows = tecs.ecs.newRelationship({
    name = "game.Follows", reverseIndex = true,
})
local leader = world:spawn()
local other = world:spawn()
local follower = world:spawn(follows(leader), follows(other))
world:commit()
local followers = world:newQuery({include = {follows:targeting(leader)}})
world:remove(follower, follows(other))
world:commit()

Remove a relationship definition to remove every edge; pass an instance to remove just its target, for either storage mode. get and getFirstRelationship return the first edge in ascending target order. forEachRelationship visits every edge in that order. Its archetype counterpart takes a one-based row. Edge values are live; use getMut before changing payload fields. Never write an edge's target field directly: set maintains the signature and reverse index.

newRelationship(EdgeType, options) creates an explicit payload relationship. Its constructor receives the target first and returns a value with that same target field. Automatic codecs preserve the top-level declared type; custom codecs handle resource identities or nested managed types. RelationshipDefinition<T> retains T through world reads, iteration and targeted column access. Snapshots store relationship names and edges, independent of generated dense target-component identifiers.

newComponent(ValueType, options) and newRelationship(EdgeType, options) create distinct named definitions from one value declaration. When the type derives the ECS contract, its initializer supplies construction and defaults. A type without that derive supplies explicit construction factories and a name. Registration uses the type witness without running a constructor or default factory. Custom codecs, world-aware decoding and requirements belong in these options. Calling a factory with a derived type's default name registers that type's definition; a different name creates an independent identity whose values must be supplied through the returned factory.

reverseIndex = true enables relationshipSources, callback-based targets, and depth-first traverse. Traversal excludes its root, reports direct children at depth zero and visits each identifier at most once. walkUp follows the first edge at each level, reports the direct parent at depth one, and raises on cycles or its default depth limit of 100. Return false from its callback to stop early. cascadeDelete = true requires an exclusive, reverse-indexed relationship. Destruction then removes the descendants in the same publication barrier. For a reverse-indexed dense relationship without cascading, deleting a target removes just that target's incoming edges. Non-cascading sparse edges retain the target identifier until explicitly removed; always check isAlive before using such a target as a live entity.

Bulk mutations and maintenance#

batchSpawn(count, inputs, callback?) reserves a shared signature once and publishes its rows at the next barrier. It returns (firstId, nil) only when every packed identity is contiguous; otherwise it returns (nil, ids). Use the explicit list in that case, including after recycling slots or clearing a world whose used prefix and fresh suffix carry different generations. batchSpawnAt validates all supplied identities before reserving them, for restoration work. Like spawnAt, it does not add the active state's automatic tag. batchSpawnAtRaw(ids, count, inputs, callback?) reads a zero-based native double array without materializing an ID list. The world retains the array until publication; its selected prefix must not change before that barrier. This restoration path also permits initializing EntityKey before index registration.

local firstId, ids = world:batchSpawn(100, {tecs.ecs.Transform2D},
    function(candidate: tecs.ecs.Archetype, first: integer, last: integer)
        local transforms = assert(candidate:getMut(tecs.ecs.Transform2D))
        @unsafe do
            for row = first, last do
                transforms[row].x = row * 10
            end
        end
    end
)
world:commit()

Initializers receive (archetype, firstRow, lastRow, count) with one-based inclusive bounds, after placement but before query-entry and spawn events. Cancelled spawns receive no rows or events. Later set and remove calls on reserved IDs apply after initialization. A batch takes explicit relationship values such as ChildOf(parent), not a bare relationship without a target. Never overwrite relationship targets through a column; stage per-entity set calls when targets vary. Ordinary batch spawn signatures cannot contain EntityKey, including through requirements; assign keys individually with set.

batchSet(query, value) and batchRemove(query, componentOrRelationshipValue) stage changes for the query's committed members at the call. batchDespawn(query) uses normal lifecycle events, observer cleanup and relationship cascading. Queries must belong to the same world; temporary queries are supported. New members that arrive later in the transaction are not retroactively selected. Query state filters apply, so include Disabled explicitly when selecting it.

batchSet(query, Component, callback) ensures a plain component exists and invokes the writer at the barrier, once per contiguous affected row range. Writers use getMut, see earlier staged writes, and precede later scalar writes. Entries into queries that require the added component see initialized values. Callback mode rejects instances and relationships; constant mode supports edges. Bulk setting EntityKey is rejected because a shared value cannot claim distinct keys. Explicit record constants get independent shallow outer copies, retaining their record type; nested references remain shared. Instance-valued requirements remain shared. Default factories run per entity.

Bulk storage paths operate on compact batch descriptors and native slot stamps. A contiguous spawn allocates no identity list or per-entity transaction records. Plain whole-archetype moves exchange common column buffers when the destination is empty and copy native ranges when it is populated; plain deletion truncates storage once. Relationships, durable keys and selections changed by earlier publication use the per-entity behavior where needed. Query batches retain native identity snapshots to preserve membership at the call. Reacquire column views after publication, including a buffer exchange.

All operations remain deferred. Callback boundaries preserve call order inside the transaction; they do not publish early from the API call. A callback can stage further work for the same commit to drain, but cannot clear or compact the world during publication. As with scalar mutations, a callback failure is not an atomic rollback of already published rows.

forEachArchetype includes empty and disabled archetypes. dirtyArchetypes() captures an independent iterator over the queue in first-dirtied order, including empty ones changed by removal. Dirty marks clear at the end of update. findArchetypes(Component) uses the component index, including empty matches. getStats(fill) updates a caller-owned statistics record without allocating one.

Entity IDs occupy contiguous native double columns. Their exact length remains available through #entities; row zero holds that length. Use indexed numeric loops, not table-library functions or ipairs, and treat the column as read-only. Persistent queries maintain active-only lists through lifecycle notifications. iter, group and groups return reusable generic-for functions, their state and an initial cursor. They allocate no per-iteration closure and support nested and interleaved traversal. Manual stepping must pass that state and prior result.

Observe ArchetypeCreated at address zero to attach addEntityObserver callbacks before an archetype's first publication. Added and removed ranges are one-based; swap-pop onEntityMove positions are zero-based. Added callbacks see initialized values, removed callbacks can still read departing rows, and moves identify the opposite archetype. Activation, deactivation and destruction are also observable.

structuralDescribed(previousCount) reports whether bounded row residue covers a consumer's structural count. structuralAdded() identifies an appended suffix; structuralTouched() returns a borrowed list and count of swap-pop overwrites. A false description requires a full refresh. trackValueCount(Component) opts a column into the aggregate valueCount() counter; structural writes do not increment that counter. archetype:set(row, instance) replaces an existing value and marks it dirty, but cannot change relationship membership.

Call compact() outside dispatch on a committed world. It prunes empty dense relationship archetypes with dead target identities, releases their persistent query/group entries, and reuses freed archetype IDs without renumbering survivors. Ordinary empty archetypes and the empty-signature sentinel remain registered. It also rebuilds row tables whose occupancy has fallen since their high-water mark. The returned counts are (pruned, rebuilt); the second counts rebuilt stores, not bytes reclaimed or an exposed native capacity. Component values, dirty flags, systems and persistent queries survive. Reacquire column/entity views after compaction, and do not compact or commit inside an active iterator. An explicitly retained temporary query can keep an old empty archetype object alive, but it will not adopt a new archetype that later reuses the same ID.

World-managed random streams#

world:randomStream(name) returns a nupp.random.Xoshiro128 owned by the world. The world seed and the non-empty stream name determine its sequence, independently of which other streams exist or how many values they draw. Repeated calls return the same generator. Use namespaced names and capture streams during setup.

local world = tecs.ecs.newWorld()
world:seedRandom(42)
local loot = world:randomStream("game.loot")
local roll = loot:integer(1, 20)
local saved = world:saveSnapshot()
local expected = loot:next()
world:loadSnapshot(saved)
assert(loot:next() == expected)

The initial world seed is the fixed value 0x5EED1234, not a clock reading. seedRandom(seed) reads a 32-bit word and restarts all existing streams in place; future streams derive their seeds from the new world seed too. Drawing, shuffling, ranges and individual state access use Nupp's generator methods directly. Independent generators outside a world use new nupp.random.Xoshiro128(seed). Generators are mutable and must not be shared across concurrent workers.

The first stream or seed call enables snapshot persistence under tecs.random. This reserved key, its {seed, streams} payload and the byte-based name-to-seed mapping are persistence contracts. Each saved stream contains four signed 32-bit state words. Saving neither advances the generators nor leaves a live view into them.

Loading a snapshot restores already-captured generators in place, creates saved streams not yet requested, and restarts existing streams absent from the save using the restored world seed. A fresh world needs no initialization call before loading saved random data. Random state restores after entity publication and before custom snapshot handlers run. Malformed random payloads raise before the world clears entities or changes generators. Unsigned 32-bit saved words are accepted and normalized too.

A snapshot without tecs.random leaves current streams and the seed unchanged. Clearing entities also leaves them alone. Runtime closures such as timer predicates are not snapshot state: giving runif.every a world stream restores its future random draws, but does not rewind the timer's elapsed time. The tecs.random key cannot be supplied through custom data or a snapshot handler. Installing audio uses the tecs.audio stream for pitch variance automatically; standalone mixers retain their own independent Nupp generators.

System scheduling#

registerPhase({name = "game.Custom"}) registers a custom leaf; children makes an ordered tree of registered names. position selects its inspection-registry position, not automatic execution in the default frame. Run the tree explicitly with runPhase, or provide WorldConfig.pipelineFactory to replace scheduling. The custom Pipeline receives the world's task scope, owns system ordering and phase barriers, and receives all registration, phase-control and inspection calls. Its fixed remainder and phase-enabled flags participate in snapshots.

addSystem accepts before and after lists of system names. Constraints apply only within one leaf phase; missing names and names in other phases contribute no edge. Self references are ignored and duplicate edges count once. Among systems whose dependencies are satisfied, the earliest registered runs first. Disabled systems retain their position and ordering edges.

The world copies constraint lists. It rebuilds the schedule after registration changes, validating every phase before the next dispatch publishes staged work or runs any system. A cycle raises with its phase and blocked system names. listSystems() reports dependency order and also raises for a cycle. Remove a conflicting system to repair the schedule; enabling or disabling cannot repair it.

An update, startup, shutdown or explicit runPhase captures one schedule at its entry. A system added during that dispatch starts on the next external dispatch, even if its phase has not run yet. Removal and enable/disable changes affect remaining dispatches immediately. Listing during a dispatch describes the next schedule without changing the active one. Ordering does not introduce structural barriers: request commitBefore or commitAfter when a same-phase dependency also requires publication of staged entities.

Call world:enqueueCommit() when that extra barrier is conditional on work performed by a system. Requests from its body or runIf predicate coalesce into one publication after the body returns, or after a false predicate skips it, before the next system runs. Suspension does not end the system: its query view stays unchanged until it returns. Requests alone never publish midway through iteration. A publication callback may request another commit without recursion; the active drain includes its staged work.

Outside a running system, enqueueCommit() publishes synchronously, including child work settling after dispatch. Leave any query iterator before calling it there. Explicit commit() remains synchronous even inside a system. If a body or predicate raises, the dispatcher clears its request without introducing a barrier during unwinding; pending mutations remain staged for a later commit. Publication failures retain already published rows and discard unpublished work, as with any other commit failure.

world:addSystem({
    name = "game.SpawnWave",
    phase = tecs.ecs.phases.Update,
    before = {"game.MoveEnemies"},
    commitAfter = true,
    runIf = tecs.ecs.runif.both(
        tecs.ecs.runif.inState("game"),
        tecs.ecs.runif.every(2)
    ),
    run = spawnWave,
})

tecs.ecs.runif provides after, every, cooldown, inState, both, either and negate. Timers consume the phase delta only when evaluated. after removes its system before its one allowed run; every retains excess elapsed time but fires at most once per dispatch; cooldown starts ready and discards excess time when firing. Each timer factory creates state for one system. Reusing a predicate shares that state. Timer closures are not snapshots.

Combinators short-circuit, including their operands' side effects. The example pauses its timer outside game; swapping the operands keeps the timer advancing and spends ticks outside that state. A disabled system or phase never evaluates its predicates. Use every(interval, jitter, generator) for jitter, supplying a nupp.random.Xoshiro128 directly. The first interval is unjittered and later intervals clamp to one percent of the base interval. Pass a named world stream to snapshot its random state; there is no implicit stream or automatic timer rewind when an entity snapshot is restored.

Submodules

ModuleDescription
tecs.ecs.phasesThe ordered frame phase constants.
tecs.ecs.runifProvides timer, state and logical predicates for system dispatch.

Module contents

Types

TypeKindDescription
ArchetyperecordA dense archetype returned by query iteration.
ArchetypeCreatedrecordReports newly registered archetypes at the world's zero address.
ArchetypeEntityObserverinterfaceReceives row and lifetime notifications from one archetype.
BatchCallbacktypeInitializes or updates a contiguous one-based archetype row range at a barrier.
BundlerecordA reusable world-bound spawn shape.
BundleDefinitiontypeRequired and defaulted components for a bundle.
ComponentinterfaceA process-wide component definition.
componentrecordConfigures a derived component's persisted identity and snapshot policy.
ComponentDefinitioninterfaceA named definition with its column type selected from the value declaration.
ComponentInputtypeA component definition or constructed value accepted by a mutation.
ComponentOptionstypeConfigures an explicit component identity from a declaration.
ComponentValueinterfaceBounds generic helpers to records or structs deriving the component contract.
DoubleArrayinterfaceExposes the native, one-based packed entity ID column and its exact length.
EdgeOptionstypeConfigures a named payload relationship from a declaration.
EntityLifecycletypeThe payload shared by entity spawn and despawn lifecycle events.
FinishSnapshotLoadrecordReports completion of snapshot metadata restoration.
FixedOverloadtypeThe policy applied when a frame exceeds its fixed-step limit.
NewRelationshiptypeAccepts target-only options or a declaration with payload relationship options.
OnDespawnrecordFires at the entity address and address zero immediately before removal.
OnSnapshotSaverecordAllows snapshot participants to attach metadata and exclude regenerated entities.
OnSpawnrecordFires at address zero after an entity becomes committed and alive.
PhasetypeA frame phase.
PhaseDefinitiontypeDeclares a custom phase or ordered phase tree.
PhaseGrouptypeAn ordered predefined group of frame or lifecycle phases.
PhaseSelectiontypeA leaf phase or predefined group accepted by schedule controls.
PipelineinterfaceImplements custom scheduling while the world owns entities and task scopes.
PreviousTransform2DstructStores the position and rotation before the current fixed step.
QueryrecordA reusable archetype query.
QueryDescriptortypeMembership constraints, grouping and notifications for a reusable query.
RelationshiprecordA target-only entity relationship with selectable cardinality and storage.
relationshiprecordConfigures a derived relationship's identity, cardinality and storage policy.
RelationshipDefinitioninterfaceA payload relationship whose target selector retains the physical column type.
RelationshipOptionstypeConstruction and storage options for target-only relationships.
RelationshipPayloadinterfaceBounds generic helpers to target-bearing declarations deriving the relationship contract.
RelationshipValuerecordA target-only relationship edge value.
RelativeTransform2DstructOffsets an entity from the transform of the parent it names with ChildOf.
RunIftypeA predicate receiving the phase delta, world and registered system name.
ScalarComponentrecordA primitive-valued component definition.
ScalarComponentOptionstypeOptions accepted by the kind-correlated scalar component factory.
SnapshotrecordA detached, format-neutral world snapshot.
SnapshotHandlertypeA named custom snapshot participant.
SnapshotOptionstypeOptions for adding custom snapshot data.
SnapshotPreluderecordMetadata returned by a snapshot load.
StartSnapshotLoadrecordAllows snapshot participants to subscribe to metadata during a load.
StateBlurrecordFires after the current state loses focus.
StateBlurChangetypeThe payload emitted when a state loses focus.
StateChangetypeThe payload emitted when a state enters or exits.
StateEnterrecordFires after a state becomes active.
StateExitrecordFires before a state leaves the stack.
StateFocusrecordFires after an uncovered state regains focus.
StateFocusChangetypeThe payload emitted when a state regains focus.
StatePolicytypePolicy hooks for one world state.
SystemtypeA system body receiving elapsed time, its world, and the update task scope.
SystemConfigtypeRegistration options for a frame system.
SystemInfotypeOne registered system as reported in execution order.
TagComponentOptionstypeOptions for a marker component with no per-entity value.
Transform2DstructPlaces an entity in the two-dimensional world.
Transform3DstructPlaces an entity in a right-handed 3D world using a quaternion and per-axis scale.
TTLstructCounts down an entity's remaining lifetime.
WorldrecordA Tecs world.
WorldConfigtypeThe options accepted by newWorld.
WorldStatsrecordFixed-step overload counters accumulated by a world.

Functions

FunctionKindDescription
Componentcomptime functionMarks a record or struct as an ECS component and selects its physical storage.
declaredComponentsfunctionReturns a fresh snapshot of every declared component.
definitionfunctionReturns the registered definition for a derived component declaration.
findComponentByIdfunctionReturns a registered component by numeric id.
findComponentByNamefunctionReturns a registered component by name.
newComponentfunctionRegisters a declaration with managed or native columns selected from its layout.
newTagComponentfunctionCreates and registers a marker component with no per-entity value.
newWorldfunctionCreates an independent empty world carrying the builtin systems.
Relationshipcomptime functionMarks a target-bearing record or struct as an ECS relationship.
targetingfunctionSelects the typed dense column for one target of a derived relationship.

Values

ValueKindDescription
ChildOfvariableRelates one child entity to its parent.
DEFAULT_FIXED_MAX_STEPSvariableThe per-frame fixed-step limit used when newWorld receives no override.
DEFAULT_MAX_ENTITIESvariableThe entity capacity used when newWorld receives no override.
DEFAULT_TIMESTEPvariableThe fixed update interval used when newWorld receives no override.
DisabledvariableMarks entities disabled by a state policy.
EntityKeyvariableStores a durable unique name for one entity.
MAX_ENTITIESvariableThe greatest entity capacity supported by the packed id format.
NamevariableNames an entity for a human reader.
newRelationshipvariableRegisters a target-only relationship or a record or struct payload declaration.
newScalarComponentvariableCreates and registers a scalar component whose column stores raw values.
PausedvariableMarks entities paused by a state policy.
PreviousTransform2DvariableOpts an entity into fixed-step presentation interpolation.
RelativeTransform2DvariableConstructs an offset from a parent's transform.
Transform2DvariableConstructs the shared two-dimensional transform component.
Transform3DvariableConstructs a 3D transform, defaulting to the identity at the origin.
TTLvariableConstructs a lifetime that despawns its entity when it runs out.

Types#

Archetyperecord#

record Archetype ...

A dense archetype returned by query iteration.

Members

NameKindDescription
idfield
signaturefield
componentIdsfield
componentsfield
entitiesfield
columnsfieldEngine-owned.
dirtyfield
structureVersionfield
valueVersionsfield
sparseEdgesfield
storageHighWaterfield
nativeCapacityfield
nativeColumnsfield
nativeAliasesfield
observersfield
activatedfield
dirtyQueuefield
dirtyEpochfield
residueFromfield
addedFromfield
touchedfield
touchedAllfield
countedValuesfield
valueVersionfield
plainfield
addEdgesfield
removeEdgesfield
movePlansfield
addEntityObservermethodRegisters publication callbacks without replaying existing rows.
structuralDescribedmethodReports whether row residue completely describes changes since a structural count.
structuralAddedmethodReturns the first appended one-based row in this dirty window, or zero.
structuralTouchedmethodReturns the reused swap-pop row residue for this dirty window.
valueCountmethodCounts explicitly tracked value writes, excluding structural changes.
trackValueCountmethodEnables aggregate value counting for one present component.
setmethodWrites one existing component without changing row membership.
getfield
getMutfield
isComponentDirtymethod
anyComponentDirtymethod
markComponentDirtymethod
markAllComponentsDirtymethod
clearDirtyComponentsmethod
dirtyComponentsmethod
structuralCountmethodReturns the structural write count, which survives dirty-bit clearing.
writeCountmethodReturns one column's write count, which survives dirty-bit clearing.
forEachRelationshipfieldIterates an entity row's edges in target order.
getFirstRelationshipfieldReturns the first edge in target order.

idfield#

id: integer

signaturefield#

signature: string

componentIdsfield#

componentIds: {[integer]: boolean}

componentsfield#

components: {components.Component}

entitiesfield#

entities: entitycolumn.DoubleArray

columnsfield#

columns: {[integer]: any}

Engine-owned. Holds heterogeneous managed arrays or native C arrays. This storage seam is public for world internals; game code uses get or getMut.

dirtyfield#

dirty: {[integer]: boolean}
@private

structureVersionfield#

structureVersion: integer
@private

valueVersionsfield#

valueVersions: {[integer]: integer}
@private

sparseEdgesfield#

sparseEdges: {[integer]: {[integer]: {any}}}
@private

storageHighWaterfield#

storageHighWater: integer
@private

nativeCapacityfield#

nativeCapacity: integer
@private

nativeColumnsfield#

nativeColumns: {[integer]: ffistorage.Storage}?
@private

nativeAliasesfield#

nativeAliases: {[integer]: integer}?
@private

observersfield#

observers: {EntityObserver}
@private

activatedfield#

activated: boolean
@private

dirtyQueuefield#

dirtyQueue: DirtyQueue?
@private

dirtyEpochfield#

dirtyEpoch: integer
@private

residueFromfield#

residueFrom: integer
@private

addedFromfield#

addedFrom: integer
@private

touchedfield#

touched: {integer}
@private

touchedAllfield#

touchedAll: boolean
@private

countedValuesfield#

countedValues: {[integer]: boolean}
@private

valueVersionfield#

valueVersion: integer
@private

plainfield#

plain: boolean
@private

addEdgesfield#

addEdges: {[integer]: Archetype}
@private

removeEdgesfield#

removeEdges: {[integer]: Archetype}
@private

movePlansfield#

movePlans: {[Archetype]: MovePlan}
@private

addEntityObservermethod#

addEntityObserver: function(self: Archetype, observer: EntityObserver): nil

Registers publication callbacks without replaying existing rows.

Arguments
NameTypeDescription
selfArchetype

The archetype to observe.

observerEntityObserver

The callbacks retained until destruction.

Returns
TypeDescription
nil

structuralDescribedmethod#

structuralDescribed: function(self: Archetype, count: integer): boolean

Reports whether row residue completely describes changes since a structural count.

Arguments
NameTypeDescription
selfArchetype

The archetype to inspect.

countinteger

The consumer's previous structural count.

Returns
TypeDescription
boolean

Returns false when a full refresh is necessary.

structuralAddedmethod#

structuralAdded: function(self: Archetype): integer

Returns the first appended one-based row in this dirty window, or zero.

Arguments
NameTypeDescription
selfArchetype

The archetype to inspect.

Returns
TypeDescription
integer

Returns the suffix start, which may exceed the current row count.

structuralTouchedmethod#

structuralTouched: function(self: Archetype): ({integer}, integer)

Returns the reused swap-pop row residue for this dirty window.

Arguments
NameTypeDescription
selfArchetype

The archetype to inspect.

Returns
TypeDescription
{integer}

Returns the borrowed row list and its live prefix length.

integer

valueCountmethod#

valueCount: function(self: Archetype): integer

Counts explicitly tracked value writes, excluding structural changes.

Arguments
NameTypeDescription
selfArchetype

The archetype to inspect.

Returns
TypeDescription
integer

Returns the monotonically increasing counter.

trackValueCountmethod#

trackValueCount: function(self: Archetype, component: components.Selector): nil

Enables aggregate value counting for one present component.

Arguments
NameTypeDescription
selfArchetype

The archetype to track.

componentcomponents.Selector

The column whose future writes contribute to valueCount.

Returns
TypeDescription
nil

setmethod#

set: function(self: Archetype, row: integer, input: components.Input): nil

Writes one existing component without changing row membership.

Arguments
NameTypeDescription
selfArchetype

The archetype to update.

rowinteger

The one-based live row.

inputcomponents.Input

The constructed component value.

Returns
TypeDescription
nil
Raises
TypeCondition
string

when the row or component is absent, or the input changes relationship membership or a durable key.

getfield#

get: (function<C is components.Component>(self: Archetype, component: C): C.Column?)
& (function<T is derived.Value>(self: Archetype, component: Type<T>): derived.Column(T, derived.Edge)?)

getMutfield#

getMut: (function<C is components.Component>(self: Archetype, component: C): C.Column?)
& (function<T is derived.Value>(self: Archetype, component: Type<T>): derived.Column(T, derived.Edge)?)

isComponentDirtymethod#

isComponentDirty: function(self: Archetype, component: components.Selector): boolean
Arguments
NameTypeDescription
selfArchetype
componentcomponents.Selector
Returns
TypeDescription
boolean

anyComponentDirtymethod#

anyComponentDirty: function(self: Archetype): boolean
Arguments
NameTypeDescription
selfArchetype
Returns
TypeDescription
boolean

markComponentDirtymethod#

markComponentDirty: function(self: Archetype, component: components.Selector): nil
Arguments
NameTypeDescription
selfArchetype
componentcomponents.Selector
Returns
TypeDescription
nil

markAllComponentsDirtymethod#

markAllComponentsDirty: function(self: Archetype): nil
Arguments
NameTypeDescription
selfArchetype
Returns
TypeDescription
nil

clearDirtyComponentsmethod#

clearDirtyComponents: function(self: Archetype): nil
Arguments
NameTypeDescription
selfArchetype
Returns
TypeDescription
nil

dirtyComponentsmethod#

dirtyComponents: function(self: Archetype): function(): components.Component?
Arguments
NameTypeDescription
selfArchetype
Returns
TypeDescription
function(): components.Component?

structuralCountmethod#

structuralCount: function(self: Archetype): integer

Returns the structural write count, which survives dirty-bit clearing.

Arguments
NameTypeDescription
selfArchetype
Returns
TypeDescription
integer

writeCountmethod#

writeCount: function(self: Archetype, component: components.Selector): integer

Returns one column's write count, which survives dirty-bit clearing.

Arguments
NameTypeDescription
selfArchetype
componentcomponents.Selector
Returns
TypeDescription
integer

forEachRelationshipfield#

forEachRelationship: (
    function<C is components.Component>(
        self: Archetype,
        relationship: C,
        row: integer,
        callback: function(value: C.Value)
    ): nil
)
    & (
        function<T is derived.Edge>(
            self: Archetype,
            relationship: Type<T>,
            row: integer,
            callback: function(value: T)
        ): nil
    )

Iterates an entity row's edges in target order.

getFirstRelationshipfield#

getFirstRelationship: (
    function<C is components.Component>(self: Archetype, relationship: C, row: integer): C.Value?
)
    & (
        function<T is derived.Edge>(self: Archetype, relationship: Type<T>, row: integer): T?
    )

Returns the first edge in target order.

ArchetypeCreatedrecord#

record ArchetypeCreated ...
@derive(events.Event)@event(name="ArchetypeCreated")

Reports newly registered archetypes at the world's zero address.

Members

NameKindDescription
archetypefieldRead-only.

archetypefield#

archetype: archetype.Archetype

Read-only. Identifies the new archetype, available for lifecycle observation.

ArchetypeEntityObserverinterface#

interface ArchetypeEntityObserver ...

Receives row and lifetime notifications from one archetype.

Members

NameKindDescription
onEntitiesAddedfieldCaller-writable.
onEntitiesRemovedfieldCaller-writable.
onEntityMovefieldCaller-writable.
onActivatedfieldCaller-writable.
onDeactivatedfieldCaller-writable.
onArchetypeDestroyedfieldCaller-writable.

onEntitiesAddedfield#

onEntitiesAdded: (
    function(
        self: EntityObserver,
        value: Archetype,
        first: integer,
        last: integer,
        count: integer,
        source: Archetype?
    )
)?

Caller-writable. Receives initialized one-based rows and their previous archetype.

onEntitiesRemovedfield#

onEntitiesRemoved: (
    function(
        self: EntityObserver,
        value: Archetype,
        first: integer,
        last: integer,
        count: integer,
        target: Archetype?
    )
)?

Caller-writable. Receives still-readable one-based rows and their destination.

onEntityMovefield#

onEntityMove: (function(self: EntityObserver, value: Archetype, entity: integer, fromRow: integer, toRow: integer))?

Caller-writable. Receives a swap-pop relocation with zero-based row indices.

onActivatedfield#

onActivated: (function(self: EntityObserver, value: Archetype))?

Caller-writable. Runs when the archetype becomes nonempty.

onDeactivatedfield#

onDeactivated: (function(self: EntityObserver, value: Archetype))?

Caller-writable. Runs when the archetype becomes empty.

onArchetypeDestroyedfield#

onArchetypeDestroyed: (function(self: EntityObserver, value: Archetype))?

Caller-writable. Runs before maintenance permanently unregisters the archetype.

BatchCallbacktype#

type BatchCallback = function(
    candidate: archetype.Archetype,
    firstRow: integer,
    lastRow: integer,
    count: integer
)

Initializes or updates a contiguous one-based archetype row range at a barrier.

Bundlerecord#

record Bundle ...

A reusable world-bound spawn shape.

Members

NameKindDescription
namefield
requiredfield
defaultedfield
worldfield
requiredComponentsfield
defaultComponentsfield
defaultFactoriesfield
cachedTargetfield
cachedStatefield
requiredDefaultsfield
plainfield
scratchInputsfield
busyfield
spawnmethod

namefield#

name: string

requiredfield#

required: {string}

defaultedfield#

defaulted: {string}

worldfield#

world: any
@private

requiredComponentsfield#

requiredComponents: {components.Component}
@private

defaultComponentsfield#

defaultComponents: {components.Component}
@private

defaultFactoriesfield#

defaultFactories: {BundleFactory?}
@private

cachedTargetfield#

cachedTarget: archetype.Archetype?
@private

cachedStatefield#

cachedState: components.Component?
@private

requiredDefaultsfield#

requiredDefaults: {[integer]: any}
@private

plainfield#

plain: boolean
@private

scratchInputsfield#

scratchInputs: {components.Input}
@private

busyfield#

busy: boolean
@private

spawnmethod#

spawn: function(self: Bundle, ...: components.Input): integer
Arguments
NameTypeDescription
selfBundle
...components.Input
Returns
TypeDescription
integer

BundleDefinitiontype#

type BundleDefinition = {
    required: {components.Selector}?,
    with: {[components.Selector]: true | BundleFactory}?
}

Required and defaulted components for a bundle.

Componentinterface#

interface Component ...

A process-wide component definition.

Members

NameKindDescription
Valuefield
Columnfield
componentIdfield
componentNamefield
storageTypefield
transientfield

Valuefield#

Value: associatedDecl

Columnfield#

Column: associatedDecl

componentIdfield#

componentId: integer

componentNamefield#

componentName: string

storageTypefield#

storageType: string

transientfield#

transient: boolean

componentrecord#

record component ...
@annotation(targets={"record","struct"})

Configures a derived component's persisted identity and snapshot policy.

Members

NameKindDescription
namefieldCaller-writable.
transientfieldCaller-writable.

namefield#

name: string?

Caller-writable. Pins the persisted name; nil uses the qualified declaration.

transientfield#

transient: boolean?

Caller-writable. Omits this component's values from snapshots.

ComponentDefinitioninterface#

interface ComponentDefinition<T> is Component ...

A named definition with its column type selected from the value declaration.

Type parameters

NameDescription
T

Members

NameKindDescription
Valuefield
Columnfield
constructmethod
defaultFactorymethod
snapshotSavemethod
snapshotLoadmethod
__callmetamethod

Valuefield#

Value: associatedDecl

Columnfield#

Column: associatedDecl

constructmethod#

construct: function(...: any): T
Arguments
NameTypeDescription
...any
Returns
TypeDescription
T

defaultFactorymethod#

defaultFactory: function(): T
Returns
TypeDescription
T

snapshotSavemethod#

snapshotSave: function(value: T): any
Arguments
NameTypeDescription
valueT
Returns
TypeDescription
any

snapshotLoadmethod#

snapshotLoad: function(value: any, exclusive world: any): T
Arguments
NameTypeDescription
valueany
exclusive worldany
Returns
TypeDescription
T

__callmetamethod#

__call: function(self, ...: any): FFIInstance<T, TypedComponent<T>>
Arguments
NameTypeDescription
?self
...any
Returns
TypeDescription
FFIInstance<T, TypedComponent<T>>

ComponentInputtype#

type ComponentInput = Component
| Type<derived.Value>
| derived.Value
| ScalarInstance<any>
| TableInstance<any>
| FFIInstance<any, any>
| RelationshipInstance
| RelationshipBatch

A component definition or constructed value accepted by a mutation.

ComponentOptionstype#

type ComponentOptions<T> = {
    --- Caller-writable. Sets the persisted identity; defaults to the derived name.
    name: string?,

    --- Caller-writable. Overrides the declaration's initializer for factory calls.
    construct: (function(...: any): T)?,

    --- Caller-writable. Overrides per-entity default initialization.
    default: (function(): T)?,

    --- Caller-writable. Omits this definition's values from snapshots.
    transient: boolean?,

    --- Caller-writable. Adds missing components or shared instances transitively.
    requires: {ComponentInput}?,

    --- Caller-writable. Replaces automatic encoding; pair with load or deserialize.
    save: (function(value: T): any)?,

    --- Caller-writable. Reconstructs a saved value; excludes deserialize.
    load: (function(value: any): T)?,

    --- Caller-writable. Reconstructs a value with the destination world; excludes load.
    deserialize: (function(exclusive world: World, value: any): T)?
}

Configures an explicit component identity from a declaration.

Type parameters

NameDescription
T

ComponentValueinterface#

sealed interface ComponentValue

Bounds generic helpers to records or structs deriving the component contract.

DoubleArrayinterface#

interface DoubleArray ...

Exposes the native, one-based packed entity ID column and its exact length.

Members

NameKindDescription
__lenmetamethod
__indexmetamethod
__newindexmetamethod

__lenmetamethod#

__len: function(self: DoubleArray): integer
Arguments
NameTypeDescription
selfDoubleArray
Returns
TypeDescription
integer

__indexmetamethod#

__index: function(self: DoubleArray, index: integer): integer
Arguments
NameTypeDescription
selfDoubleArray
indexinteger
Returns
TypeDescription
integer

__newindexmetamethod#

__newindex: function(self: DoubleArray, index: integer, id: integer?): nil
Arguments
NameTypeDescription
selfDoubleArray
indexinteger
idinteger?
Returns
TypeDescription
nil

EdgeOptionstype#

type EdgeOptions<T> = {
    --- Caller-writable. Sets the persisted identity; defaults to the derived name.
    name: string?,

    --- Caller-writable. Constructs an edge from its target and optional payload
    --- arguments.
    construct: (function(target: integer, ...: any): T)?,

    --- Caller-writable. Omits this definition's edges from snapshots.
    transient: boolean?,

    --- Caller-writable. Adds missing components or shared instances transitively.
    requires: {ComponentInput}?,

    --- Caller-writable. Replaces automatic encoding; pair with load or deserialize.
    save: (function(value: T): any)?,

    --- Caller-writable. Reconstructs a saved edge; excludes deserialize.
    load: (function(value: any): T)?,

    --- Caller-writable. Reconstructs an edge with the destination world; excludes load.
    deserialize: (function(exclusive world: World, value: any): T)?,

    --- Caller-writable. Limits each source to one target when true.
    exclusive: boolean?,

    --- Caller-writable. Selects entity-indexed edges instead of dense target columns.
    sparse: boolean?,

    --- Caller-writable. Maintains target-to-source lookup when true.
    reverseIndex: boolean?,

    --- Caller-writable. Deletes sources with their target; requires reverseIndex and
    --- exclusive.
    cascadeDelete: boolean?
}

Configures a named payload relationship from a declaration.

Type parameters

NameDescription
T

EntityLifecycletype#

type EntityLifecycle = OnSpawn | OnDespawn

The payload shared by entity spawn and despawn lifecycle events.

FinishSnapshotLoadrecord#

record FinishSnapshotLoad ...
@derive(events.Event)@event(name="FinishSnapshotLoad")

Reports completion of snapshot metadata restoration.

Members

NameKindDescription
preludefieldRead-only.

preludefield#

Read-only. Describes the restored snapshot.

FixedOverloadtype#

type FixedOverload = "drop" | "accumulate"

The policy applied when a frame exceeds its fixed-step limit.

NewRelationshiptype#

type NewRelationship = (function(options: RelationshipOptions): Relationship)
& (function<T>(witness: Type<T>, options: EdgeOptions<T>?): RelationshipDefinition<T>)

Accepts target-only options or a declaration with payload relationship options.

OnDespawnrecord#

record OnDespawn ...
@derive(events.Event)@event(name="OnDespawn")

Fires at the entity address and address zero immediately before removal.

Members

NameKindDescription
entityfield
sourcefieldEngine-owned.
rowfieldEngine-owned.
requestedDespawnsfieldEngine-owned.
getmethodReads one of the entity's committed components before removal.
despawnmethodStages another entity for despawn at the same commit barrier.

entityfield#

entity: integer

sourcefield#

source: archetype.Archetype

Engine-owned. Identifies the entity's last committed archetype.

rowfield#

row: integer

Engine-owned. Identifies the entity's zero-based row before removal.

requestedDespawnsfield#

requestedDespawns: {integer}

Engine-owned. Collects dependent entities observers ask to despawn.

getmethod#

get: function get<C is components.Component>(borrows self: OnDespawn, component: C): C.Value?

Reads one of the entity's committed components before removal.

Arguments
NameTypeDescription
borrows selfOnDespawn
componentC
Returns
TypeDescription
C.Value?

despawnmethod#

despawn: function despawn(self: OnDespawn, entity: integer): nil

Stages another entity for despawn at the same commit barrier.

Arguments
NameTypeDescription
selfOnDespawn
entityinteger
Returns
TypeDescription
nil

OnSnapshotSaverecord#

record OnSnapshotSave ...
@derive(events.Event)@event(name="OnSnapshotSave")

Allows snapshot participants to attach metadata and exclude regenerated entities.

Members

NameKindDescription
datafieldEngine-owned.
excludedfieldEngine-owned.
addDatamethodAttaches one named detached value to the snapshot.
excludemethodExcludes every entity carrying a derived-data component.

datafield#

data: {[string]: any}

Engine-owned. Supplies save staging to event construction; use addData instead.

excludedfield#

excluded: {components.Component}

Engine-owned. Supplies exclusion staging to event construction; use exclude instead.

addDatamethod#

addData: function addData(self: OnSnapshotSave, key: string, value: any): nil

Attaches one named detached value to the snapshot.

Arguments
NameTypeDescription
selfOnSnapshotSave

The call-scoped save event.

keystring

The unique nonempty metadata key.

valueany

The serializable metadata value.

Returns
TypeDescription
nil
Raises
TypeCondition
string

when a key is empty or repeated.

excludemethod#

exclude: function exclude(self: OnSnapshotSave, component: components.Selector): nil

Excludes every entity carrying a derived-data component.

Arguments
NameTypeDescription
selfOnSnapshotSave

The call-scoped save event.

componentcomponents.Selector

The component whose entities must be regenerated after load.

Returns
TypeDescription
nil

OnSpawnrecord#

record OnSpawn ...
@derive(events.Event)@event(name="OnSpawn")

Fires at address zero after an entity becomes committed and alive.

Members

NameKindDescription
entityfield

entityfield#

entity: integer

Phasetype#

type Phase = string

A frame phase.

PhaseDefinitiontype#

type PhaseDefinition = {
    --- Caller-writable. Supplies a nonempty stable system-inspection name.
    name: string,

    --- Caller-writable. Selects the registry position; nil appends after existing
    --- positions.
    position: integer?,

    --- Caller-writable. Lists already registered child names; nil declares a leaf.
    children: {string}?
}

Declares a custom phase or ordered phase tree.

PhaseGrouptype#

type PhaseGroup = "StartupGroup"
| "FixedUpdateGroup"
| "RenderGroup"
| "MainGroup"
| "ShutdownGroup"
| "AllGroups"

An ordered predefined group of frame or lifecycle phases.

PhaseSelectiontype#

type PhaseSelection = Phase | PhaseGroup

A leaf phase or predefined group accepted by schedule controls.

Pipelineinterface#

interface Pipeline ...

Implements custom scheduling while the world owns entities and task scopes.

Members

NameKindDescription
countfieldRead-only.
fixedTimestepfieldRead-only.
fixedMaxStepsfieldRead-only.
fixedOverloadfieldRead-only.
fixedAccumulatorfieldEngine-owned.
fixedStepCountfieldRead-only.
fixedTimeDroppedfieldRead-only.
fixedStepsDroppedfieldRead-only.
phaseStatesfieldEngine-owned.
updatemethodDispatches a frame inside the world's existing task scope.
runmethodDispatches one phase or phase tree inside the world's task scope.
addSystemmethodRegisters a system and returns its unique name.
removeSystemmethodRemoves a named system.
listSystemsmethodReturns detached system inspection data.
setSystemEnabledmethodChanges a registered system's enabled state.
enablePhasemethodEnables a phase tree.
disablePhasemethodDisables a phase tree.
isPhaseEnabledmethodReports whether a leaf is enabled.
registerPhasemethodRegisters a custom phase tree and assigns any omitted position.

countfield#

count: integer

Read-only. Reports the registered system count.

fixedTimestepfield#

fixedTimestep: number

Read-only. Reports the fixed-step duration in seconds.

fixedMaxStepsfield#

fixedMaxSteps: integer

Read-only. Limits catch-up iterations in one frame.

fixedOverloadfield#

fixedOverload: FixedOverload

Read-only. Selects drop or accumulate for excess fixed time.

fixedAccumulatorfield#

fixedAccumulator: number

Engine-owned. Stores the fixed remainder; snapshot restore writes it.

fixedStepCountfield#

fixedStepCount: integer

Read-only. Reports completed fixed iterations.

fixedTimeDroppedfield#

fixedTimeDropped: number

Read-only. Reports abandoned fixed time in seconds.

fixedStepsDroppedfield#

fixedStepsDropped: integer

Read-only. Reports abandoned whole fixed steps.

phaseStatesfield#

phaseStates: {boolean}

Engine-owned. Stores enabled flags by registered phase position; snapshots restore it.

updatemethod#

update: function(self: Pipeline, dt: number, exclusive world: World, borrows scope: tasks.Scope): nil

Dispatches a frame inside the world's existing task scope.

Arguments
NameTypeDescription
selfPipeline

The custom scheduler.

dtnumber

The frame duration in seconds.

exclusive worldWorld

The world whose systems run.

borrows scopetasks.Scope

The call-scoped owner of child tasks.

Returns
TypeDescription
nil

runmethod#

run: function(
    self: Pipeline,
    phase: phases.Selection,
    dt: number,
    exclusive world: World,
    borrows scope: tasks.Scope
): nil

Dispatches one phase or phase tree inside the world's task scope.

Arguments
NameTypeDescription
selfPipeline

The custom scheduler.

phasephases.Selection

The selected phase name.

dtnumber

The elapsed seconds supplied to systems.

exclusive worldWorld

The world whose systems run.

borrows scopetasks.Scope

The call-scoped owner of child tasks.

Returns
TypeDescription
nil

addSystemmethod#

addSystem: function(self: Pipeline, config: SystemConfig): string

Registers a system and returns its unique name.

Arguments
NameTypeDescription
selfPipeline

The custom scheduler.

configSystemConfig

The system and its ordering constraints.

Returns
TypeDescription
string

Returns the registered name.

removeSystemmethod#

removeSystem: function(self: Pipeline, name: string): boolean

Removes a named system.

Arguments
NameTypeDescription
selfPipeline

The custom scheduler.

namestring

The registered name.

Returns
TypeDescription
boolean

Returns whether the system existed.

listSystemsmethod#

listSystems: function(self: Pipeline): {SystemInfo}

Returns detached system inspection data.

Arguments
NameTypeDescription
selfPipeline

The custom scheduler.

Returns
TypeDescription
{SystemInfo}

Returns systems in dispatch order.

setSystemEnabledmethod#

setSystemEnabled: function(self: Pipeline, name: string, enabled: boolean): (boolean, string?)

Changes a registered system's enabled state.

Arguments
NameTypeDescription
selfPipeline

The custom scheduler.

namestring

The registered name.

enabledboolean

The desired state.

Returns
TypeDescription
boolean

Returns success and an optional failure reason.

string?

enablePhasemethod#

enablePhase: function(self: Pipeline, phase: phases.Selection): nil

Enables a phase tree.

Arguments
NameTypeDescription
selfPipeline

The custom scheduler.

phasephases.Selection

The selected name.

Returns
TypeDescription
nil

disablePhasemethod#

disablePhase: function(self: Pipeline, phase: phases.Selection): nil

Disables a phase tree.

Arguments
NameTypeDescription
selfPipeline

The custom scheduler.

phasephases.Selection

The selected name.

Returns
TypeDescription
nil

isPhaseEnabledmethod#

isPhaseEnabled: function(self: Pipeline, phase: phases.Phase): boolean

Reports whether a leaf is enabled.

Arguments
NameTypeDescription
selfPipeline

The custom scheduler.

phasephases.Phase

The selected name.

Returns
TypeDescription
boolean

Returns whether dispatch is enabled.

registerPhasemethod#

registerPhase: function(self: Pipeline, phase: phases.Definition): nil

Registers a custom phase tree and assigns any omitted position.

Arguments
NameTypeDescription
selfPipeline

The custom scheduler.

phasephases.Definition

The phase declaration.

Returns
TypeDescription
nil

PreviousTransform2Dstruct#

struct PreviousTransform2D ...
@derive(nupp.derive.Debug)

Stores the position and rotation before the current fixed step.

Members

NameKindDescription
xfieldEngine-owned.
yfieldEngine-owned.
rotationfieldEngine-owned.

xfield#

x: number

Engine-owned. Stores the previous horizontal position in world units.

yfield#

y: number

Engine-owned. Stores the previous vertical position in world units.

rotationfield#

rotation: number

Engine-owned. Stores the previous clockwise rotation in radians.

Queryrecord#

record Query ...

A reusable archetype query.

Members

NameKindDescription
ownerfield
descriptorfieldRead-only.
includefield
excludefield
includeAnyfield
activefield
positionsfield
lifecyclefield
matchedfield
groupIdsfield
groupPositionsfield
groupedfield
archetypeGroupsfield
itermethodIterates nonempty archetypes, in ascending group order when grouped.
groupsmethodIterates nonempty group identifiers in ascending order.
groupmethodIterates nonempty archetypes in one group.
getGroupmethodReturns an archetype's assigned group.
getGroupCountmethodCounts entities in one group.
countmethodCounts all currently matching entities.

ownerfield#

owner: Owner?
@private

descriptorfield#

descriptor: Descriptor

Read-only. Describes the normalized query; mutation after construction is unsupported.

includefield#

include: {components.Component}
@private

excludefield#

exclude: {components.Component}
@private

includeAnyfield#

includeAny: {components.Component}
@private

activefield#

active: {archetype.Archetype}
@private

positionsfield#

positions: {[archetype.Archetype]: integer}
@private

lifecyclefield#

lifecycle: archetype.EntityObserver?
@private

matchedfield#

matched: {[archetype.Archetype]: boolean}
@private

groupIdsfield#

groupIds: {integer}
@private

groupPositionsfield#

groupPositions: {[integer]: integer}
@private

groupedfield#

grouped: {[integer]: GroupState}
@private

archetypeGroupsfield#

archetypeGroups: {[archetype.Archetype]: integer}
@private

itermethod#

iter: function(self: Query): (IterFn, Query, archetype.Archetype?)

Iterates nonempty archetypes, in ascending group order when grouped.

Arguments
NameTypeDescription
selfQuery

The query to read.

Returns
TypeDescription
IterFn

Returns an independent iterator yielding an archetype, count and live entity column.

Query
archetype.Archetype?

groupsmethod#

groups: function(self: Query): (GroupsIterFn, Query, integer?)

Iterates nonempty group identifiers in ascending order.

Arguments
NameTypeDescription
selfQuery

The query to read.

Returns
TypeDescription
GroupsIterFn

Returns an independent iterator, empty for ungrouped queries.

Query
integer?

groupmethod#

group: function(self: Query, groupId: integer): (GroupIterFn, GroupState, archetype.Archetype?)

Iterates nonempty archetypes in one group.

Arguments
NameTypeDescription
selfQuery

The query to read.

groupIdinteger

The integer group identifier.

Returns
TypeDescription
GroupIterFn

Returns an independent iterator yielding an archetype, count and live entity column.

GroupState
archetype.Archetype?

getGroupmethod#

getGroup: function(self: Query, candidate: archetype.Archetype): integer?

Returns an archetype's assigned group.

Arguments
NameTypeDescription
selfQuery

The query to read.

candidatearchetype.Archetype

The archetype to inspect.

Returns
TypeDescription
integer?

Returns nil when unmatched or ungrouped.

getGroupCountmethod#

getGroupCount: function(self: Query, groupId: integer): integer

Counts entities in one group.

Arguments
NameTypeDescription
selfQuery

The query to read.

groupIdinteger

The integer group identifier.

Returns
TypeDescription
integer

Returns zero when the group is absent.

countmethod#

count: function(self: Query): integer

Counts all currently matching entities.

Arguments
NameTypeDescription
selfQuery

The query to read.

Returns
TypeDescription
integer

Returns the committed entity count.

QueryDescriptortype#

type QueryDescriptor = {
    --- Caller-writable. Names this query for inspection.
    name: string?,

    --- Caller-writable. Excludes Paused for logic queries; nil behaves like render.
    type: ("logic" | "render")?,

    --- Caller-writable. Requires all listed components and overrides their automatic
    --- exclusions.
    include: const{components.Selector}?,

    --- Caller-writable. Requires at least one listed component; an empty list adds no
    --- constraint.
    includeAny: const{components.Selector}?,

    --- Caller-writable. Rejects every listed component.
    exclude: const{components.Selector}?,

    --- Caller-writable. Receives entering rows after publication, including initial
    --- members.
    onEntitiesAdded: MembershipCallback?,

    --- Caller-writable. Receives departing rows while their old values remain readable.
    onEntitiesRemoved: MembershipCallback?,

    --- Caller-writable. Retains only initially matching archetypes, with live rows, and
    --- forbids callbacks.
    temp: boolean?,

    --- Caller-writable. Assigns each matching archetype an integer group once.
    groupBy: (function(candidate: archetype.Archetype): integer)?
}

Membership constraints, grouping and notifications for a reusable query.

Relationshiprecord#

record Relationship is Component ...

A target-only entity relationship with selectable cardinality and storage.

Members

NameKindDescription
Valuefield
componentIdfield
componentNamefield
storageTypefield
transientfield
exclusivefield
reverseIndexfield
cascadeDeletefield
sparsefieldRead-only.
__callmetamethod
targetingmethodReturns a component matching one target of this dense relationship.

Valuefield#

Value: associatedDecl

componentIdfield#

componentId: integer

componentNamefield#

componentName: string

storageTypefield#

storageType: string

transientfield#

transient: boolean

exclusivefield#

exclusive: boolean

reverseIndexfield#

reverseIndex: boolean

cascadeDeletefield#

cascadeDelete: boolean

sparsefield#

sparse: boolean

Read-only. Selects entity-indexed edge storage; false selects target-specific dense columns.

__callmetamethod#

__call: function(self, target: integer): RelationshipInstance
Arguments
NameTypeDescription
?self
targetinteger
Returns
TypeDescription
RelationshipInstance

targetingmethod#

targeting: function(self: RelationshipComponent, target: integer): RelationshipComponent

Returns a component matching one target of this dense relationship.

Arguments
NameTypeDescription
selfRelationship

The relationship definition.

targetinteger

The packed target entity identifier.

Returns
TypeDescription
Relationship

Returns a stable target-specific component definition.

Raises
TypeCondition
string

when the relationship uses sparse storage or the target is invalid.

relationshiprecord#

record relationship ...
@annotation(targets={"record","struct"})

Configures a derived relationship's identity, cardinality and storage policy.

Members

NameKindDescription
namefieldCaller-writable.
transientfieldCaller-writable.
exclusivefieldCaller-writable.
sparsefieldCaller-writable.
reverseIndexfieldCaller-writable.
cascadeDeletefieldCaller-writable.

namefield#

name: string?

Caller-writable. Pins the persisted name; nil uses the qualified declaration.

transientfield#

transient: boolean?

Caller-writable. Omits this relationship from snapshots.

exclusivefield#

exclusive: boolean?

Caller-writable. Limits each source to one target when true.

sparsefield#

sparse: boolean?

Caller-writable. Selects entity-indexed edges instead of dense target columns.

reverseIndexfield#

reverseIndex: boolean?

Caller-writable. Maintains target-to-source lookup when true.

cascadeDeletefield#

cascadeDelete: boolean?

Caller-writable. Deletes sources with their target; requires both index and exclusivity.

RelationshipDefinitioninterface#

interface RelationshipDefinition<T> is Component ...

A payload relationship whose target selector retains the physical column type.

Type parameters

NameDescription
T

Members

NameKindDescription
Valuefield
Columnfield
constructmethod
defaultFactorymethod
snapshotSavemethod
snapshotLoadmethod
__callmetamethod
targetingmethod

Valuefield#

Value: associatedDecl

Columnfield#

Column: associatedDecl

constructmethod#

construct: function(...: any): T
Arguments
NameTypeDescription
...any
Returns
TypeDescription
T

defaultFactorymethod#

defaultFactory: function(): T
Returns
TypeDescription
T

snapshotSavemethod#

snapshotSave: function(value: T): any
Arguments
NameTypeDescription
valueT
Returns
TypeDescription
any

snapshotLoadmethod#

snapshotLoad: function(value: any, exclusive world: any): T
Arguments
NameTypeDescription
valueany
exclusive worldany
Returns
TypeDescription
T

__callmetamethod#

__call: function(self, ...: any): FFIInstance<T, TypedRelationship<T>>
Arguments
NameTypeDescription
?self
...any
Returns
TypeDescription
FFIInstance<T, TypedRelationship<T>>

targetingmethod#

targeting: function(self: TypedRelationship<T>, target: integer): TypedComponent<T>
Arguments
NameTypeDescription
selfRelationshipDefinition<T>
targetinteger
Returns
TypeDescription
TypedComponent<T>

RelationshipOptionstype#

type RelationshipOptions = {
    --- Caller-writable. Sets the stable process-wide relationship name.
    name: string,

    --- Caller-writable. Limits each source to one target when true; defaults to false.
    exclusive: boolean?,

    --- Caller-writable. Uses entity-indexed storage instead of target-specific
    --- archetypes when true.
    sparse: boolean?,

    --- Caller-writable. Maintains target-to-source lookup when true.
    reverseIndex: boolean?,

    --- Caller-writable. Deletes sources with their target; requires exclusive and
    --- reverseIndex.
    cascadeDelete: boolean?,

    --- Caller-writable. Adds missing definitions or shared instance values when an
    --- edge first adds this relationship. Tecs copies the list at registration.
    requires: {Input}?,

    --- Caller-writable. Omits this relationship from snapshots when true.
    transient: boolean?
}

Construction and storage options for target-only relationships.

RelationshipPayloadinterface#

sealed interface RelationshipPayload is Value

Bounds generic helpers to target-bearing declarations deriving the relationship contract.

RelationshipValuerecord#

record RelationshipValue ...

A target-only relationship edge value.

Members

NameKindDescription
targetfieldRead-only.

targetfield#

target: integer

Read-only. Names the target; replace the edge through world:set to retarget it.

RelativeTransform2Dstruct#

struct RelativeTransform2D ...
@derive(nupp.derive.Debug)

Offsets an entity from the transform of the parent it names with ChildOf.

Members

NameKindDescription
xfieldCaller-writable.
yfieldCaller-writable.
zfieldCaller-writable.
rotationfieldCaller-writable.
scaleXfieldCaller-writable.
scaleYfieldCaller-writable.
originXfieldCaller-writable.
originYfieldCaller-writable.

xfield#

x: number

Caller-writable. Sets the horizontal offset from the parent, in the parent's rotated and scaled space.

yfield#

y: number

Caller-writable. Sets the vertical offset from the parent, in the parent's rotated and scaled space.

zfield#

z: number

Caller-writable. Sets the depth offset added to the parent's depth.

rotationfield#

rotation: number

Caller-writable. Sets the clockwise rotation in radians added to the parent's rotation.

scaleXfield#

scaleX: number

Caller-writable. Sets the horizontal scale multiplied by the parent's.

scaleYfield#

scaleY: number

Caller-writable. Sets the vertical scale multiplied by the parent's.

originXfield#

originX: number

Caller-writable. Sets the horizontal origin as a fraction of the entity's width, where zero is the left edge and one the right. The builtin composition carries this value and does not read it, because nothing in the transform knows the entity's size; a layout module that does read it is what gives it meaning.

originYfield#

originY: number

Caller-writable. Sets the vertical origin as a fraction of the entity's height, where zero is the top edge and one the bottom. The builtin composition carries this value and does not read it.

RunIftype#

type RunIf = function(dt: number, exclusive world: World, systemName: string): boolean

A predicate receiving the phase delta, world and registered system name.

ScalarComponentrecord#

record ScalarComponent<T> is Component ...

A primitive-valued component definition.

Type parameters

NameDescription
T

Members

NameKindDescription
Valuefield
componentIdfield
componentNamefield
storageTypefield
transientfield
scalarKindfield
scalarDefaultfield
__callmetamethod

Valuefield#

Value: associatedDecl

componentIdfield#

componentId: integer

componentNamefield#

componentName: string

storageTypefield#

storageType: string

transientfield#

transient: boolean

scalarKindfield#

scalarKind: "number" | "boolean" | "string"

scalarDefaultfield#

scalarDefault: T

__callmetamethod#

__call: function(self, value: T): ScalarInstance<T>
Arguments
NameTypeDescription
?self
valueT
Returns
TypeDescription
ScalarInstance<T>

ScalarComponentOptionstype#

type ScalarComponentOptions = NumberComponentOptions | BooleanComponentOptions | StringComponentOptions

Options accepted by the kind-correlated scalar component factory.

Snapshotrecord#

record Snapshot ...

A detached, format-neutral world snapshot.

Members

NameKindDescription
versionfield
nextEntityIdfield
entityCountfield
archetypeCountfield
componentTablefield
archetypesfield
datafield
statesfield
formatfieldRead-only.
bufferfieldRead-only.
pipelinefieldRead-only.

versionfield#

version: integer

nextEntityIdfield#

nextEntityId: integer

entityCountfield#

entityCount: integer

archetypeCountfield#

archetypeCount: integer

componentTablefield#

componentTable: {SnapshotComponentEntry}

archetypesfield#

archetypes: {SnapshotArchetype}

datafield#

data: {SnapshotDataEntry}

statesfield#

states: {string}

formatfield#

format: ("binary" | "table")?

Read-only. Identifies binary output when a native buffer was requested.

bufferfield#

buffer: buffer.Buffer?

Read-only. Holds binary output; later saves into the same buffer overwrite it.

pipelinefield#

pipeline: {
    fixedAccumulator: number,
    phaseStates: {boolean},
    disabledPhases: {[string]: boolean}
}?

Read-only. Preserves fixed-step remainder and disabled phase names in table output.

SnapshotHandlertype#

type SnapshotHandler = {
    name: string,
    save: (function(exclusive world: World): any)?,
    load: (function(exclusive world: World, value: any): nil)?,
    finish: (function(exclusive world: World, prelude: SnapshotPrelude): nil)?
}

A named custom snapshot participant.

SnapshotOptionstype#

type SnapshotOptions = {
    --- Caller-writable. Attaches unique named custom data.
    customData: {[string]: any}?,

    --- Caller-writable. Selects entities without automatic Disabled or Paused
    --- exclusions.
    filterQuery: query.Descriptor?,

    --- Caller-writable. Selects draw layers from zero through 31; entities without
    --- Transform2D always pass.
    layers: {integer}?,

    --- Caller-writable. Chooses binary framing or a detached table; nil retains table
    --- output.
    format: ("binary" | "table")?,

    --- Caller-writable. Supplies reusable binary output storage, reset at save time.
    buffer: buffer.Buffer?,

    --- Caller-writable. Writes binary output to this file and also returns its buffer.
    path: string?
}

Options for adding custom snapshot data.

SnapshotPreluderecord#

record SnapshotPrelude ...

Metadata returned by a snapshot load.

Members

NameKindDescription
versionfieldRead-only.
nextEntityIdfieldRead-only.
entityCountfieldRead-only.
archetypeCountfieldRead-only.
componentTablefieldRead-only.

versionfield#

version: integer

Read-only. Reports the ECS framing version, independently of game data versions.

nextEntityIdfield#

nextEntityId: integer

Read-only. Reports the next fresh entity slot after restoration.

entityCountfield#

entityCount: integer

Read-only. Reports the number of saved entities.

archetypeCountfield#

archetypeCount: integer

Read-only. Reports the number of saved archetype frames.

componentTablefield#

componentTable: {SnapshotComponentEntry}

Read-only. Lists the saved component names and native layouts in frame-index order.

StartSnapshotLoadrecord#

record StartSnapshotLoad ...
@derive(events.Event)@event(name="StartSnapshotLoad")

Allows snapshot participants to subscribe to metadata during a load.

Members

NameKindDescription
preludefieldRead-only.
handlersfieldEngine-owned.
onDatamethodSubscribes to one custom-data key for this load only.

preludefield#

Read-only. Describes the snapshot being restored.

handlersfield#

handlers: {[string]: {function(value: any)}}

Engine-owned. Supplies dispatch staging to event construction; use onData instead.

onDatamethod#

onData: function onData(self: StartSnapshotLoad, key: string, callback: function(value: any)): nil

Subscribes to one custom-data key for this load only.

Arguments
NameTypeDescription
selfStartSnapshotLoad

The call-scoped load event.

keystring

The nonempty metadata key.

callbackfunction(value: any)

The callback; multiple listeners receive the same key in registration order.

Returns
TypeDescription
nil
Raises
TypeCondition
string

when the key is empty.

StateBlurrecord#

record StateBlur ...
@derive(events.Event)@event(name="StateBlur")

Fires after the current state loses focus.

Members

NameKindDescription
statefield
pushedfield

statefield#

state: string

pushedfield#

pushed: string

StateBlurChangetype#

type StateBlurChange = StateBlur

The payload emitted when a state loses focus.

StateChangetype#

type StateChange = StateEnter | StateExit

The payload emitted when a state enters or exits.

StateEnterrecord#

record StateEnter ...
@derive(events.Event)@event(name="StateEnter")

Fires after a state becomes active.

Members

NameKindDescription
statefield

statefield#

state: string

StateExitrecord#

record StateExit ...
@derive(events.Event)@event(name="StateExit")

Fires before a state leaves the stack.

Members

NameKindDescription
statefield

statefield#

state: string

StateFocusrecord#

record StateFocus ...
@derive(events.Event)@event(name="StateFocus")

Fires after an uncovered state regains focus.

Members

NameKindDescription
statefield
poppedfield

statefield#

state: string

poppedfield#

popped: string

StateFocusChangetype#

type StateFocusChange = StateFocus

The payload emitted when a state regains focus.

StatePolicytype#

type StatePolicy = {
    onBlur: StatePolicyOperation?,
    onFocus: StatePolicyOperation?,
    onEnter: StatePolicyOperation?,
    onExit: StatePolicyOperation?
}

Policy hooks for one world state.

Systemtype#

type System = function(dt: number, exclusive world: World, borrows scope: tasks.Scope)

A system body receiving elapsed time, its world, and the update task scope.

SystemConfigtype#

type SystemConfig = {
    --- Caller-writable. Names the system uniquely; nil requests an engine-owned name.
    name: string?,

    --- Caller-writable. Selects the leaf phase that dispatches the system.
    phase: phases.Phase,

    --- Caller-writable. Receives the phase delta, world and borrowed task scope.
    run: System,

    --- Caller-writable. Gates each dispatch; a disabled system does not evaluate it.
    runIf: RunIf?,

    --- Caller-writable. Names systems that must run later in this phase; missing and
    --- cross-phase names contribute no edge. The world copies the list.
    before: {string}?,

    --- Caller-writable. Names systems that must run earlier in this phase; missing and
    --- cross-phase names contribute no edge. The world copies the list.
    after: {string}?,

    --- Caller-writable. Publishes staged changes before evaluating runIf.
    commitBefore: boolean?,

    --- Caller-writable. Publishes staged changes after dispatch, even when runIf is
    --- false.
    commitAfter: boolean?
}

Registration options for a frame system.

SystemInfotype#

type SystemInfo = {
    --- Read-only. Names the registered system.
    name: string,

    --- Read-only. Names its dispatch phase.
    phase: phases.Phase,

    --- Read-only. Reports its position in the inspected schedule.
    position: integer,

    --- Read-only. Reports whether the scheduler permits dispatch.
    enabled: boolean,

    --- Read-only. Reports whether dispatch has an additional predicate.
    hasRunIf: boolean
}

One registered system as reported in execution order.

TagComponentOptionstype#

type TagComponentOptions = {
    name: string,
    transient: boolean?,

    --- Caller-writable. Adds missing definitions or shared instance values, including
    --- transitive requirements. Tecs copies the list at registration.
    requires: {Input}?
}

Options for a marker component with no per-entity value.

Transform2Dstruct#

struct Transform2D ...
@derive(nupp.derive.Debug)

Places an entity in the two-dimensional world.

Members

NameKindDescription
xfieldCaller-writable.
yfieldCaller-writable.
zfieldCaller-writable.
layerfieldCaller-writable.
rotationfieldCaller-writable.
scaleXfieldCaller-writable.
scaleYfieldCaller-writable.

xfield#

x: number

Caller-writable. Sets the horizontal position in world units.

yfield#

y: number

Caller-writable. Sets the vertical position in world units.

zfield#

z: number

Caller-writable. Sets depth within the selected layer.

layerfield#

layer: integer

Caller-writable. Selects the integer draw layer.

rotationfield#

rotation: number

Caller-writable. Sets clockwise rotation in radians.

scaleXfield#

scaleX: number

Caller-writable. Sets horizontal scale in world units.

scaleYfield#

scaleY: number

Caller-writable. Sets vertical scale in world units.

Transform3Dstruct#

struct Transform3D ...
@derive(nupp.derive.Debug)

Places an entity in a right-handed 3D world using a quaternion and per-axis scale.

Members

NameKindDescription
xfield
yfield
zfield
rotationXfield
rotationYfield
rotationZfield
rotationWfield
scaleXfield
scaleYfield
scaleZfield

xfield#

x: number

yfield#

y: number

zfield#

z: number

rotationXfield#

rotationX: number

rotationYfield#

rotationY: number

rotationZfield#

rotationZ: number

rotationWfield#

rotationW: number

scaleXfield#

scaleX: number

scaleYfield#

scaleY: number

scaleZfield#

scaleZ: number

TTLstruct#

struct TTL ...
@derive(nupp.derive.Debug)

Counts down an entity's remaining lifetime.

Members

NameKindDescription
startingTimefieldCaller-writable.
remainingfieldCaller-writable.
percentCompletemethodReturns elapsed lifetime as a fraction from zero at spawn to one at expiry.

startingTimefield#

startingTime: number

Caller-writable. Sets the lifetime the entity started with, in seconds, which is what percentComplete measures against. Raising remaining past this value leaves percentComplete negative, so refresh both when a pickup extends a timer.

remainingfield#

remaining: number

Caller-writable. Sets the seconds of fixed time left before the entity is despawned. Writing a larger value refreshes the timer.

percentCompletemethod#

percentComplete: function percentComplete(self: TTL): number

Returns elapsed lifetime as a fraction from zero at spawn to one at expiry.

A fresh TTL answers zero and an expired one answers one, so a fade or a shrink can drive straight off it. A value restored from a snapshot whose startingTime is zero also answers one, because nothing distinguishes it from having run out.

Arguments
NameTypeDescription
selfTTL

the lifetime to measure

Returns
TypeDescription
number

the completed fraction, clamped to the range zero through one

Worldrecord#

record World is Source<integer> ...

A Tecs world.

Members

NameKindDescription
allocatorfield
archetypesfield
archetypeByIdfield
maxArchetypeIdfield
freeArchetypeIdsfield
archetypeBySignaturefield
componentArchetypesfield
dirtyQueuefield
pendingSpawnsfield
flatSpawnsfield
flatSpawnCountfield
flatSealedCountfield
spawnShapesfield
spawnScratchfield
flatMovesfield
flatMoveCountfield
flatMovesSealedfield
moveScratchfield
mutationValuesfield
emptyValuesfield
pendingSegmentsfield
pendingSpawnBySlotfield
spawnBatchesfield
mutationBatchesfield
pendingMovesfield
pendingMoveBySlotfield
publishingMovefield
pendingDespawnsfield
pendingDespawnBySlotfield
queriesfield
queryOwnerfield
queryObserversfield
relationshipIndexesfield
keyIndexfield
systemsfield
schedulefield
scheduleDirtyfield
pipelinefield
customPhasesfield
phaseOrderfield
systemNamesfield
anonymousSystemCountfield
disabledPhasesfield
bundlesfield
snapshotHandlersfield
snapshotHandlerNamesfield
randomRegistryfield
stateComponentsfield
statePoliciesfield
stateStackfield
autoStateComponentfield
updatingfield
observedEntitiesfieldThe entity addresses something has observed, so clearing every entity can clear their registrations without touching...
transitionObserverfield
committingfield
runningSystemfield
systemThreadfield
commitRequestedfield
nominalFrameTimefield
fixedTimestepfield
fixedAccumulatorfield
fixedStepTotalfield
fixedMaxStepsfield
fixedOverloadfield
fixedTimeDroppedfield
fixedStepsDroppedfield
beforeFixedCallbacksfield
afterFixedCallbacksfield
liveCountfield
archetypeCountfield
systemCountfield
observersfieldObserver registrations by address and event; observers.count is how many are live.
resourcesfield
spawnmethod
spawnAtmethod
batchSpawnmethodReserves a batch sharing one signature and initializes its rows at the next barrier.
batchSpawnAtmethodReserves supplied packed identities in order for a deferred batch spawn.
batchSpawnAtRawmethodReserves packed identities directly from a zero-based native double array.
batchSetmethodStages a value or deferred column writer for currently matching entities.
batchRemovemethodStages component removal for the query's current committed members.
batchDespawnmethodStages normal teardown, events and cascading for currently matching entities.
forEachArchetypemethodVisits every archetype, including empty and disabled ones, in registry order.
findArchetypesmethodIterates registered archetypes containing a component, including empty ones.
dirtyArchetypesmethodCaptures archetypes with dirty components in registry order.
compactmethodPrunes empty dead-target archetypes and rebuilds storage that has lost rows.
isAlivemethod
hasmethod
byKeymethod
requireKeymethod
getfield
getMutfield
markComponentDirtymethod
relationshipSourcesmethod
forEachRelationshipfieldIterates a source entity's edges in target order.
getFirstRelationshipfieldReturns the first edge in target order.
targetsmethodVisits sources targeting an entity in ascending identifier order.
traversemethodTraverses descendants depth first, visiting each identifier at most once.
walkUpmethodWalks the first outgoing edge at each level, in target order.
newQuerymethodCreates a query over committed entities, excluding Disabled by default.
setmethod
removemethod
despawnmethod
commitmethodPublishes staged mutations synchronously, including work staged by observers.
enqueueCommitmethodRequests publication after the current system and its predicate return.
randomStreammethodReturns this world's stable named Nupp random generator.
seedRandommethodRestarts every named random stream without replacing captured generators.
clearEntitiesmethodClears entity data and pending batches while preserving systems, queries and resources.
addSystemmethodRegisters a system for the next external dispatch, copying its constraints.
registerPhasemethodRegisters a custom leaf or tree without adding it to the default frame loop.
removeSystemmethod
listSystemsmethodReports the next schedule in phase and dependency order.
setSystemEnabledmethod
updatemethod
startupmethod
shutdownmethod
runPhasemethod
enablePhasemethod
disablePhasemethod
isPhaseEnabledmethod
getNominalFrameTimemethodReturns the configured seconds per presentation tick.
setNominalFrameTimemethodChanges conversion for future sequence waits; existing deadlines stay fixed.
getFixedTimingmethod
fixedStepCountmethod
getStatsmethodReports current counts and accumulated fixed-step losses.
createStatemethod
pushStatemethod
popStatemethod
peekStatemethod
listStatesmethod
newBundlemethod
spawnBundlemethod
getBundlesmethod
getBundlemethod
saveSnapshotmethodSaves committed entities and durable world metadata in table or native binary form.
loadSnapshotmethodReplaces entity state while retaining registered runtime setup.
addSnapshotHandlermethod
observemethod
observeOncemethod
stopObservingmethod
hasObserversmethod
emitmethod
delivermethod
clearObserversmethod

allocatorfield#

allocator: idallocator.IdAllocator
@private

archetypesfield#

archetypes: {archetype.Archetype}
@private

archetypeByIdfield#

archetypeById: {[integer]: archetype.Archetype}
@private

maxArchetypeIdfield#

maxArchetypeId: integer
@private

freeArchetypeIdsfield#

freeArchetypeIds: {integer}
@private

archetypeBySignaturefield#

archetypeBySignature: {[string]: archetype.Archetype}
@private

componentArchetypesfield#

componentArchetypes: {[integer]: {archetype.Archetype}}
@private

dirtyQueuefield#

dirtyQueue: archetype.DirtyQueue
@private

pendingSpawnsfield#

pendingSpawns: {PendingSpawn}
@private

flatSpawnsfield#

flatSpawns: {any}
@private

flatSpawnCountfield#

flatSpawnCount: integer
@private

flatSealedCountfield#

flatSealedCount: integer
@private

spawnShapesfield#

spawnShapes: SpawnShape
@private

spawnScratchfield#

spawnScratch: {[integer]: any}
@private

flatMovesfield#

flatMoves: {any}
@private

flatMoveCountfield#

flatMoveCount: integer
@private

flatMovesSealedfield#

flatMovesSealed: integer
@private

moveScratchfield#

moveScratch: PendingMove
@private

mutationValuesfield#

mutationValues: {[integer]: any}
@private

emptyValuesfield#

emptyValues: {[integer]: any}
@private

pendingSegmentsfield#

pendingSegments: {PendingSegment}
@private

pendingSpawnBySlotfield#

pendingSpawnBySlot: {[integer]: PendingSpawn}
@private

spawnBatchesfield#

spawnBatches: {SpawnBatch}
@private

mutationBatchesfield#

mutationBatches: {MutationBatch}
@private

pendingMovesfield#

pendingMoves: {PendingMove}
@private

pendingMoveBySlotfield#

pendingMoveBySlot: {[integer]: PendingMove}
@private

publishingMovefield#

publishingMove: PendingMove?
@private

pendingDespawnsfield#

pendingDespawns: {integer}
@private

pendingDespawnBySlotfield#

pendingDespawnBySlot: {[integer]: boolean}
@private

queriesfield#

queries: {query.Query}
@private

queryOwnerfield#

queryOwner: query.Owner
@private

queryObserversfield#

queryObservers: {query.Query}
@private

relationshipIndexesfield#

relationshipIndexes: {[integer]: inverseindex.InverseIndex}
@private

keyIndexfield#

keyIndex: {[string]: integer}
@private

systemsfield#

systems: {RegisteredSystem}
@private

schedulefield#

schedule: {[phases.Phase]: {RegisteredSystem}}
@private

scheduleDirtyfield#

scheduleDirty: boolean
@private

pipelinefield#

pipeline: Pipeline?
@private

customPhasesfield#

customPhases: {[string]: phases.Definition}
@private

phaseOrderfield#

phaseOrder: {string}
@private

systemNamesfield#

systemNames: {[string]: RegisteredSystem}
@private

anonymousSystemCountfield#

anonymousSystemCount: integer
@private

disabledPhasesfield#

disabledPhases: {[string]: boolean}
@private

bundlesfield#

bundles: {[string]: Bundle}
@private

snapshotHandlersfield#

snapshotHandlers: {SnapshotHandler}
@private

snapshotHandlerNamesfield#

snapshotHandlerNames: {[string]: boolean}
@private

randomRegistryfield#

randomRegistry: randomstreams.Registry?
@private

stateComponentsfield#

stateComponents: {[string]: components.Component}
@private

statePoliciesfield#

statePolicies: {[string]: StatePolicy}
@private

stateStackfield#

stateStack: {string}
@private

autoStateComponentfield#

autoStateComponent: components.Component?
@private

updatingfield#

updating: boolean
@private

observedEntitiesfield#

observedEntities: {[integer]: boolean}
@private

The entity addresses something has observed, so clearing every entity can clear their registrations without touching the world's own.

transitionObserverfield#

transitionObserver: TransitionObserver?
@private

committingfield#

committing: boolean
@private

runningSystemfield#

runningSystem: boolean
@private

systemThreadfield#

systemThread: thread?
@private

commitRequestedfield#

commitRequested: boolean
@private

nominalFrameTimefield#

nominalFrameTime: number
@private

fixedTimestepfield#

fixedTimestep: number
@private

fixedAccumulatorfield#

fixedAccumulator: number
@private

fixedStepTotalfield#

fixedStepTotal: integer
@private

fixedMaxStepsfield#

fixedMaxSteps: integer
@private

fixedOverloadfield#

fixedOverload: FixedOverload
@private

fixedTimeDroppedfield#

fixedTimeDropped: number
@private

fixedStepsDroppedfield#

fixedStepsDropped: integer
@private

beforeFixedCallbacksfield#

beforeFixedCallbacks: {function(exclusive world: World)}?
@private

afterFixedCallbacksfield#

afterFixedCallbacks: {function(exclusive world: World)}?
@private

liveCountfield#

liveCount: integer

archetypeCountfield#

archetypeCount: integer

systemCountfield#

systemCount: integer

observersfield#

observers: Observers<integer>

Observer registrations by address and event; observers.count is how many are live.

resourcesfield#

resources: Store

spawnmethod#

spawn: function(exclusive self: World, ...: components.Input): integer
Arguments
NameTypeDescription
exclusive selfWorld
...components.Input
Returns
TypeDescription
integer

spawnAtmethod#

spawnAt: function(exclusive self: World, id: integer, ...: components.Input): nil
Arguments
NameTypeDescription
exclusive selfWorld
idinteger
...components.Input
Returns
TypeDescription
nil

batchSpawnmethod#

batchSpawn: function(
    exclusive self: World,
    count: integer,
    inputs: {components.Input},
    callback: BatchCallback?
): (integer?, {integer}?)

Reserves a batch sharing one signature and initializes its rows at the next barrier.

Arguments
NameTypeDescription
exclusive selfWorld

The world to modify.

countinteger

The positive number of entities to reserve.

inputs{components.Input}

The component definitions or values, including required defaults.

callbackBatchCallback?

The optional initializer, called before membership and spawn events.

Returns
TypeDescription
integer?

Returns a first packed id and nil for a contiguous range, or nil and an explicit id list when slots or generations are non-contiguous.

{integer}?
Raises
TypeCondition
string

for invalid count, exhausted capacity, bare relationships or EntityKey.

batchSpawnAtmethod#

batchSpawnAt: function(
    exclusive self: World,
    ids: {integer},
    inputs: {components.Input},
    callback: BatchCallback?
): nil

Reserves supplied packed identities in order for a deferred batch spawn.

Arguments
NameTypeDescription
exclusive selfWorld

The world to modify.

ids{integer}

The identities to restore; an empty list does nothing.

inputs{components.Input}

The shared component signature and initial values.

callbackBatchCallback?

The optional row initializer at publication.

Returns
TypeDescription
nil
Raises
TypeCondition
string

before reserving any id if one is invalid, duplicated or occupied, or the signature contains EntityKey or a bare relationship.

batchSpawnAtRawmethod#

batchSpawnAtRaw: function(
    exclusive self: World,
    ids: number[?],
    count: integer,
    inputs: {components.Input},
    callback: BatchCallback?
): nil

Reserves packed identities directly from a zero-based native double array.

Arguments
NameTypeDescription
exclusive selfWorld

The world to modify.

idsnumber[?]

The borrowed array, retained until publication. Do not change its selected prefix before the barrier.

countinteger

The number of identities in the prefix; zero does nothing.

inputs{components.Input}

The shared signature. Unlike ordinary batch spawns, this restoration path permits EntityKey, initialized before key registration.

callbackBatchCallback?

The optional initializer, called before indexes and observers.

Returns
TypeDescription
nil
Raises
TypeCondition
string

before reservation for an invalid count, identity, duplicate, occupied slot, or bare relationship.

batchSetmethod#

batchSet: function(
    exclusive self: World,
    selection: query.Query,
    input: components.Input,
    callback: BatchCallback?
): nil

Stages a value or deferred column writer for currently matching entities.

Arguments
NameTypeDescription
exclusive selfWorld

The world owning the query.

selectionquery.Query

The reusable query; membership is captured at this call.

inputcomponents.Input

The component value, or definition when supplying a callback.

callbackBatchCallback?

The optional writer, called for each contiguous affected range.

Returns
TypeDescription
nil
Raises
TypeCondition
string

for a foreign query, EntityKey, or callback mode with an instance or relationship. Relationship values support constant mode.

batchRemovemethod#

batchRemove: function(exclusive self: World, selection: query.Query, input: components.Input): nil

Stages component removal for the query's current committed members.

Arguments
NameTypeDescription
exclusive selfWorld

The world owning the query.

selectionquery.Query

The reusable query to capture now.

inputcomponents.Input

The component definition or a relationship value selecting one target.

Returns
TypeDescription
nil
Raises
TypeCondition
string

when the query belongs to another world.

batchDespawnmethod#

batchDespawn: function(exclusive self: World, selection: query.Query): nil

Stages normal teardown, events and cascading for currently matching entities.

Arguments
NameTypeDescription
exclusive selfWorld

The world owning the query.

selectionquery.Query

The reusable query to capture now.

Returns
TypeDescription
nil
Raises
TypeCondition
string

when the query belongs to another world.

forEachArchetypemethod#

forEachArchetype: function(borrows self: World, callback: function(candidate: archetype.Archetype)): nil

Visits every archetype, including empty and disabled ones, in registry order.

Arguments
NameTypeDescription
borrows selfWorld

The world to inspect.

callbackfunction(candidate: archetype.Archetype)

The callback; it must not commit or compact during this traversal.

Returns
TypeDescription
nil

findArchetypesmethod#

findArchetypes: function(
    borrows self: World,
    component: components.Selector
): function(): (archetype.Archetype?, integer?, DoubleArray?)

Iterates registered archetypes containing a component, including empty ones.

Arguments
NameTypeDescription
borrows selfWorld

The world to inspect.

componentcomponents.Selector

The component used to select the index.

Returns
TypeDescription
function(): (archetype.Archetype?, integer?, DoubleArray?)

Returns an iterator over the live component index.

dirtyArchetypesmethod#

dirtyArchetypes: function(borrows self: World): function(): archetype.Archetype?

Captures archetypes with dirty components in registry order.

Arguments
NameTypeDescription
borrows selfWorld

The world to inspect.

Returns
TypeDescription
function(): archetype.Archetype?

Returns an independent iterator, including empty dirty archetypes.

compactmethod#

compact: function(exclusive self: World): (integer, integer)

Prunes empty dead-target archetypes and rebuilds storage that has lost rows.

Arguments
NameTypeDescription
exclusive selfWorld

A quiet world with no pending mutations or active dispatch.

Returns
TypeDescription
integer

Returns the number of archetypes pruned and surviving stores rebuilt.

integer
Raises
TypeCondition
string

during dispatch, publication, or with uncommitted work.

isAlivemethod#

isAlive: function(borrows self: World, id: integer): boolean
Arguments
NameTypeDescription
borrows selfWorld
idinteger
Returns
TypeDescription
boolean

hasmethod#

has: function(borrows self: World, id: integer, component: components.Selector): boolean
Arguments
NameTypeDescription
borrows selfWorld
idinteger
componentcomponents.Selector
Returns
TypeDescription
boolean

byKeymethod#

byKey: function(borrows self: World, key: string): integer?
Arguments
NameTypeDescription
borrows selfWorld
keystring
Returns
TypeDescription
integer?

requireKeymethod#

requireKey: function(borrows self: World, key: string): integer
Arguments
NameTypeDescription
borrows selfWorld
keystring
Returns
TypeDescription
integer

getfield#

get: (function<C is components.Component>(borrows self: World, id: integer, component: C): C.Value?)
& (function<T is derived.Value>(borrows self: World, id: integer, component: Type<T>): T?)

getMutfield#

getMut: (function<C is components.Component>(exclusive self: World, id: integer, component: C): C.Value?)
& (function<T is derived.Value>(exclusive self: World, id: integer, component: Type<T>): T?)

markComponentDirtymethod#

markComponentDirty: function(exclusive self: World, id: integer, component: components.Selector): nil
Arguments
NameTypeDescription
exclusive selfWorld
idinteger
componentcomponents.Selector
Returns
TypeDescription
nil

relationshipSourcesmethod#

relationshipSources: function(borrows self: World, relationship: components.Selector, target: integer): {integer}
Arguments
NameTypeDescription
borrows selfWorld
relationshipcomponents.Selector
targetinteger
Returns
TypeDescription
{integer}

forEachRelationshipfield#

forEachRelationship: (
    function<C is components.Component>(
        borrows self: World,
        id: integer,
        relationship: C,
        callback: function(value: C.Value)
    ): nil
)
    & (
        function<T is derived.Edge>(
            borrows self: World,
            id: integer,
            relationship: Type<T>,
            callback: function(value: T)
        ): nil
    )

Iterates a source entity's edges in target order.

getFirstRelationshipfield#

getFirstRelationship: (
    function<C is components.Component>(borrows self: World, id: integer, relationship: C): C.Value?
)
    & (
        function<T is derived.Edge>(borrows self: World, id: integer, relationship: Type<T>): T?
    )

Returns the first edge in target order.

targetsmethod#

targets: function<T>(
    borrows self: World,
    target: integer,
    relationship: components.Selector,
    callback: function(source: integer, context: T),
    context: T
): nil

Visits sources targeting an entity in ascending identifier order.

Arguments
NameTypeDescription
borrows selfWorld

The world to inspect.

targetinteger

The target entity identifier.

relationshipcomponents.Selector

The reverse-indexed relationship.

callbackfunction(source: integer, context: T)

The callback receiving each source and the caller's context.

contextT

The caller-owned callback context.

Returns
TypeDescription
nil
Raises
TypeCondition
string

when the relationship has no reverse index.

traversemethod#

traverse: function(
    borrows self: World,
    root: integer,
    relationship: components.Selector
): function(): (integer?, integer?)

Traverses descendants depth first, visiting each identifier at most once.

Arguments
NameTypeDescription
borrows selfWorld

The world to inspect.

rootinteger

The excluded root identifier.

relationshipcomponents.Selector

The reverse-indexed relationship.

Returns
TypeDescription
function(): (integer?, integer?)

Returns an iterator yielding depth and entity; direct children have depth zero.

Raises
TypeCondition
string

when the relationship has no reverse index.

walkUpmethod#

walkUp: function<T>(
    borrows self: World,
    id: integer,
    relationship: components.Selector,
    callback: function(ancestor: integer, depth: integer, context: T): boolean?,
    context: T,
    maxDepth: integer?
): nil

Walks the first outgoing edge at each level, in target order.

Arguments
NameTypeDescription
borrows selfWorld

The world to inspect.

idinteger

The excluded starting entity.

relationshipcomponents.Selector

The relationship to follow.

callbackfunction(ancestor: integer, depth: integer, context: T): boolean?

The callback receiving ancestor, depth starting at one, and context; false stops traversal.

contextT

The caller-owned callback context.

maxDepthinteger?

The positive depth limit, defaulting to 100.

Returns
TypeDescription
nil
Raises
TypeCondition
string

on a cycle or when the depth limit is exceeded.

newQuerymethod#

newQuery: function(exclusive self: World, descriptor: query.Descriptor?): query.Query

Creates a query over committed entities, excluding Disabled by default.

Arguments
NameTypeDescription
exclusive selfWorld

The world that owns the query.

descriptorquery.Descriptor?

The constraints and callbacks; nil matches enabled entities.

Returns
TypeDescription
query.Query

Returns a persistent query unless temp is true.

Raises
TypeCondition
string

for an invalid query type or temporary membership callbacks.

setmethod#

set: function(exclusive self: World, id: integer, input: components.Input, value: any?): nil
Arguments
NameTypeDescription
exclusive selfWorld
idinteger
inputcomponents.Input
valueany?
Returns
TypeDescription
nil

removemethod#

remove: function(exclusive self: World, id: integer, input: components.Input): nil
Arguments
NameTypeDescription
exclusive selfWorld
idinteger
inputcomponents.Input
Returns
TypeDescription
nil

despawnmethod#

despawn: function(exclusive self: World, id: integer): nil
Arguments
NameTypeDescription
exclusive selfWorld
idinteger
Returns
TypeDescription
nil

commitmethod#

commit: function(exclusive self: World): nil

Publishes staged mutations synchronously, including work staged by observers. Reentrant calls during publication join the active drain.

Arguments
NameTypeDescription
exclusive selfWorld

The world to publish; callers must leave query iteration first.

Returns
TypeDescription
nil
Raises
TypeCondition
string

when a publication callback raises.

enqueueCommitmethod#

enqueueCommit: function(exclusive self: World): nil

Requests publication after the current system and its predicate return. Repeated requests coalesce, including across suspension. Outside a system this publishes synchronously; publication callbacks join the active drain. A failed system cancels the request without publishing its staged work.

Arguments
NameTypeDescription
exclusive selfWorld

The world whose pending mutations need a publication barrier.

Returns
TypeDescription
nil
Raises
TypeCondition
string

when a synchronous publication callback raises.

randomStreammethod#

randomStream: function(exclusive self: World, name: string): random.Xoshiro128

Returns this world's stable named Nupp random generator. Stream names and the world seed determine independent sequences. The world snapshots generators automatically and restores captured objects in place.

Arguments
NameTypeDescription
exclusive selfWorld

The world that owns the generator and its snapshot state.

namestring

The non-empty stream name, preferably namespaced for its consumer.

Returns
TypeDescription
random.Xoshiro128

Returns the same mutable generator for each call with this name.

Raises
TypeCondition
string

when the name is empty.

seedRandommethod#

seedRandom: function(exclusive self: World, seed: integer): nil

Restarts every named random stream without replacing captured generators. Streams created later derive their seeds from this seed too.

Arguments
NameTypeDescription
exclusive selfWorld

The world whose random sequences restart.

seedinteger

The finite integer seed, interpreted as a 32-bit word.

Returns
TypeDescription
nil
Raises
TypeCondition
string

when the seed is not a finite integer.

clearEntitiesmethod#

clearEntities: function(exclusive self: World): nil

Clears entity data and pending batches while preserving systems, queries and resources.

Arguments
NameTypeDescription
exclusive selfWorld

The world to reset; reserved identities are invalidated too.

Returns
TypeDescription
nil
Raises
TypeCondition
string

during publication. Use staged despawn from callbacks instead.

addSystemmethod#

addSystem: function(exclusive self: World, config: SystemConfig): string

Registers a system for the next external dispatch, copying its constraints.

Arguments
NameTypeDescription
exclusive selfWorld

The world to modify.

configSystemConfig

The phase, body, optional ordering, gate and barriers.

Returns
TypeDescription
string

Returns the unique explicit or generated system name.

Raises
TypeCondition
string

when another registered system carries that name.

registerPhasemethod#

registerPhase: function(exclusive self: World, phase: phases.Definition): nil

Registers a custom leaf or tree without adding it to the default frame loop.

Arguments
NameTypeDescription
exclusive selfWorld

The world whose phase registry changes.

phasephases.Definition

The stable name, optional position and registered child names.

Returns
TypeDescription
nil
Raises
TypeCondition
string

for duplicate names, invalid positions, unknown children or registration during dispatch.

removeSystemmethod#

removeSystem: function(exclusive self: World, name: string): boolean
Arguments
NameTypeDescription
exclusive selfWorld
namestring
Returns
TypeDescription
boolean

listSystemsmethod#

listSystems: function(borrows self: World): {SystemInfo}

Reports the next schedule in phase and dependency order.

Arguments
NameTypeDescription
borrows selfWorld

The world to inspect without changing any active dispatch.

Returns
TypeDescription
{SystemInfo}

Returns caller-owned metadata, including disabled systems.

Raises
TypeCondition
string

when any phase contains an ordering cycle.

setSystemEnabledmethod#

setSystemEnabled: function(exclusive self: World, name: string, enabled: boolean): (boolean, string?)
Arguments
NameTypeDescription
exclusive selfWorld
namestring
enabledboolean
Returns
TypeDescription
boolean
string?

updatemethod#

update: function(exclusive self: World, dt: number): nil
Arguments
NameTypeDescription
exclusive selfWorld
dtnumber
Returns
TypeDescription
nil

startupmethod#

startup: function(exclusive self: World): nil
Arguments
NameTypeDescription
exclusive selfWorld
Returns
TypeDescription
nil

shutdownmethod#

shutdown: function(exclusive self: World): nil
Arguments
NameTypeDescription
exclusive selfWorld
Returns
TypeDescription
nil

runPhasemethod#

runPhase: function(exclusive self: World, phase: phases.Selection, dt: number?): nil
Arguments
NameTypeDescription
exclusive selfWorld
phasephases.Selection
dtnumber?
Returns
TypeDescription
nil

enablePhasemethod#

enablePhase: function(exclusive self: World, phase: phases.Selection): nil
Arguments
NameTypeDescription
exclusive selfWorld
phasephases.Selection
Returns
TypeDescription
nil

disablePhasemethod#

disablePhase: function(exclusive self: World, phase: phases.Selection): nil
Arguments
NameTypeDescription
exclusive selfWorld
phasephases.Selection
Returns
TypeDescription
nil

isPhaseEnabledmethod#

isPhaseEnabled: function(borrows self: World, phase: phases.Phase): boolean
Arguments
NameTypeDescription
borrows selfWorld
phasephases.Phase
Returns
TypeDescription
boolean

getNominalFrameTimemethod#

getNominalFrameTime: function(borrows self: World): number

Returns the configured seconds per presentation tick.

Arguments
NameTypeDescription
borrows selfWorld
Returns
TypeDescription
number

setNominalFrameTimemethod#

setNominalFrameTime: function(exclusive self: World, seconds: number): nil

Changes conversion for future sequence waits; existing deadlines stay fixed.

Arguments
NameTypeDescription
exclusive selfWorld
secondsnumber
Returns
TypeDescription
nil

getFixedTimingmethod#

getFixedTiming: function(borrows self: World): (number, number, number)
Arguments
NameTypeDescription
borrows selfWorld
Returns
TypeDescription
number
number
number

fixedStepCountmethod#

fixedStepCount: function(borrows self: World): integer
Arguments
NameTypeDescription
borrows selfWorld
Returns
TypeDescription
integer

getStatsmethod#

getStats: function(borrows self: World, fill: WorldStats?): WorldStats

Reports current counts and accumulated fixed-step losses.

Arguments
NameTypeDescription
borrows selfWorld

The world to inspect.

fillWorldStats?

The optional caller-owned result to overwrite without allocating.

Returns
TypeDescription
WorldStats

Returns fill itself, or a new record when fill is absent.

createStatemethod#

createState: function(exclusive self: World, name: string, policy: StatePolicy?): components.Component
Arguments
NameTypeDescription
exclusive selfWorld
namestring
policyStatePolicy?
Returns
TypeDescription
components.Component

pushStatemethod#

pushState: function(exclusive self: World, name: string): nil
Arguments
NameTypeDescription
exclusive selfWorld
namestring
Returns
TypeDescription
nil

popStatemethod#

popState: function(exclusive self: World): nil
Arguments
NameTypeDescription
exclusive selfWorld
Returns
TypeDescription
nil

peekStatemethod#

peekState: function(borrows self: World): string?
Arguments
NameTypeDescription
borrows selfWorld
Returns
TypeDescription
string?

listStatesmethod#

listStates: function(borrows self: World): {string}
Arguments
NameTypeDescription
borrows selfWorld
Returns
TypeDescription
{string}

newBundlemethod#

newBundle: function(self: World, name: string, definition: BundleDefinition?): Bundle
Arguments
NameTypeDescription
selfWorld
namestring
definitionBundleDefinition?
Returns
TypeDescription
Bundle

spawnBundlemethod#

spawnBundle: function(exclusive self: World, name: string, ...: components.Input): integer
Arguments
NameTypeDescription
exclusive selfWorld
namestring
...components.Input
Returns
TypeDescription
integer

getBundlesmethod#

getBundles: function(borrows self: World): {[string]: Bundle}
Arguments
NameTypeDescription
borrows selfWorld
Returns
TypeDescription
{[string]: Bundle}

getBundlemethod#

getBundle: function(borrows self: World, name: string): Bundle?
Arguments
NameTypeDescription
borrows selfWorld
namestring
Returns
TypeDescription
Bundle?

saveSnapshotmethod#

saveSnapshot: function(exclusive self: World, options: SnapshotOptions?): Snapshot

Saves committed entities and durable world metadata in table or native binary form.

Arguments
NameTypeDescription
exclusive selfWorld

The world to save; staged mutations publish first.

optionsSnapshotOptions?

The optional format, reusable output, file, filters and custom metadata.

Returns
TypeDescription
Snapshot

Returns a detached table snapshot or a tagged binary buffer, according to format.

Raises
TypeCondition
string

during publication or another suspended dispatch, for invalid options, duplicate or reserved metadata, unencodable values, or failed file output.

loadSnapshotmethod#

loadSnapshot: function(exclusive self: World, snapshot: any): SnapshotPrelude

Replaces entity state while retaining registered runtime setup.

Arguments
NameTypeDescription
exclusive selfWorld

The destination with component and state definitions already registered.

snapshotany

The current or version-one table, tagged output, byte string or non-consuming buffer.

Returns
TypeDescription
SnapshotPrelude

Returns the validated snapshot prelude.

Raises
TypeCondition
string

during publication or another suspended dispatch, or for invalid framing, identities, schemas, state or codecs.

addSnapshotHandlermethod#

addSnapshotHandler: function(exclusive self: World, handler: SnapshotHandler): nil
Arguments
NameTypeDescription
exclusive selfWorld
handlerSnapshotHandler
Returns
TypeDescription
nil

observemethod#

observe: function<E is Emittable>(
    exclusive self: World,
    address: integer,
    event: Type<E>,
    callback: Observer<E>,
    id: string?
): nil
Arguments
NameTypeDescription
exclusive selfWorld
addressinteger
eventType<E>
callbackObserver<E>
idstring?
Returns
TypeDescription
nil

observeOncemethod#

observeOnce: function<E is Emittable>(
    exclusive self: World,
    address: integer,
    event: Type<E>,
    callback: Observer<E>,
    id: string?
): nil
Arguments
NameTypeDescription
exclusive selfWorld
addressinteger
eventType<E>
callbackObserver<E>
idstring?
Returns
TypeDescription
nil

stopObservingmethod#

stopObserving: function<E is Emittable>(
    exclusive self: World,
    address: integer,
    event: Type<E>,
    callbackOrId: Observer<E> | string
): boolean
Arguments
NameTypeDescription
exclusive selfWorld
addressinteger
eventType<E>
callbackOrIdObserver<E> | string
Returns
TypeDescription
boolean

hasObserversmethod#

hasObservers: function<E is Emittable>(borrows self: World, address: integer, event: Type<E>): boolean
Arguments
NameTypeDescription
borrows selfWorld
addressinteger
eventType<E>
Returns
TypeDescription
boolean

emitmethod#

emit: function<E is Emittable>(
    exclusive self: World,
    address: integer,
    event: Type<E>,
    ...: unpackof Construction(E)
): nil
Arguments
NameTypeDescription
exclusive selfWorld
addressinteger
eventType<E>
...unpackof Construction(E)
Returns
TypeDescription
nil

delivermethod#

deliver: function<E is Emittable>(exclusive self: World, address: integer, event: Type<E>, instance: E): nil
Arguments
NameTypeDescription
exclusive selfWorld
addressinteger
eventType<E>
instanceE
Returns
TypeDescription
nil

clearObserversmethod#

clearObservers: function(exclusive self: World, address: integer): nil
Arguments
NameTypeDescription
exclusive selfWorld
addressinteger
Returns
TypeDescription
nil

WorldConfigtype#

type WorldConfig = {
    --- Caller-writable. Sets seconds per presentation tick, defaulting to 1/60 even
    --- headless.
    nominalFrameTime: number?,
    maxEntities: integer?,
    timestep: number?,
    fixedMaxSteps: integer?,
    fixedOverload: entityworld.FixedOverload?,

    --- Caller-writable. Replaces the scheduler before built-in systems are installed.
    pipelineFactory: (function(): entityworld.Pipeline)?
}

The options accepted by newWorld.

WorldStatsrecord#

record WorldStats ...

Fixed-step overload counters accumulated by a world.

Members

NameKindDescription
entitiesfield
archetypesfield
componentsfield
systemsfield
fixedTimeDroppedfield
fixedStepsDroppedfield

entitiesfield#

entities: integer

archetypesfield#

archetypes: integer

componentsfield#

components: integer

systemsfield#

systems: integer

fixedTimeDroppedfield#

fixedTimeDropped: number

fixedStepsDroppedfield#

fixedStepsDropped: integer

Functions#

Componentcomptime function#

@comptime function Component(info: nupp.derive.Info): nupp.derive.Result<derived.Value>
@comptime

Marks a record or struct as an ECS component and selects its physical storage.

Arguments

NameTypeDescription
infonupp.derive.Info

The declaration being derived.

Returns

TypeDescription
nupp.derive.Result<derived.Value>

Returns its metadata and reusable initializer recipe.

Raises

TypeCondition
string

when the declaration cannot supply a reusable initializer.

declaredComponentsfunction#

function declaredComponents(): {[string]: Component}

Returns a fresh snapshot of every declared component.

Returns

TypeDescription
{[string]: Component}

the caller-owned name-to-component table

definitionfunction#

function definition<T is derived.Value>(declaration: Type<T>): Component

Returns the registered definition for a derived component declaration.

Type parameters

NameDescription
T

Arguments

NameTypeDescription
declarationType<T>

The component declaration to register if necessary.

Returns

TypeDescription
Component

Returns its process-wide identity and storage metadata.

findComponentByIdfunction#

function findComponentById(id: integer): Component?

Returns a registered component by numeric id.

Arguments

NameTypeDescription
idinteger

the process-wide component id

Returns

TypeDescription
Component?

the component, or nil when the id is unknown

findComponentByNamefunction#

function findComponentByName(name: string): Component?

Returns a registered component by name.

Arguments

NameTypeDescription
namestring

the process-wide component name

Returns

TypeDescription
Component?

the component, or nil when the name is unknown

newComponentfunction#

function newComponent<T>(witness: Type<T>, options: ComponentOptions<T>?): ComponentDefinition<T>

Registers a declaration with managed or native columns selected from its layout. The default identity of a derived declaration is cached. Configure it before its first use, or supply a distinct name to create another identity.

Type parameters

NameDescription
T

Arguments

NameTypeDescription
witnessType<T>

The record or struct declaration whose values this definition stores.

optionsComponentOptions<T>?

The optional identity, constructor, defaults and snapshot policy.

Returns

TypeDescription
ComponentDefinition<T>

Returns a callable definition with the declaration's exact column type.

Raises

TypeCondition
string

when the name is empty or already belongs to another definition.

string

when a declaration has neither an initializer nor an explicit constructor.

string

when a native layout is unsupported or snapshot codecs are incomplete.

string

when a requirement is unregistered or names an untargeted relationship.

newTagComponentfunction#

function newTagComponent(options: TagComponentOptions): Component

Creates and registers a marker component with no per-entity value.

Arguments

NameTypeDescription
optionsTagComponentOptions

the process-unique component name and snapshot policy

Returns

TypeDescription
Component

the registered tag component

Raises

TypeCondition
string

when the name is empty or already registered

string

when a requirement is unregistered or names an untargeted relationship.

newWorldfunction#

function newWorld(config: WorldConfig?): World

Creates an independent empty world carrying the builtin systems.

The world arrives with tecs.SnapshotTransforms, ttl, RelativeTransform2D and RelativeTransformDirtySampler already registered, which is what makes a TTL expire and a RelativeTransform2D move its entity without a game installing anything.

Arguments

NameTypeDescription
configWorldConfig?

the world settings, or nil for defaults

Returns

TypeDescription
World

the empty world

Raises

TypeCondition
string

when a capacity or fixed-clock option is invalid

Relationshipcomptime function#

@comptime function Relationship(info: nupp.derive.Info): nupp.derive.Result<derived.Edge>
@comptime

Marks a target-bearing record or struct as an ECS relationship.

Arguments

NameTypeDescription
infonupp.derive.Info

The declaration being derived.

Returns

TypeDescription
nupp.derive.Result<derived.Edge>

Returns its metadata and reusable initializer recipe.

Raises

TypeCondition
string

when the target, policies or initializer are invalid.

targetingfunction#

function targeting<T is derived.Edge>(relationship: Type<T>, target: integer): ComponentDefinition<T>

Selects the typed dense column for one target of a derived relationship.

Type parameters

NameDescription
T

Arguments

NameTypeDescription
relationshipType<T>

The derived edge declaration.

targetinteger

The committed or reserved target identifier.

Returns

TypeDescription
ComponentDefinition<T>

Returns a reusable selector with the edge's exact physical column type.

Raises

TypeCondition
string

when the relationship is sparse or the target is invalid.

Values#

ChildOfvariable#

const ChildOf: RelationshipComponent

Relates one child entity to its parent.

world:spawn(ChildOf(parent)) places an entity under parent, and world:set(child, ChildOf(other)) reparents it at the next barrier. The relationship is exclusive, reverse indexed and cascading: a child has one parent, world:relationshipSources(ChildOf, parent) answers with that parent's children, and despawning a parent despawns the tree beneath it.

DEFAULT_FIXED_MAX_STEPSvariable#

The per-frame fixed-step limit used when newWorld receives no override.

DEFAULT_MAX_ENTITIESvariable#

const DEFAULT_MAX_ENTITIES: integer

The entity capacity used when newWorld receives no override.

DEFAULT_TIMESTEPvariable#

const DEFAULT_TIMESTEP: number

The fixed update interval used when newWorld receives no override.

Disabledvariable#

const Disabled: TagComponent

Marks entities disabled by a state policy.

EntityKeyvariable#

const EntityKey: ScalarComponent<string>

Stores a durable unique name for one entity.

A key names at most one live entity, and World.byKey answers with the entity holding it. Claiming a key another live entity already holds raises, since nothing later could resolve which of the two a lookup means.

The component is registered under the name Key, which is what a snapshot records. That spelling is a compatibility surface and does not follow this public name.

MAX_ENTITIESvariable#

const MAX_ENTITIES: integer

The greatest entity capacity supported by the packed id format.

Namevariable#

const Name: ScalarComponent<string>

Names an entity for a human reader.

A name is neither indexed nor unique. EntityKey is what a lookup resolves through; this is what a debug overlay prints.

newRelationshipvariable#

Registers a target-only relationship or a record or struct payload declaration. The one-argument options form creates target-only edges. The declaration form selects managed or native payload storage without running a user constructor.

Raises

TypeCondition
string

when cascade deletion lacks exclusivity or reverse indexing.

string

when the name is invalid or already belongs to another definition.

string

when a payload declaration does not provide a valid target field.

string

when a native layout is unsupported or snapshot codecs are incomplete.

newScalarComponentvariable#

const newScalarComponent: NewScalarComponent

Creates and registers a scalar component whose column stores raw values.

Raises

TypeCondition
string

when the name is empty or already registered

Pausedvariable#

const Paused: TagComponent

Marks entities paused by a state policy.

PreviousTransform2Dvariable#

const PreviousTransform2D: components.FFIComponent<PreviousTransform2D>

Opts an entity into fixed-step presentation interpolation. Physics seeds this with the body's creation pose. The builtin snapshot system refreshes it before each fixed step; rendering never mutates simulation.

RelativeTransform2Dvariable#

const RelativeTransform2D: components.FFIComponent<RelativeTransform2D>

Constructs an offset from a parent's transform.

Spawn it beside Transform2D and ChildOf. The builtin RelativeTransform2D system composes the parent's world transform with the offset and writes the result into the entity's own Transform2D, so a renderer, a query, or a physics body keeps reading one transform.

Transform2Dvariable#

const Transform2D: components.FFIComponent<Transform2D>

Constructs the shared two-dimensional transform component.

Transform3Dvariable#

const Transform3D: components.FFIComponent<Transform3D>

Constructs a 3D transform, defaulting to the identity at the origin.

TTLvariable#

const TTL: components.FFIComponent<TTL>

Constructs a lifetime that despawns its entity when it runs out.

world:spawn(TTL(0.5)) gives an entity half a second of fixed time. The builtin ttl system spends it one fixed step at a time and despawns the entity at zero, and ttl:percentComplete() reports how much of the original budget is gone.