How It Works
Deterministic authoring, schema-backed rollback, render mirrors, and transport boundaries.
Layer Model
- Game authoring:
defineGamemodules and performance-modestep(ctx)functions describe deterministic gameplay. - Canonical simulation: V0.2/V0.3 performance mode stores schema-backed plain records generated from
schemaScalar,schemaRecord, andschemaTable. - Rollback engine: The engine owns prediction, query logging, snapshots, hashes, rollback, replay, bootstrap, and recovery.
- Render mirror: The renderer reads
RenderMirrortables fed by bus messages. It does not own simulation state. - Runtime transport:
TrysteroTransportmoves peer messages in standalone browser demos; tests and embedded hosts can inject other transports.
Deterministic step(ctx)
A performance-mode step gets PerformanceModeEngineContext and should normally start with const world = ctx.world(). The same previous state, tick, participants, and routed inputs must always produce the same next state.
- Read state from schema rows through
world.get,world.all,world.spawn, andworld.destroy. - Read player intent through
world.input(playerId)orworld.query(...), which route through the rollback query system. - Use
world.tickandworld.dtfor tick metadata. - Do not read wall-clock time, browser globals, DOM state, renderer state, transport state, or ambient randomness.
Schema-Backed Performance Mode
Performance mode uses declared schemas instead of arbitrary object graphs. Rows are plain scalar records. Wrapper classes are temporary authoring handles over those records; they are not canonical state and never cross worker or transport boundaries.
The schema backend can cheaply produce snapshots, hashes, patches, and transfer payloads because every table and field is declared ahead of time. That is why V0.2/V0.3 examples start with schemaScalar, schemaRecord, and schemaTable.
Rollback and Queries
The engine predicts remote input, advances locally, and corrects when real input arrives. If a correction changes a recorded query result, the engine restores an earlier snapshot and replays to the present.
const input = world.input(playerId) || {};
if (input.left && !input.right) paddle.s.x -= 1;
Use input reads only where they affect simulation. In Pac-Man, the game queries direction at junctions and turn-around points rather than treating every button change as gameplay-relevant.
Render-Mirror Separation
Simulation writes canonical rows. The runtime publishes mirror.snapshot anchors and mirror.patch updates through bus messages. Render code reads the resulting RenderMirror projection and may create sprites, audio controllers, or view models locally.
The renderer must not mutate canonical state, read live backend wrappers, or decide authoritative gameplay. Rollback-safe one-shot events such as sound are emitted by simulation and consumed idempotently by presentation code.
Trystero Transport
Standalone browser demos use TrysteroTransport, a transport wrapper around Trystero peer rooms. It is isolated behind the transport interface so Node tests can inject deterministic fakes and embedded hosts can provide their own mesh.
V0.3 Buses and Workers
V0.3 bus managers, scheduled buses, runtime adapters, and workers are runtime infrastructure. They schedule ticks, move input batches, publish mirror anchors and patches, and select render sources. They are not a separate authoring API. Game code still uses defineGame or schema-backed step(ctx) plus ctx.world().
Which Mode Should I Use?
| Situation | Use |
|---|---|
| Starting a small game or integration | defineGame. |
| Need scalable rollback state, render mirrors, or worker/runtime separation | V0.2/V0.3 schema-backed performance mode. |
| Want transparent easy/proxy mode objects | Future/deferred work, not a current recommended path. |
Maintaining an older page built with new EasyMultiplayer | Legacy callback facade, only for compatibility. |
Working on BusManager, WorkerRenderHost, or scheduled buses | Runtime infrastructure. Do not expose it as gameplay authoring. |
State, Events, and Presentation
| Data | Owner | Rollback behavior |
|---|---|---|
| Canonical rows | Schema backend | Snapshotted, hashed, patched, transferred, and replayed. |
| One-shot events | Simulation emits; presentation consumes | Confirmed or cancelled through rollback-aware keys. |
| Sprites, audio handles, interpolation objects | Renderer | Derived from mirror data; never authoritative. |