All pages

Rooms

room.json holds a room's settings, its rules, and every thing standing in it.

Each room is a folder under rooms/, named like the room, with a room.json and its script files.

room.json

{
  "id": "room:tpi_room_…",
  "name": "Skybound",
  "root": true,
  "width": 48, "height": 48,
  "view": "iso", "view_height": 1, "camera": "fit",
  "chat": "line", "watch": "off", "capacity": 8,
  "rules": [
    { "kind": "rounds", "seconds": 90, "min": 2, "countdown": 5, "results": 8 },
    { "kind": "winner", "by": "points" }
  ],
  "things": [
    { "id": "placed_…", "thing": "Guardian", "x": 24, "y": 20 },
    { "thing": "Skybound Sign", "x": 20, "y": 26, "bricks": [{ "kind": "sign", "text": "Strike the guardian." }] },
    { "thing": "Spawn Pad", "x": 24, "y": 30, "rotation": 90, "bricks": [{ "kind": "spawn", "team": "red" }] },
    { "door": "Belt Island", "x": 40, "y": 10 }
  ]
}

Settings

fieldvaluesmeaning
roottrue on one roomthe game's own room, where its door leads
width, height12 to 48the room in tiles
viewiso, topthe world's own view, or a board from above
view_height0, 1, 2seen from above: a plan, three-quarter, tall fronts
camerafit, followthe whole board, or the player
chatline, open, offEnter opens one line; the bar stays open; no chat
watchoff, quiet, openwhether a copy can be watched, and whether watchers talk
clicknear, anywherewhere a click on a thing counts from: beside it (a click from further walks there first), or from any tile at once
capacity1 to 1000people per copy

A room folder with no matching room on the server is created on push. A room on the server with no folder is left as it is, and the push says so.

Rules

rules is the list of bricks on the game for this room: rounds, winner, teams, lives, score, welcome. No rounds makes a hangout. Every brick and its fields: Bricks.

Things

Each entry in things is one placed thing:

fieldmeaning
thingthe name of a thing in the game's stock
doorinstead of thing: another room of the game; the door stands here
x, ythe tile
idwritten by a pull; a thing that keeps its id and its tile stays as it is, everything else is placed anew
bricksbricks on this one placed thing, on top of the thing's own
rotation0, 90, 180, 270
heightits lift, in voxels
looka filter: outline, inked, soft, flat, sticker, flat-ink, color-ink, soft-ink or chunky
hiddentrue for a thing a script shows later
statethe state it shows before a script sets another, one of the thing's own states; the Studio and renders show it too
taga name for this one placed thing, up to 32 characters; a script finds it with tagged("plot-3") and reads t.tag
versionwhich published version of the thing this one shows; without it, it shows the stock's (eggox stock use)
clickanywhere: this thing can be clicked from any tile, whatever the room's click

Any other field is refused, and the push names it. Things are placed in the order listed; a tile another thing already covers refuses, and the push names the entry.

Doors

A door is the room itself, standing in one place: {"door": "Hall"} in the root puts Hall's door there. Each room has one door, so it stands in one room only. There is no door back: leaving a room takes players out to where its door stands, and a script can send(p, "Room") to any room of the game. A door to the room it stands in, or to a room that holds this one (the root, from a room inside it), is refused.

A door wears the floor star. To dress the doors into a room as a thing from the stock: eggox entrance set "Moss Portal" --room Hall.

Size

A push that shrinks a room picks up the things it drops first, so shrinking and clearing the far side is one push. A thing that stays but would stand outside the new edge is named.

Script files

rooms/<Room>/<file>.lua are the room's files, each compiled as its own block, in name order (name them 1-main.lua, 2-shop.lua if it matters). Globals are shared between files and with the scripts on things. Up to 8 files of 16 KB each. A room with no .lua file has no script.

Shared code

Any other .lua file in the folder, outside rooms/ and things/, is a module every room can load with require:

-- shared/ui.lua
local M = {}
function M.coins(p, n) hud(p, "COINS", n) end
return M
-- rooms/Hub/main.lua
local ui = require("shared/ui")
on("enter", function(p) ui.coins(p, 0) end)

The name is the file's path without .lua, written as text in the call (require("shared/" .. x) is not followed). A module runs once per copy, the first time it is required, and what it returns is what every require of it gets. A room carries only the modules its code requires, and they count toward its script size. Rooms share the code, not the values: each copy runs its own. Up to 64 shared files.

This page as markdown, for you or your agent: /project/rooms.md