ecs family
The World, component stores, queries, phase schedules and the world ticker.
Every symbol on this page is exported from the package root: import { Name } from "gamekit";
10 symbols.
| Symbol | Summary |
|---|---|
createConventionalSchedule | function. Creates the opt-in input -> simulate -> resolve -> present -> flush phase chain. |
DenseStore | class. Stores one component value per live generational entity id. |
DenseStoreFactory | class. Creates GameKit's default dense component stores. |
IComponentStore | interface. Defines the indexed membership operations required by World and Query. |
IComponentStoreFactory | interface. Creates game-selected component stores for a World. |
PhaseSchedule | class. Orders named simulation phases by explicit dependencies and preserves system registration order within each phase. |
Query | class. Visits the live intersection of World ownership and one component store in stable entity-id order. |
Query2 | class. Visits entities present in two component stores, choosing the smaller store as the candidate set. |
World | class. Owns one simulation domain's entities, component stores, and deferred structural work. |
WorldTicker | class. Steps a World through a PhaseSchedule once per tick of a node's onTick hook. |
createConventionalSchedule
ts
import { createConventionalSchedule } from "gamekit";
function createConventionalSchedule(): PhaseScheduleCreates the opt-in input -> simulate -> resolve -> present -> flush phase chain.
- Returns: A mutable schedule that flushes the World after every phase succeeds.
DenseStore
ts
import { DenseStore } from "gamekit";
class DenseStore<T> implements IComponentStore<T>Stores one component value per live generational entity id. Removal may move the final dense entry, while snapshots remain ordered by id rather than storage position.
Members
ts
constructor(allocator: EntityAllocator)Binds membership checks to the allocator that issued the entity ids.
allocator: Source of generation and liveness checks for every access.
ts
register(id: EntityId, value: T): voidAdds a value for a live id, evicting only a stale occupant of a recycled index.
id: Exact index-and-generation identity receiving the component.value: Component reference retained until removal or entity release.- Throws: DuplicateRegistration when the same live id already has a value.
- Throws: StaleHandle when
idis no longer live in the allocator.
ts
get(id: EntityId): T | nullReads exact live membership without treating absence or a stale generation as an error.
id: Index-and-generation identity to test.- Returns: The registered value, or
nullwhen the id is stale or absent.
ts
getRequired(id: EntityId): TReads a component when both the identity and its membership must exist.
id: Exact live identity to read.- Returns: The value registered for
id. - Throws: StaleHandle when the allocator has retired
id. - Throws: MissingRegistration when the live id has no component here.
ts
remove(id: EntityId): T | nullRemoves exact membership using swap compaction without changing query order.
id: Index-and-generation identity to remove.- Returns: The former value, or
nullwhen no exact membership exists.
ts
has(id: EntityId): booleanTests exact membership independently of whether T itself permits null-like values.
id: Identity whose current generation must match.- Returns:
trueonly for a live id registered in this store.
ts
snapshotIds(): EntityId[]Captures current members in ascending index then generation order.
- Returns: A detached id array unaffected by later registrations or compaction.
ts
get size(): intNumber of exact current memberships.
DenseStoreFactory
ts
import { DenseStoreFactory } from "gamekit";
class DenseStoreFactory implements IComponentStoreFactoryCreates GameKit's default dense component stores. Usage: World constructs this factory when no replacement is supplied.
Members
ts
create(allocator: EntityAllocator, key: ComponentKey<any>): IComponentStore<any>Creates a dense store sharing the World's identity allocator.
IComponentStore
ts
import { IComponentStore } from "gamekit";
interface IComponentStore<T>Defines the indexed membership operations required by World and Query. Usage: implement this interface when dense storage is unsuitable for a game.
Members
ts
register(id: EntityId, value: T): voidRegisters one live entity identity and value.
ts
get(id: EntityId): T | nullReturns a current value or null for absence.
ts
getRequired(id: EntityId): TReturns a current value and throws for absent membership.
ts
remove(id: EntityId): T | nullRemoves exact current membership and returns its prior value.
ts
has(id: EntityId): booleanReports exact current membership independently of nullable values.
ts
snapshotIds(): EntityId[]Returns an independent candidate snapshot for deterministic query ordering.
ts
readonly size: intReports the number of current registrations.
IComponentStoreFactory
ts
import { IComponentStoreFactory } from "gamekit";
interface IComponentStoreFactoryCreates game-selected component stores for a World. Usage: pass an implementation to the World constructor before registering stores.
Members
ts
create(allocator: EntityAllocator, key: ComponentKey<any>): IComponentStore<any>Creates one store for the supplied allocator and typed key.
PhaseSchedule
ts
import { PhaseSchedule } from "gamekit";
class PhaseScheduleOrders named simulation phases by explicit dependencies and preserves system registration order within each phase. A phase may define the command-buffer flush boundary; the schedule never invents phases or systems.
Members
ts
addPhase(name: string, after: string[] = [], flushAfter: boolean = false): voidDeclares a phase and the phase names that must precede it.
name: Non-empty identity unique within this schedule.after: Dependency names resolved whenrunbegins; declaration order breaks unrelated ties.flushAfter: Whether to flush the World after every system in this phase succeeds.- Throws: Error for an empty or duplicate name, or mutation during a run.
ts
addSystem(phaseName: string, work: Function): voidAppends a system to a declared phase.
phaseName: Existing phase that owns the callback order.work: Callback receiving(world, deltaSeconds, tickNumber).- Throws: Error when the phase is unknown or the schedule is running.
ts
run(world: World, delta: float, tick: int): voidResolves dependencies, then invokes systems phase by phase under the World's structural guard. A thrown system aborts remaining work and prevents that phase's automatic flush.
world: Simulation domain passed to every system.delta: Fixed-step duration in seconds.tick: Monotonic simulation tick supplied unchanged to callbacks.- Throws: Error for recursion, dependency cycles, missing dependencies, or a system failure.
Query
ts
import { Query } from "gamekit";
class Query<T>Visits the live intersection of World ownership and one component store in stable entity-id order.
Members
ts
constructor(world: any, key: ComponentKey<T>)Captures the World and component identity; membership is snapshotted later by each.
world: World that owns entity resolution and query guards.key: Registered component store to traverse.
ts
each(visitor: Function): voidVisits a membership snapshot in ascending entity-id order while direct structural mutation is forbidden. Deferred commands remain invisible until a later explicit World.flush.
visitor: Callback receiving(entity, component)for each still-live member.- Throws: MissingRegistration when the component store was not registered.
Query2
ts
import { Query2 } from "gamekit";
class Query2<A, B>Visits entities present in two component stores, choosing the smaller store as the candidate set.
Members
ts
constructor(world: any, first: ComponentKey<A>, second: ComponentKey<B>)Captures the World and two component identities; membership is snapshotted by each.
world: World that owns entity resolution and query guards.first: First registered component store and first callback value.second: Second registered component store and second callback value.
ts
each(visitor: Function): voidVisits the live intersection in ascending entity-id order under the World's query guard.
visitor: Callback receiving(entity, firstValue, secondValue)for every exact match.- Throws: MissingRegistration when either component store was not registered.
World
ts
import { World } from "gamekit";
class World implements IEntityWorldOwnerOwns one simulation domain's entities, component stores, and deferred structural work. Game code retains the World and advances its explicit phases; it has no import-time registration.
Members
ts
constructor(storeFactory: IComponentStoreFactory = new DenseStoreFactory())Starts an open simulation domain with no entities or component stores.
storeFactory: Factory invoked once for each key registered with the World.
ts
createEntity(): EntityCreates and adopts an active root Entity in this World. Use this helper when the World should construct the object. Use adoptEntity when game code constructs an Entity or subtype first. The returned Entity is immediately World-owned and gets a fresh generational identity.
- Returns: A new active root owned by this World.
- Throws: Error when the World is closed or structural work is currently deferred.
ts
adoptEntity(entity: Entity): EntityIdAdopts a detached Entity into this World and activates it as a root. This is the ownership primitive. Use it when game code constructs an Entity or subtype first; use createEntity for the shorthand that constructs a plain Entity before adoption. Each adoption issues a fresh runtime identity.
entity: Detached object to claim; its local components and effects survive transfer.- Returns: A fresh generational identity valid only while this World owns the entity.
- Throws: Error when the entity is not detached or structural mutation is guarded.
ts
removeEntity(entity: Entity): voidReleases an Entity, its runtime id, and indexed components without disposing local state. This is the ownership-removal primitive used for transfer and pooling. Use disposeEntity when the object itself must become terminal.
entity: Current member, detached before its identity is retired.- Throws: Error when the entity is foreign or structural mutation is guarded.
ts
disposeEntity(entity: Entity): voidRemoves one owned Entity and then disposes that object permanently. This helper combines the removeEntity ownership primitive with Entity.dispose. Use removeEntity instead for transfer or pooling.
entity: Current member to remove and dispose.- Throws: Error when the target is foreign or structural mutation is guarded.
ts
dispose(): voidCloses this World and disposes every Entity it owns. A bare verb acts on its receiver; use disposeEntity(entity) to dispose one named Entity. Repeated calls are harmless.
ts
onEntityDisposed(entity: Entity): voidReleases World indexes after an owned Entity completes disposal. This public hook keeps core independent from ecs; game code normally calls disposeEntity.
entity: Possibly owned object issuing its disposal notification.
ts
beforeEntityDispose(entity: Entity): voidRejects direct Entity disposal during query, phase, or flush callbacks.
entity: Object about to enter its disposal callbacks.- Throws: Error when direct structural mutation is not currently safe.
ts
idOf(entity: Entity): EntityIdReads the entity's current World-local generational identity.
entity: Object whose ownership must be current.- Returns: An id invalidated when the object is removed or disposed.
- Throws: Error when this World does not own
entity.
ts
resolve(id: EntityId): Entity | nullResolves an exact generation without reviving recycled identities.
id: World-issued identity to resolve.- Returns: The owned Entity, or
nullwhen the id is stale, released, or foreign.
ts
owns(entity: Entity): booleanTests object ownership without throwing for detached or foreign entities.
entity: Object reference to compare with current members.- Returns:
trueonly while this World retains that exact object.
ts
get entityCount(): intNumber of roots currently owned by this World.
ts
entities(): Entity[]Captures owned roots in adoption order.
- Returns: A detached array unaffected by later World mutation.
ts
registerStore<T>(key: ComponentKey<T>): IComponentStore<T>Creates the sole indexed store associated with a typed component key.
key: Identity token used for later access; equal labels do not make keys equal.- Returns: The factory-created store retained by this World.
- Throws: DuplicateRegistration when the exact key is already registered.
ts
store<T>(key: ComponentKey<T>): IComponentStore<T> | nullLooks up a component store by typed-key identity.
key: Exact key originally registered with this World.- Returns: The store, or
nullwhen that key was never registered.
ts
storeRequired<T>(key: ComponentKey<T>): IComponentStore<T>Retrieves a store when absence indicates a configuration error.
key: Exact registered component identity.- Returns: The store associated with
key. - Throws: MissingRegistration when no store uses that key.
ts
put<T>(entity: Entity, key: ComponentKey<T>, value: T): voidRegisters an indexed component immediately for an owned entity.
entity: Current member receiving the component.key: Registered store identity.value: Component reference retained by the store.- Throws: Error during a query, phase, or flush callback; use
deferPutComponentthere.
ts
get<T>(entity: Entity, key: ComponentKey<T>): T | nullReads indexed membership without treating a foreign entity or unregistered key as an error.
entity: Object to resolve in this World.key: Component identity to inspect.- Returns: The current value, or
nullfor absent ownership, store, or membership.
ts
getRequired<T>(entity: Entity, key: ComponentKey<T>): TReads indexed membership when ownership, store registration, and presence are invariants.
entity: Object that must currently belong to this World.key: Component identity that must have a store and value.- Returns: The exact component reference in the store.
- Throws: Error when any required ownership or membership is absent.
ts
removeComponent<T>(entity: Entity, key: ComponentKey<T>): T | nullRemoves indexed membership immediately when ownership, store, and value are present.
entity: Object to inspect in this World.key: Component identity to remove.- Returns: The former value, or
nullfor absent ownership, store, or membership. - Throws: Error during a query, phase, or flush callback; use
deferRemoveComponentthere.
ts
query<T>(key: ComponentKey<T>): Query<T>Creates a reusable one-store query; membership is captured when each starts.
key: Registered component identity required by the query.- Returns: A lightweight query bound to this World and key.
ts
query2<A, B>(first: ComponentKey<A>, second: ComponentKey<B>): Query2<A, B>Creates a reusable two-store intersection query; membership is captured by each.
first: Registered key whose value is the visitor's second argument.second: Registered key whose value is the visitor's third argument.- Returns: A lightweight query bound to this World and both keys.
ts
runPhase(work: Function): voidRuns a callback inside a structural-mutation guard without implicitly flushing commands. Nested phases are allowed, and the guard is released even when the callback throws.
work: Synchronous simulation callback.
ts
deferCreateEntity(): EntityQueues creation and returns the detached Entity that later commands may reference.
- Returns: An object not owned or query-visible until a successful
flush.
ts
deferDisposeEntity(entity: Entity): voidAppends entity disposal to the command buffer.
entity: Current member, or an earlierdeferCreateEntityresult in the same batch.
ts
deferPutComponent<T>(entity: Entity, key: ComponentKey<T>, value: T): voidAppends component registration to the command buffer in issue order.
entity: Current member, or an earlier deferred creation in the batch.key: Store identity validated during flush preflight.value: Component reference made visible only after the batch applies.
ts
deferRemoveComponent<T>(entity: Entity, key: ComponentKey<T>): voidAppends component removal to the command buffer in issue order.
entity: Current member whose eventual membership is targeted.key: Component identity to remove when the batch applies.
ts
flush(): voidPreflights and applies the current command batch atomically in issue order. Invalid batches are discarded before mutation; callback commands wait for the next flush.
- Throws: Error inside a query or phase, on recursive flush, or for a conflicting batch.
WorldTicker
ts
import { WorldTicker } from "gamekit";
class WorldTickerSteps a World through a PhaseSchedule once per tick of a node's onTick hook. The runtime owns the fixed tick (App.tps, catch-up cap, pause and time scale); this class only forwards each tick, so pausing or disposing the node stops or ends the world step with it.
Members
ts
constructor(node: any, world: World, schedule: PhaseSchedule, tickDelta: float)Installs the step as node.onTick.
node: Scene node whoseonTickhook drives the world; its previous hook is replaced.world: Simulation domain passed to every system.schedule: Ordering of the systems inside one step.tickDelta: Positive seconds per tick, normallyApp.tickDelta.- Throws: Error for a null node or a non-positive delta.
ts
get tickCount(): intCounts steps run so far, which is also the next tick number passed to the systems.
ts
dispose(): voidDetaches the hook from the node; later ticks no longer step the world. Safe to call twice.