DocsLayout & seats

Layout

A zone says what a region means and how its contents behave — but not where it is. That lives in layout. The layout block holds two things: the seats around the table, and a placement for every zone — its position and size on the felt.

Layout is deliberately kept separate from the zone definitions. Zones carry meaning; layout carries geometry. Because they’re separate, your hand-tuned positions survive regeneration — re-running the pipeline can rewrite a zone’s role or contents without throwing away where you placed it.

Every coordinate here is in abstract table units, with the table origin at its centre. The renderer fits the table to the viewport, so only the ratios between things matter — pixel scaling happens at render time.

The table

The surface itself has a shape (round, rectangular, or custom), a size (in table units), and an optional surfaceAsset — a felt or board image painted across the whole table. An optional viewMode controls how the scene orients for each player: fixed (default when omitted) locks the board upright for all players; seated rotates the scene so the viewer's seat faces the near edge — use it for directional board games where territory or orientation matters.

What a placement holds

Each zone has exactly one entry in layout.zones, keyed by zone id:

FieldTypeMeaning
spacetable | seatLocaltable = absolute table coordinates; seatLocal = relative to a seat, with one copy instantiated per seat, rotated to that seat
x / ynumber (table units)Position of the zone box (origin = table centre)
w / hnumber (table units)Zone box width and height (both positive)
rotationnumber .optional()Box rotation in degrees
layernumber .optional()Draw order when zones overlap
fitContentsboolean .optional()Scale contents to fill the box. Default lets the renderer pick: card zones fit, piece/dice/token trays don’t. Set true for a single-component zone you want to resize by resizing the box
lockedboolean .optional()Designer-only: the editor ignores the box’s own click/drag (handy for a big background board) — contents stay interactive; ignored at runtime
bySeatrecord .optional()seatLocal zones only: per-seat geometry overrides keyed by seat index. A seat with no entry uses the base geometry, so the zone stays symmetric until you reposition one seat

How to edit in the Studio

Open your game → Layout tab. The table is drawn to scale; drag a zone to move it, drag its handles to resize, and use the Zone inspector to set rotation, layer, fitContents, and lock. Switching a zone to seatLocal space mirrors it to every seat at once; nudging one seat’s copy writes a bySeat override for just that seat. The Table inspector sets the surface shape, size, and image. For a full tour of the canvas, panels, and gestures, see the Layout Editor.

Arranging several zones

The editor snaps, aligns, and matches zones for you — marquee-select a group, then align, distribute, or Match their sizes. See arranging zones on the felt for the full gesture set.

Already have a set of zones that drifted out of line — a tableau of slots, a row of supply piles? Ask Pip to arrange or even out them: it reads where each zone currently sits, works out the tidy positions (lining up rows and columns, evening the gaps), and proposes the moves (positions only — sizes stay as you set them), which you review and Save like any edit.

Sign in to ask Pip about building games.
Sign in