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(...).
const Position = Descriptor.Component<{ x: number; y: number }>()("Position")
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.
// Route raw component input through a constructor once at the boundary.
const Position = Descriptor.ConstructedComponent(Vector2)("Position")
Defines a component descriptor that snapshots skip.
Restored entities come back without it, so systems that need it rebuild it,
for example from an added(...) query.
const SpriteRef = Descriptor.TransientComponent<{ frame: number }>()("SpriteRef")
Defines a marker component: no data, only presence ([Player, {}]).
Tags validate on load like any constructed component, so they never block
snapshots.
const Player = Descriptor.Tag("Player")
const Enemy = Descriptor.Tag("Enemy")
Defines a state component: its value is one of states, validated (so
snapshots reject unknown states), and it behaves like any other component
(storage, change detection, rollback, traces).
With transitions, its write cell gains transition(from, to): the pair
is checked against the graph at compile time, and at runtime the move
happens only if the current state is still from, otherwise it returns a
StateMismatch failure. Transitions are ordinary component writes:
immediate, visible to later systems, rolled back with a failed system.
const Phase = Descriptor.State("Phase", ["ready", "windup", "active"] as const, {
transitions: { ready: ["windup"], windup: ["active", "ready"], active: ["ready"] }
})
// in a system with a write slot `phase`:
const moved = data.phase.transition("windup", "active") // "ready" -> "active" does not compile
Whether a descriptor was built with State.
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.
// Store shared world state once and request it explicitly from systems.
const Score = Descriptor.Resource<number>()("Score")
Defines a resource descriptor that also knows how to validate raw values.
Defines a resource descriptor that snapshots skip. Restoring keeps its
current value.
const DeltaTime = Descriptor.TransientResource<number>()("DeltaTime")
Defines an event descriptor.
Use event descriptors to model append-only messages flowing between systems
without exposing untyped channels.
Events are per-reader streams, like change detection: each reading system
sees the events published since its own previous run, once, in emission
order. A system's events are published when it completes successfully, so
later systems in the same schedule see them, and a failed system publishes
nothing. Events are kept until every system that reads them has run (see
Game.System.readEvent).
const Hit = Descriptor.Event<{ target: number; amount: number }>()("Hit")
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(...).
// Describe one host capability the runtime must provide.
const Logger = Descriptor.Service<{ log: (message: string) => void }>()("Logger")
Checks whether one descriptor is transient (skipped by snapshots).
Adapts a Standard Schema validator into a descriptor constructor, so any
compliant validation library can guard constructed components and
resources. Validation must be synchronous; a schema that returns a promise
fails with an issue instead.
const Position = Descriptor.ConstructedComponent(
Descriptor.fromStandardSchema(type({ x: "number", y: "number" }))
)("Position")
Returns the function that validates untrusted values for a constructed
descriptor: its constructor's decode when present, otherwise result.
The snapshot types only allow the result fallback when it accepts
unknown.
Checks whether one descriptor carries raw-construction metadata.
Returns the raw constructor carried by one descriptor when present.
Plain descriptors return undefined.