How-To: Publish and Play
Publish a world, enter Play, and handle the normal lifecycle: reconnecting after a dropped session and reloading after an edit. The thread running through every step is that the frontend is a non-authoritative projection — the runtime owns the session, and the client re-derives from authoritative state. You trust the backend receipt, never the client's local picture.
This page describes the canonical publish-and-Play flow for v1. The engine is pre-launch: its readiness rows are all unaccepted, and "publishable" or "playable" is a contract model here, not a guarantee that a given world runs end-to-end today. Status tracks the v1 readiness ledger.
Publishing is gated, not automatic
Publishing promotes a project graph to a deployment that a Play session can run against. It is not a copy step — it passes a gate first. The relevant surfaces:
- Script publish gate.
script_publish_gateruns the script publish-gate checks for a game and surfaces blockers before a deployment is created. Run it first; a script blocker should stop the publish, not the Play session. - Create the deployment.
runtime_create_deploymentpublishes a project graph as a deployment (action surfaces includedeployment.redeployto redeploy a content version anddeployment.rollbackto revert). These aremcp:admin/publish-domain operations — they are deliberately not in the everydaymcp:writeset. - Open a room.
runtime_create_roomcreates a Runtime room for a deployment; a Play session connects to that room.
Promoting state and passing the script gate is necessary, not sufficient. A scene that renders is not a game. Playability is a separate, runtime-proved property — camera, spawn, possession under a live session — and it is gated by the proof registry, not by a successful publish. See Reference: Runtime Playability.
The publish-and-Play recipe
- Run the publish gate. Call
script_publish_gatefor the game. Resolve any reported blockers before continuing — the gate exists to catch them before deployment, not after. - Publish a deployment. Promote the project graph with
runtime_create_deployment(action domainpublish). This produces the authoritative, version-pinned content a Play session runs against. - Enter Play. Open a Runtime room (
runtime_create_room) and connect. The runtime drives the session; the client renders a projection of authoritative state. It does not simulate independently. - Reconnect on drop. If the session drops, the client re-establishes the connection and re-syncs to the authoritative snapshot — it does not invent state to fill the gap. After reconnect, the client's view is whatever the snapshot says, not whatever it last believed.
- Reload after an edit. After authoring a change (a component edit, a script patch), reload the Play session so it runs against the latest published state. A live edit is not silently mixed into a running session; you re-derive from the new published content.
The frontend is non-authoritative — trust the receipt
None of these steps let the client become a second source of truth. Publish, Play, reconnect, and reload all re-derive from backend authority:
- Publish promotes authoritative state; the client does not "own" the published version.
- Play is runtime-driven; the client renders a projection.
- Reconnect re-syncs to the authoritative snapshot rather than reconstructing from local memory.
- Reload re-projects from the latest published content.
Treat publish and deployment results as receipts from the authority, not as confirmation of your local intent. Run script_publish_gate before runtime_create_deployment. After reconnect or reload, read current state from the runtime rather than assuming your last-sent change is live. Never narrate the client's local view as ground truth.
This is the same backend-authority discipline that governs editing — see Explanation: Backend Authority. The runtime, the publish gate, and the deployment lifecycle are owned by the server runtime modules (server/src/modules/runtime); there is no single generator for runtime playability, so its source of truth is those modules plus the readiness registries.
What "playable" formally means
In v1, a world is playable only when runtime evidence holds under a live session, and that evidence is recorded as a proof — not asserted in prose. The minimum runtime proof is camera, spawn, and possession under a live session, runnable via the runtime.proof.run action.
A playability claim requires runtime-driven camera, controlled-entity spawn, and possession (input bound to the controlled entity) demonstrated under a live session, backed by a registry receipt. A markdown description is not proof. Today every v1 readiness-ledger row is unaccepted, so this is a contract model, not a guarantee.
The readiness registries are the source of truth for what is proven: FEATURE_LEDGER.json, PROOF_REGISTRY.json, and the others under docs/cycles/v1-engine-readiness-loop/.
Related
- Reference: Runtime Playability — the playability criteria and the registries that gate them.
- Explanation: Playability Proofs — why proof, not prose, decides "playable".
- Explanation: Backend Authority — why reconnect and reload re-derive from authority.
- How-To: Use MCP Tools — the deployment and room tools used above.
Status: this page documents the canonical publish-and-Play flow for v1. The engine is pre-launch; "publishable" and "playable" are contract models whose end-to-end runnable status tracks the v1 readiness ledger.