Skip to content

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.

SymbolSummary
createConventionalSchedulefunction. Creates the opt-in input -> simulate -> resolve -> present -> flush phase chain.
DenseStoreclass. Stores one component value per live generational entity id.
DenseStoreFactoryclass. Creates GameKit's default dense component stores.
IComponentStoreinterface. Defines the indexed membership operations required by World and Query.
IComponentStoreFactoryinterface. Creates game-selected component stores for a World.
PhaseScheduleclass. Orders named simulation phases by explicit dependencies and preserves system registration order within each phase.
Queryclass. Visits the live intersection of World ownership and one component store in stable entity-id order.
Query2class. Visits entities present in two component stores, choosing the smaller store as the candidate set.
Worldclass. Owns one simulation domain's entities, component stores, and deferred structural work.
WorldTickerclass. Steps a World through a PhaseSchedule once per tick of a node's onTick hook.

createConventionalSchedule ​

ts
import { createConventionalSchedule } from "gamekit";
function createConventionalSchedule(): PhaseSchedule

Creates 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): void

Adds 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 id is no longer live in the allocator.
ts
get(id: EntityId): T | null

Reads 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 null when the id is stale or absent.
ts
getRequired(id: EntityId): T

Reads 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 | null

Removes exact membership using swap compaction without changing query order.

  • id: Index-and-generation identity to remove.
  • Returns: The former value, or null when no exact membership exists.
ts
has(id: EntityId): boolean

Tests exact membership independently of whether T itself permits null-like values.

  • id: Identity whose current generation must match.
  • Returns: true only 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(): int

Number of exact current memberships.

DenseStoreFactory ​

ts
import { DenseStoreFactory } from "gamekit";
class DenseStoreFactory implements IComponentStoreFactory

Creates 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): void

Registers one live entity identity and value.

ts
get(id: EntityId): T | null

Returns a current value or null for absence.

ts
getRequired(id: EntityId): T

Returns a current value and throws for absent membership.

ts
remove(id: EntityId): T | null

Removes exact current membership and returns its prior value.

ts
has(id: EntityId): boolean

Reports exact current membership independently of nullable values.

ts
snapshotIds(): EntityId[]

Returns an independent candidate snapshot for deterministic query ordering.

ts
readonly size: int

Reports the number of current registrations.

IComponentStoreFactory ​

ts
import { IComponentStoreFactory } from "gamekit";
interface IComponentStoreFactory

Creates 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 PhaseSchedule

Orders 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): void

Declares a phase and the phase names that must precede it.

  • name: Non-empty identity unique within this schedule.
  • after: Dependency names resolved when run begins; 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): void

Appends 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): void

Resolves 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): void

Visits 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): void

Visits 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 IEntityWorldOwner

Owns 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(): Entity

Creates 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): EntityId

Adopts 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): void

Releases 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): void

Removes 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(): void

Closes 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): void

Releases 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): void

Rejects 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): EntityId

Reads 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 | null

Resolves an exact generation without reviving recycled identities.

  • id: World-issued identity to resolve.
  • Returns: The owned Entity, or null when the id is stale, released, or foreign.
ts
owns(entity: Entity): boolean

Tests object ownership without throwing for detached or foreign entities.

  • entity: Object reference to compare with current members.
  • Returns: true only while this World retains that exact object.
ts
get entityCount(): int

Number 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> | null

Looks up a component store by typed-key identity.

  • key: Exact key originally registered with this World.
  • Returns: The store, or null when 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): void

Registers 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 deferPutComponent there.
ts
get<T>(entity: Entity, key: ComponentKey<T>): T | null

Reads 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 null for absent ownership, store, or membership.
ts
getRequired<T>(entity: Entity, key: ComponentKey<T>): T

Reads 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 | null

Removes 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 null for absent ownership, store, or membership.
  • Throws: Error during a query, phase, or flush callback; use deferRemoveComponent there.
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): void

Runs 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(): Entity

Queues 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): void

Appends entity disposal to the command buffer.

  • entity: Current member, or an earlier deferCreateEntity result in the same batch.
ts
deferPutComponent<T>(entity: Entity, key: ComponentKey<T>, value: T): void

Appends 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>): void

Appends 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(): void

Preflights 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 WorldTicker

Steps 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 whose onTick hook 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, normally App.tickDelta.
  • Throws: Error for a null node or a non-positive delta.
ts
get tickCount(): int

Counts steps run so far, which is also the next tick number passed to the systems.

ts
dispose(): void

Detaches the hook from the node; later ticks no longer step the world. Safe to call twice.