Skip to content

plot.json ​

Every package, the runtime and each mod, has its own plot.json beside its code; there's no single manifest for a plot. build.mjs and lint.mjs validate it and name every problem. The table is generated from plot/sdk/manifest.mjs by gen.mjs. Status: Built (validated, and used by the headless room and the plots dev stack).

json
{
  "kind": "runtime",
  "namespace": "bedwars",
  "id": "ana.bedwars",
  "version": "1.0.0",
  "name": "Bedwars",
  "apiVersion": 1,
  "code": "dist/logic.js",
  "stashItems": true,
  "lobbies": { "size": 16, "area": { "min": [0, 64, 0], "max": [16, 72, 16] } },
  "worldgen": { "generator": "void" },
  "tickRate": 20,
  "movement": "server",
  "channels": { "shop": { "reliable": true } },
  "assets": "assets",
  "rating": "everyone",
  "tags": ["pvp", "teams"]
}
FieldTypeRequired
kind"runtime" | "mod"yesA plot runs exactly one Runtime (none = the default Inventery runtime) and any number of Mods.
namespacestringyesThe namespace of this package's ids ("bedwars" makes "bedwars:bed"); "inventery" is the base game's.
dependsstring[]Package ids ("<owner>.<name>") this one needs; they load first.
worldgen{ generator: string; seed?: number; features?: string[] }Runtime only: the base world-gen recipe (a lobby is seed + edits)
id`${string}.${string}`yes"<owner>.<name>": lowercase letters, digits, _ and -.
versionstringyesSemver ("1.0.0"); onUpgrade(oldVersion) runs when it changes.
namestringyesShown by the trusted layer ("Typing to {name}", the "keep your items?" prompt)
apiVersion1yesThe host API version it was built for (1)
codestringruntimesThe module the room loads: "dist/logic.js" (built by sdk/build.mjs) or a raw-ABI ".wasm"; a data pack (a mod with no code) leaves it out.
stashItemsbooleanruntimesRuntime only. R6: true = the player's real items and body are set aside while they're inside.
lobbies{ size: number; area?: Box } | nullruntimesRuntime only. R3: players per lobby (the platform makes and fills lobbies) and the lobby area (relative to the plot's min corner); null = no lobbies (one shared lobby, "main")
tickRatenumber20 (default) to 60 Hz, within the CPU quota.
baseRules{ blocks?: boolean; pvp?: boolean; drops?: boolean; pickup?: boolean; hunger?: boolean; mobs?: boolean; chests?: boolean; furnaces?: boolean }Runtime only. The base game runs inside your plot by default and your hooks filter it; set a category false to own it yourself: blocks, pvp (only a player's hit on a player: falls, creatures, explosions and starving always hurt as the base does), drops and pickup (on, they run the world's own item pipeline in the lobby: base reach and delay, stack limits with the overflow left lying, the pickup sound, bob and spin, 5 minutes), hunger, mobs (entity types' ai and the base melee on plot entities), chests (the base chest screen on the lobby's own boxes), furnaces (the base furnace on the lobby's own furnaces, smelting on its own tick)
movement"server" | "client"Who owns player movement (default "server")
entryVec3Where soft deaths and Leave put you, relative to the plot's min corner (default: where you entered)
rollback{ relay?: ("move" | "look" | "buttons" | "action" | "pointer" | "aimRay")[] }Runtime only: opts in to the rollback relay (the lobby's inputs, only these fields, to its other players; default move, look, buttons). Every listed field is visible to every player.
channels{ [name: string]: { reliable: boolean; rate?: number } }Custom channels for game logic (never visuals)
assetsstringThe bundle folder (models, textures, sounds, levels), usually "assets".
content{ blocks?: unknown[]; props?: unknown[]; terrain?: unknown[] }Published static content (tier 1). content.terrain is Planned (see "glTF levels" in AGENTS.md)
registriesstringA folder of JSON definitions the host registers before any code runs: blocks.json (BlockDef[]), items.json (ItemDef[]), recipes.json (RecipeDef[]), entities.json (EntityTypeDef[]), structures.json (StructurePattern[]), worldgen.json (WorldgenFeature[]). A data pack is a mod with registries and no code.
ratingstringThe content rating.
tagsstring[]Search tags (MANIFEST lists them inside the rating entry)
models{ maxTris?: number; lods?: number[] }How the bundle's glTF models are served: decimated past maxTris (default 8000, at most 131072), far LODs at these fractions of the model (default [0.25], up to three, finest first)
water{ blend: "radial"; inner: number; outer: number; opacity?: number; edgeColor?: string }A model water surface's blend into the world's block water (register #117), for the plot's code to give its Material.blendWithBlockWater: the model's own water inside inner blocks of its centre, a smooth radial gradient to the block water at outer.
skySkyDefThe sky and light players see while inside the plot (register #116): { skybox?: an equirectangular PNG or JPEG in the bundle, top?, horizon?, fog?: colours, turn?: radians, fadeSeconds?, light?: { time?, sun?, sunStrength?, ambient? } }; onlookers outside keep the world's.
portalPortalDefThe plot portal's look (register #124): { title, subtitle?, line?: the feed card's line, titleFont?, subtitleFont?, titleColors?, subtitleColor? }; a published creator plot gets its destination portal built at its arrival spot, styled so.

Unknown fields are flagged (a typo like tickrate is caught). Coordinates in plot.json (entry, lobbies.area) are relative to the plot's min corner; host calls take world coordinates (world.bounds().min is the corner).

lobbies is all a plot declares about lobbies: their size, and optionally the area where a new lobby's players start. The platform makes, fills and suspends lobbies; see Lobbies.

baseRules (runtime only): leave it out and every base-rule category runs inside the plot. Set one false to own it yourself: { "blocks": false } (breaking and placing), pvp, drops, pickup, hunger. See Runtimes and mods.

A mod's plot.json is the small part of the same table: kind: "mod", namespace, id, version, name, apiVersion, code (or registries for a data pack), and depends when it needs a runtime or another mod (Bedwars: "depends": ["inventery.team-minigame"]). Runtime-only fields in a mod are flagged.