Architecture
Play uses a Worker-first architecture to keep MuJoCo/WASM work off the main thread.
Dataflow
+-------------------------------+ postMessage +------------------------------+
| Main thread | <------------------> | Worker (MuJoCo + forge) |
| | | |
| - UI panels (Simulate-style) | commands/events | - loads dist/<ver>/mujoco.js |
| - Plugin host API | ------------------> | - runs mujoco.wasm |
| - Three.js renderer | <------------------ | - emits snapshots (typed arr)|
| | | |
+-------------------------------+ +------------------------------+
Key boundaries
Worker backend:
Runs MuJoCo and holds the WASM module instance.
Owns the authoritative simulation state.
Emits snapshot events (often containing TypedArray views).
Main thread:
Owns UI state (panels, overlays, section collapse state, etc).
Renders the 3D scene from snapshots.
Hosts plugins.
Plugins:
Run on the main thread.
Must not assume direct access to WASM exports in Worker mode.
Interact with the simulation via
host.backendand snapshot streams.
Lifecycle
Page loads → main module initializes state and UI.
Main spawns the Worker and subscribes to Worker events.
Worker loads forge
dist/<ver>/(mujoco.js+mujoco.wasm) and validates required viewer ABI exports.Worker emits
ready→ main thread finishes UI wiring and rendering.During runtime: - main thread sends commands (run/pause, set fields/options, gestures) - worker emits snapshots and metadata events
For the authoritative command/event list, see Worker message protocol.