Appearance
Drafts, hot reload and publishing
You'll learn: how you test changes on a live plot and ship updates without breaking anyone's game. You'll need this when: your plot has players.
Status: in the headless runtime, the draft lobby, hot swap, drain and live migration with automatic rollback are Built. The artifact store, the creator API, publishing from the app and the Create tab are Planned.
The draft lobby
Every plot has a private lobby called draft, for you and testers you invite. A new build hot-swaps there at once: your component's sandbox is replaced, init and onLobbyLoad run again, and state comes back from storage. Everyone else keeps playing the published version.
you save → build → draft lobby reloads (seconds) ← you and testers
publish → the draft becomes the published version ← everyone elsePublishing: the platform picks the safe path
Nobody is asked to choose an update strategy. The platform does what makes sense:
| Situation | What happens |
|---|---|
| A runtime with lobbies | drain: lobbies with players in them stay on the old version until they're empty; new lobbies get the new one |
| Otherwise | live migration: each package's onUpgrade(oldVersion) runs; if it throws, that package rolls back to the old version automatically |
| Several mods | updated one at a time |
ts
export function onUpgrade(oldVersion: string) {
// plot level: reshape stored data for the new version
if (oldVersion.startsWith("1.")) {
const scores = storage.getPlot<Record<string, number>>("scores") ?? {};
storage.setPlot("scores", { version: 2, byPlayer: scores });
}
}onUpgrade also runs when a lobby first runs on the new version after its players left, and when the plot starts from saved data of an older version. Keep it idempotent.
Where builds go (you don't need to export anything)
Built artifacts (your bundled code, assets, manifests) are content-addressed: named by a hash of their bytes, in our own artifact store. A plot's draft and its published version are each just a list of hashes, so a mod used by a thousand plots is stored once. Planned: the store, and the creator API that uploads to it.
You'll rarely touch files. When you want to share a package outside the store, build.mjs pack makes an .inv bundle (Built; see Tooling).
Versions
version in plot.json is semver. A lobby keeps the version it started with until its players have left. Older apps can still join: an app that can't run your client code joins without it, and player.runsPlotCode is false.
Next
The guides: Bedwars.