Skip to content
Konjure / spatial intelligence

Entities and systems

Attach type values to entities and schedule typed component work.

An entity is an opaque ID with at most one component of each type. spawn creates one component-bearing entity; add attaches another component. A system selects component types and gives its callback typed, mutable bindings for each match. This is the step from value to type to ECS: the type owns state and behavior, while the system owns the update schedule.

Schedule a component

Compile the counter fixture, then use Step and Finish. init prints init once for the matching counter, the first step appends 1, and done prints once when Finish completes. Reset starts a new run at tick zero.

Tick 0 · 0.00 sThis device
main.kj⌘ / Ctrl + Enter
Loading the language runtime…
Output 0
No output.

system Tick of Counter selects one component and addresses it as self. system Rotate of (spinner: Spinner, pose: Transform) selects entities with both distinct concrete types and names the bindings. A successful callback writes every changed binding back together. Misspelled fields and wrong method arguments fail compilation; there is no string lookup or cast. A single selector may name a trait, but trait joins and optional components are not implemented.

Lifecycle and world access

frame(dt) is required. init() runs before the first frame for each matching tuple, and done() runs when an initialized tuple is removed or the host finishes the run. entity, time, and tick identify the current match and simulation clock. despawn is deferred to the callback or action boundary, so teardown sees committed values and a removed entity receives no later frame.

Outside a system, use get[T](entity) to copy a statically selected component, edit the copy, and set(entity, copy) to persist it. query[T]() returns stable entity IDs, while has[T](entity) tests membership. add attaches a missing component. Invalid world operations remain runtime checks.

Systems run in linked source order, imported modules before their importers. Each system snapshots its matches at the start of its visit and traverses them by entity ID. Later systems see accepted changes from earlier systems; no systems run in parallel.

Edit exercise

Change the increment in Counter.advance from 1 to 2. After two steps, the inspected counter value should be 4; Finish should still invoke done once. Replace the frame callback’s dt: Number with dt: Bool and compilation should report the required lifecycle signature.

Initialization, actions, ticks, and finish are transactions. A failed operation rolls back component edits, globals, logs, entity IDs, and lifecycle membership. The language reference has the exact ordering and runtime rules; the built-in catalog documents ECS operations.