Defines a system from an explicit spec and a typed implementation.
This is the public entrypoint for authoring systems. The implementation only
receives the capabilities declared in the spec, and the returned effect keeps
service dependencies tracked in the type system.
Use the string-name overload in normal code. The name is turned into an
internal ordering token automatically, so the system can participate in
schedule validation without extra user-authored identity plumbing.
Open system.System in the docs
Declares read-only access to a component in a query selection.
A required read slot is both a matching requirement and a typing decision:
the entity must have that component, and the resulting slot becomes a
ReadCell. Use this for data the system needs to inspect but must not
mutate.
Open query.read in the docs
Creates a resource-write declaration for a system spec.
Use this when the system owns mutation of one world-level singleton, such as
score, UI summaries, accumulated damage, or frame-local caches. Declaring it
here makes that authority visible in the system contract before the body is
read.
Open system.writeResource in the docs
Creates one explicit executable schedule from authored plan entries.
Open schedule.Schedule in the docs
Creates an explicit query specification.
Use this inside system specs instead of relying on callback parameter
inference. The resulting value drives both runtime execution and the derived
query result type.
A query spec is purely declarative. It does not access the world by itself;
systems receive QueryHandles derived from the spec. In practice this is
where you encode the exact shape of one gameplay iteration pass.
Open query.Query in the docs
Creates a resource-read declaration for a system spec.
Use this for world-level singleton data the system needs to observe but must
not mutate, such as delta time, score snapshots, configuration, or
aggregated frame input. The resulting context slot is a read-only
ReadCell.
Open system.readResource in the docs
Defines a resource descriptor.
Resources represent unique world-level values accessed through explicit
system specs.
Use resources for singleton world data such as counters, configuration,
global timers, camera summaries, or transient per-frame aggregates that
should not be duplicated across entities.
Open descriptor.Resource in the docs
Defines a component descriptor.
Use this when declaring per-entity data that should participate in queries
and typed entity proofs.
Components are the only descriptor kind that can be queried directly with
Game.Query.read(...), write(...), or optional(...).
Open descriptor.Component in the docs
Creates the successful branch of a Result.
Open Result.success in the docs
Declares that a system needs a service from the external runtime environment.
Use this for host capabilities that should not live in ECS world storage:
clocks, random generators, render bridges, audio sinks, persistence APIs,
or network clients. The matching implementation must be supplied when the
runtime is created with Game.Runtime.services(...).
Open system.service in the docs
Creates a schema fragment.
Fragments are the main composition unit for game modules. Use them to keep
each gameplay slice local, exportable, and mergeable without introducing
hidden registry mutation.
A fragment says "this subsystem contributes these components/resources/
events/states/relations", and nothing more. Binding and runtime assembly
happen later once the final application shape is known.
Open schema.fragment in the docs
Starts a staged entity definition and inserts multiple components at once.
This is the recommended authoring API for new entity drafts because it keeps
the exact proof typing without the visual noise of nested insert(...)
chains.
Reset and restart systems should prefer this helper when rebuilding world
content after a transition boundary, because it keeps respawn logic flat and
explicit.
This is also the normal bootstrap/setup path for initial world content:
build one typed draft with spawnWith(...), then queue it through
commands.spawn(...) and commit it later at the schedule's
applyDeferred() boundary.
When the same entity shape appears more than once, the normal scaling path
is to extract a small local draft factory that just returns
Game.Command.spawnWith(...). Keep spawning explicit through
commands.spawn(...).
Open command.spawnWith in the docs
Composes one or more fragments and returns one bound Game surface.
This is the canonical public schema entrypoint. Fragment composition and
schema binding happen together so the common path does not need a separate
intermediate built-schema value.
Use Game.schema when lower-level code still needs the final closed schema.
Open schema.bind in the docs
Creates a condition that only passes in one exact machine state.
Use this to gate systems or schedule entries by the committed gameplay phase.
If you need this kind of gating, the value should generally be modeled as a
finite-state machine rather than a plain state descriptor.
Open machine.inState in the docs
Creates the failed branch of a Result.
Open Result.failure in the docs
Creates an explicit command-application marker step.
Systems before this marker can enqueue commands. Systems after it see the
fully applied world changes.
This is the normal boundary between setup/simulation work and any later
system that depends on spawned entities, inserted components, or queued
despawns becoming visible in the current schedule.
Open schedule.applyDeferred in the docs
Builds the descriptor-backed runtime service environment.
This is the runtime-side counterpart to Game.System.service(...). Use it
to assemble the host implementations the game exposes to systems, such as
clocks, random generators, render bridges, audio sinks, or network clients.
The helper keeps the runtime map keyed by service descriptors instead of
ad hoc strings, so the provision site cannot drift from the declaration site.
Open runtime.services in the docs
Declares writable access to a component in a query selection.
Use this when the system is responsible for mutating component state in
place. A write slot both requires component presence and exposes the slot as
a WriteCell, so mutation capability stays visible in the query spec rather
than appearing ad hoc in the loop body.
Open query.write in the docs
Creates an opaque entity id from a runtime integer id.
This is a low-level constructor used by the runtime and command system.
The value it stores is the stable per-runtime numeric identity exposed on
EntityId.
Open entity.makeEntityId in the docs
Converts a current runtime id into an intent-qualified durable handle.
The extra intent does not prove the entity still has that component later.
It only forces resolution through a query that statically proves the
component is present.
This is the safer default when the handle will later be used in gameplay
logic that assumes a specific role, such as "player", "camera target", or
"damage source".
Open entity.handleAs in the docs
Creates an explicit lifecycle update marker step.
This commits readable added, changed, removed, and despawned
lifecycle buffers for later systems in the same schedule.
This is the required boundary before lifecycle-driven host sync. Systems
using Game.Query.added(...), Game.Query.changed(...),
Game.System.readRemoved(...), or Game.System.readDespawned() only observe
the current schedule's structural changes after this marker. extend
is the preferred wrapper when the host slice is just a prefix or suffix
around a headless gameplay schedule.
Open schedule.updateLifecycle in the docs
Creates one service provision for Runtime.services(...).
Use this at the runtime assembly boundary to pair a service descriptor with
its concrete host implementation. Passing the descriptor first keeps the
implementation object contextually typed and makes the dependency relation
obvious in docs and code review.
Open runtime.service in the docs
Creates an explicit machine-transition application marker step.
Queued machine writes are committed only at this boundary. If a transition
bundle is provided, matching enter/exit/transition schedules run as part of
the same boundary.
This is the canonical restart/reset boundary: queue the next phase with
Game.System.nextState(...), then let applyStateTransitions(...) commit
the new current state and run any attached reset schedules.
Open schedule.applyStateTransitions in the docs
Creates a typed component entry.
Use this when building drafts through the flat variadic helpers and you want
the component/value pairing to stay visually explicit. It is especially
useful once entries come from small factories or conditional branches rather
than inline tuple literals.
Open command.entry in the docs
Defines a service descriptor.
Services are the dependency-injection side of the system model, similar to
Effect environment entries.
Use them for capabilities owned by the host instead of the ECS world:
clocks, random sources, render/audio bridges, storage, or network clients.
Systems request them explicitly with Game.System.service(...), and the
runtime provides them through Game.Runtime.services(...).
Open descriptor.Service in the docs
No description provided yet.
Open schema.Feature in the docs
Validates one reusable authored value through an existing constructor.
Use this for one named authored constant that should cross a constructor
boundary now and remain in carried form afterward.
Open Definition.entry in the docs
Declares maybe-present read-only access to a component in a query
specification.
optional(...) is for enrichment, not matching. It keeps the entity set
broad while letting one system opportunistically read extra data when
present. The returned cell forces an explicit present check before use, so
the possibility of absence remains visible in the type surface.
Open query.optional in the docs
Stages one outgoing relation edge on an entity draft.
Drafts stay pure: this only records intent so the runtime can attempt to
attach the relation when the spawn command is flushed.
Open command.relate in the docs
Creates one explicit root token for schema-bound long-lived references.
Root tokens exist before schema construction so durable entity handles can be
stored in descriptor payload types without widening to Schema.Any.
Use one root token for the whole application. Anything created from
Schema.bind(Core, Root) will carry the same hidden root brand.
Open schema.defineRoot in the docs
Declares queued write access to the next value of a finite-state machine.
This is the system-side request channel for a future phase change. It does
not immediately switch the committed state; the queued value is applied only
at an explicit Game.Schedule.applyStateTransitions(...) boundary.
Use this instead of writeState(...) when the transition timing itself is
part of the gameplay model, such as restarting a round, leaving a menu, or
entering a results screen after reset/setup schedules run.
Open system.nextState in the docs
Declares a lifecycle filter that matches components written since the last
lifecycle boundary.
This depends on the readable lifecycle buffer, so it only changes after an
explicit Game.Schedule.updateLifecycle() boundary.
Use this for narrow host-sync passes after initial creation, for example one
transform-sync system that should only touch entities whose position changed
since the last lifecycle boundary. added is the matching
creation-side lifecycle filter.
Open query.changed in the docs
Creates one machine initialization provision.
This is the machine-side equivalent of Runtime.service(...): it pairs one
machine definition with the committed initial value the runtime should start
from before any transition schedule runs.
Open runtime.machine in the docs
Creates a typed reusable transition bundle.
Use bundles to group multiple machine transition schedules and then attach
them to one applyStateTransitions(...) marker.
Open schedule.transitions in the docs
Lifts a validated result into a typed component entry result.
This is the bridge between constructor-first validation and command
authoring: validate a value separately, then preserve that success/failure
shape while turning it into an entry for spawnWithResult(...) or
spawnWithMixed(...).
Open command.entryResult in the docs
Creates a schema-bound finite-state machine definition.
This is the intended default for gameplay phases and other discrete modes
where the transition boundary itself matters.
Prefer a machine over Descriptor.State(...) when code depends on:
- queued nextState(...) writes
- explicit applyStateTransitions(...)
- inState(...) gating
- transition events or enter/exit schedules
Open machine.StateMachine in the docs
Creates an explicit event/message update marker step.
Systems before this marker can write events. Systems after it read the
committed readable event buffers for the current schedule execution.
Use this when a later system in the same schedule should observe events that
earlier systems just emitted. If those event payloads carry entity handles,
later systems should re-resolve them through lookup.getHandle(...) after
this marker.
Open schedule.updateEvents in the docs
Creates an application facade on top of an existing runtime.
Use this at the integration boundary when you want a stable "app" object
for a browser host, test harness, or engine adapter, but you do not want to
hide the fact that schedules still drive everything underneath.
bootstrap(...) remains a direct alias of runtime.initialize(...), and
update(...) remains a direct alias of runtime.tick(...). The wrapper is
ergonomic, not semantic.
Open app.makeApp in the docs
Declares a lifecycle filter that matches newly added components.
This depends on the readable lifecycle buffer, so it only changes after an
explicit Game.Schedule.updateLifecycle() boundary.
This is the usual entrypoint for incremental host sync: create host-owned
nodes only after lifecycle visibility has been advanced for the current
schedule. changed complements this for later update passes.
Open query.added in the docs
Builds the machine initialization environment from machine definitions.
Use this when gameplay phases need a known committed starting state before
any schedule runs, for example "Boot", "Menu", or "Playing".
Open runtime.machines in the docs
Starts a staged entity definition from a mix of plain validated entries and
explicit result-wrapped entries.
This is the practical "normal game code" helper when some components are
already valid and others must cross a constructor boundary first. It keeps
the whole spawn path flat while still refusing to hide validation failure.
Open command.spawnWithMixed in the docs
Creates a typed component entry by validating raw input through a
constructed descriptor.
Use this when spawn or reset data starts as raw numbers, vectors, sizes, or
other host/authored input and you want the command path itself to surface
validation failure explicitly.
Open command.entryRaw in the docs
Declares read access to the current committed value of a finite-state machine.
Use this when gameplay logic needs to branch on the current committed phase,
but should not see queued next-state writes early. Machines are the intended
default for menus, rounds, encounters, pause flows, and other discrete modes
whose transition boundary matters.
Open system.machine in the docs
Declares read access to relation-mutation failure records.
Open system.readRelationFailures in the docs
Declares read access to despawned-entity lifecycle records.
This reads the committed despawn buffer after Game.Schedule.updateLifecycle().
Use it when host-owned state must be destroyed even if no single removed
component is the canonical trigger. readRemoved is often used
alongside this in authoritative host mirrors.
Open system.readDespawned in the docs
Validates a named record of reusable authored values at once.
Successful entries are returned under the same keys. Failed entries remain
keyed so authored-data setup can report exactly which constant was invalid.
Use this when one content bundle or level definition should either validate
as a whole or report a structured set of authoring failures.
Open Definition.all in the docs
Defines a component descriptor that also knows how to validate raw values.
Use this when the component should never exist in the world in an unvalidated
shape, for example vectors, sizes, collider bounds, or other branded domain
values.
Open descriptor.ConstructedComponent in the docs
Declares read access to removed-component lifecycle records.
This reads the committed lifecycle buffer, not immediate removals. Systems
usually pair this with Game.Schedule.updateLifecycle() and host cleanup
logic such as removing renderer-owned nodes. readDespawned
complements this for whole-entity teardown.
Open system.readRemoved in the docs
Defines an event descriptor.
Use event descriptors to model append-only messages flowing between systems
without exposing untyped channels.
Writers emit into a pending buffer. Readers observe only the committed
readable buffer after an explicit Game.Schedule.updateEvents() boundary.
Open descriptor.Event in the docs
Converts a current runtime id into an unqualified durable handle.
Use this when you need a long-lived reference but do not want to assert any
intended component role. Resolve it later with lookup.getHandle(...).
The handle is storage-safe, not a proof of liveness. The entity may have
been despawned by the time it is resolved.
Open entity.handle in the docs
Defines a resource descriptor that also knows how to validate raw values.
Open descriptor.ConstructedResource in the docs
Aggregates several independent results into one explicit result.
Tuple input preserves tuple ordering in both success and failure shapes.
Record input preserves the original keys.
The first failure stays explicit in the returned error structure rather than
throwing or silently dropping invalid entries.
Open Result.all in the docs
Folds one Result into a plain value.
Use this when you are leaving the Result shape and want one explicit place
to handle both branches.
Open Result.match in the docs
Creates an event-write declaration for a system spec.
Event writes append to the pending event buffer. They are not visible to
readers in the same schedule phase until Game.Schedule.updateEvents().
If the payload needs to name an entity for later work, emit a durable
Game.Entity.handle(...) or Game.Entity.handleAs(...) and let the later
reader re-resolve it through lookup.getHandle(...) after the event buffer
is committed.
Open system.writeEvent in the docs
Defines a state descriptor.
States are singleton schema values with no queued transition semantics.
Use this when you need one current world-level value and the boundary of
changing that value is not itself meaningful. If gameplay logic depends on
queued transitions, enter/exit handling, or inState(...) gating, prefer
Game.StateMachine(...) instead.
Open descriptor.State in the docs
Requires at least one child condition to pass.
Open machine.or in the docs
Creates an explicit relation-failure update marker step.
Deferred relation mutation failures become readable only after this marker.
Open schedule.updateRelationFailures in the docs
Declares read access to committed transition events for one machine.
Transition events are committed together with normal events and become
readable only after Game.Schedule.updateEvents().
This is one of the clearest signs that the modeled value should be a machine
rather than a plain state descriptor.
Open system.readTransitionEvent in the docs
Requires every child condition to pass.
Open machine.and in the docs
Creates a reusable explicit schedule fragment.
Fragments are the only reusable authoring unit for explicit schedules.
They can contain systems, explicit boundary markers, and nested fragments.
Open schedule.fragment in the docs
Creates an event-read declaration for a system spec.
Event reads observe the committed readable event buffer. New writes become
visible only after an explicit Game.Schedule.updateEvents() boundary.
This is the usual second half of a deferred cross-system flow: one earlier
system emits an event, updateEvents() commits the buffer, and a later
system reads those events and re-validates any handles or lookups it needs.
Open system.readEvent in the docs
Defines a state descriptor that also knows how to validate raw values.
Open descriptor.ConstructedState in the docs
Defines the canonical parent/children relationship pair.
The returned relation is the source-of-truth edge component, while
related is the reverse collection maintained by the runtime.
Use hierarchy when the relationship must support ordered children,
ancestor/descendant traversal, and linked recursive despawn.
Open descriptor.Hierarchy in the docs
Creates a typed entity draft from an id and a proof.
Open entity.draft in the docs
Creates a condition that passes when the machine changed during the current schedule execution.
Open machine.stateChanged in the docs
Inserts one raw component value into a draft through a constructed
descriptor.
Open command.insertRaw in the docs
No description provided yet.
Open command.spawnWithResult in the docs
Defines a general relationship pair with direct edges and reverse lookups.
Use a general relation when you need direct source -> target edges plus
reverse lookup, but not hierarchy-only behavior such as tree traversal or
child reordering.
Open descriptor.Relation in the docs
Creates a read-only entity proof value.
Open entity.ref in the docs
Creates a mutable entity proof value.
Open entity.mut in the docs
Creates a reusable explicit schedule phase.
Use this for repeated explicit step slices such as host-sync tails or other
lifecycle-driven suffixes that should stay visible in authored schedules.
Open schedule.phase in the docs
Starts a staged entity definition.
Use this inside a system to build an entity with an exact compile-time
component proof before the spawn command is queued.
Open command.spawn in the docs
Builds one final executable schedule from explicit entries.
build(...) is the only final schedule constructor. Systems are derived
from the authored plan and kept in that exact order.
Open schedule.build in the docs
Flattens mixed schedule entries into one { systems, steps } pair.
This is the preferred way to compose systems, markers, and reusable phases
without manually keeping systems and steps in sync.
Open schedule.compose in the docs
Merges two schema fragments into a larger closed schema.
Duplicate keys are rejected both at the type level and at runtime so schema
composition stays predictable.
Open schema.merge in the docs
Creates a state-read declaration for a system spec.
Plain states are just singleton schema values. They do not have queued
transition semantics, transition events, or enter/exit boundaries.
If the behavior depends on when a mode change commits, prefer
machine(...) / nextState(...) on a Game.StateMachine(...)
machine instead.
Open system.readState in the docs