Reference4 min read4 sections

Native simulation recovery

docs/RUNTIME_RECOVERY.mdSource updated 2026-10-25
Markdown
On this page 4 sections

On codex/engine-foundations, a stalled or faulted simulation worker can recover without reloading the player page. Finding your place keeps input released while a replacement restores the latest sealed native checkpoint, reconstructs presentation and rejoins the room. After a verified frame and room baseline, the pause menu lets the traveler continue.

#Recovery point and ownership

The main thread requests a native checkpoint at most once every two seconds, with one pending capture and one retained point. A pending request expires after ten seconds. Captures run between simulation callbacks; hashing seals an owned snapshot while normal play continues. The existing 16 MiB checkpoint limit applies. Unavailable captures retain the previous sealed point and expose a diagnostic issue.

The point includes native Rapier physics, player state, authored entities and revisions, scheduler tick, input, routes, event state and content/schema fingerprints. It retains the matching source world and development document identity. It is kept only in page memory. Ordinary local-storage saves remain lightweight journey saves; this change does not make native checkpoints durable across reloads, browser termination or machine failure.

Generation checks fence messages and asynchronous replies from retired workers. A new simulation owns a new presentation channel and transfer epoch. The old simulation is terminated before that channel is disconnected and its reader reset; the canvas stays with its existing graphics owner. A fresh renderer accepts the new baseline, and a completed frame is required before recovery succeeds. Both main-thread and worker render placement use this path.

#Restoring and rejoining

The replacement verifies checkpoint hashes, engine/profile, schema, compiled content and native/ECS coherence before accepting it. Restored input is cleared. Solo physics stays held at the restored point until Continue. Shared play resumes its normal paused-world updates once the room reconnects, so routes and other travelers continue with the authoritative clock. Platform reconciliation preserves motor velocity, grounded/jump state, controller settings and existing rider support while adopting the authoritative platform poses. An interrupted NPC conversation is ended instead of renewing a hidden dialogue lease.

A valid existing room token retains traveler identity. Relay-acknowledged progress is reapplied from the new baseline; pending interactions from the retired worker are not blindly replayed. A development room loads its accepted document, restores against the checkpoint's source, then uses the existing compatible-revision preparation/fork path when the documents differ. Preparation failure leaves the durable local save available. It never silently substitutes a fresh journey for an incompatible native point.

Recovery waits for simulation readiness, shared-room connection when applicable, completion of any revision preparation, a presentation baseline and successful frame verification. The UI returns to the pause menu with no held movement. Open dialogue/chat panels are closed. Successful recovery updates the ordinary on-device save to the recovered and reconciled state.

#Bounds and fallback

  • Two replacement attempts are permitted per page session. Each has a 45-second deadline; a failed attempt goes directly to manual retry.
  • Startup, absence of a native point, overlapping graphics recovery, invalid checkpoints and failed replacement resources use the existing Try again path.
  • During recovery, intermediate states do not overwrite the durable local save. Failure terminates the replacement and retires its graphics resources. Page disposal cancels the operation and fences late completion.
  • The watchdog detects a blocked worker event loop independently of rendering receipts. Hidden tabs suspend monitoring, and a long gap in the main-thread observer grants a new probe deadline. Neither this watchdog nor the recovery timer can interrupt a blocked main thread.

The retained native point can predate the latest local autosave. Automatic recovery rolls back local movement and solo actions since that point; shared acknowledged state is reconciled from the relay. The two-second request cadence is not a guaranteed maximum rollback interval if capture is unavailable or the browser suspends execution. There is no behavior-level transaction rollback, execution budget, parked-script policy or untrusted-code isolation yet.

#Testing and diagnostics

With Node 22 and the project's Playwright browser available:

Terminal
npm run test:browser:simulation-recovery
npm run test:browser:development-recovery

The harness builds isolated production assets and temporary relay storage. It injects faults only into its own workers. Native tests require exact airborne position, velocity and tick restoration, plus continued identity and shared mutations. Other checks cover corrupted native points, the retry budget, absent native points, withheld UI frames/receipts, restoration into a newer accepted document and an actual stall during revision preparation followed by successful Apply.

Export playtest report includes simulationRecovery, simulationCheckpoint and simulationWatchdog metadata: attempt/status counters, checkpoint tick, receipt time, capture duration and capture issues. It does not export the native payload or room token. Acceptance evidence records the checked build and scoped results. Software-rendered browser evidence does not close physical-device performance, multi-machine or long-soak gates.

End of Runtime recovery