Runtime
Runtime
Runtime creation, world storage, and schedule execution.
The runtime is the concrete owner of the ECS world. It holds entities,
resources, relation graphs, machines, event buffers, lifecycle
buffers, and the host-provided services declared by systems.
This module is where the library's explicit execution model becomes real:
- systems never run without a runtime
- schedules are the only way world visibility advances
- service injection stays separate from world storage
- construction-time validation remains visible through result-returning APIs
Reach for this module when wiring the final game object that a browser loop,
server process, test, or custom engine adapter will actually execute.
Examples
// Provide the services systems declared in their specs.
const services = Game.Runtime.services(
Game.Runtime.service(RenderClock, { now: () => performance.now() }),
Game.Runtime.service(Random, { next: Math.random })
)
// Viewport is a constructed resource, so the runtime comes back as a Result.
const runtime = Game.Runtime.make({
services,
resources: {
viewport: { width: 800, height: 600 }
},
machines: Game.Runtime.machines(
Game.Runtime.machine(GameFlow, "Boot")
)
})
if (!runtime.ok) {
throw new Error("Invalid runtime bootstrap data")
}
// The runtime owns the world and executes explicit schedules.
runtime.value.tick(setupSchedule)
runtime.value.tick(updateSchedule)
Most entries one event, transition-event, relation-failure, removed, or
despawned stream keeps for readers that have not run yet. Past it the
oldest entries are dropped, and readers that missed them see
lagged() === true (or a missed read in the debug trace).
Creates a runtime for a fully built schema and a set of external services.
Resources owned by constructed descriptors take raw input and are validated
here; when any are provided the runtime comes back as a Result. Otherwise
the runtime is returned directly.
The runtime does not own the outer frame loop. It only owns ECS state plus
the host-provided services that systems are allowed to depend on.
const runtime = Game.Runtime.make({
services: Game.Runtime.services(
Game.Runtime.service(Logger, { log: console.log })
),
resources: { Score: 0 },
machines: Game.Runtime.machines(Game.Runtime.machine(Flow, "Menu"))
})
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.
// Bundle host capabilities once when building the runtime.
const services = Game.Runtime.services(
Game.Runtime.service(Logger, { log: console.log }),
Game.Runtime.service(Random, { next: Math.random })
)
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.
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".
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.
// Start the game in a known committed phase.
const machines = Game.Runtime.machines(
Game.Runtime.machine(GameFlow, "Menu")
)