Dicey Table

Workflows

Assigning a Room or Table

How a game picks the published room and table packs it uses, why the pick is pinned to an exact version, and why nobody can change either mid-session.

On this page12 sections

A room and a table are not part of your game's scene document. They are published packs — each with its own repository, its own versions and its own author — and your game holds a reference to one of each.

That is why the Game Editor shows one Room row and one Table row instead of a floor, a ceiling, four walls, their posters and a light list. Composition and construction are different jobs, done in different editors.

Open the Game Editor#

Go to /editor/game/{id}, or open the mod and use Mod ▸ Open In ▸ Game Editor in the menu bar. (It reloads the page, so unsaved changes are confirmed first.)

The Hierarchy collapses to four rows:

Room          Noir Parlour 1.2.0
Table         Hex Wargame 2.0.1
Player Zones (10)
Entities (14)

Nothing was deleted. If your scene has hand-edited room internals — an extra light, a poster, a moved wall — every byte of it is still there. Only the rows are hidden, and the Room Editor is the way back to them.

Where a new game's room and table come from#

The create dialog asks. After you choose that you are making a Game, the next step offers a Room and a Table, and both are real assignments — they are written into your game's setup.json as ordinary pins, exactly as if you had assigned them from the rows below, and every player gets them.

Leaving either on its Default option is a real answer, not a blank: a new game with no room pick is pinned to Modern Room, and one with no table pick to Square Table — the platform defaults (see The platform defaults). Nothing here is permanent — the rows below change either one in a click.

The same step appears for a room, table or asset pack, but it means something different there: those kinds cannot assign packs at all, so their picks are previews, remembered in your editor workspace and never published. See Preview and Photo Mode.

The assign inspector#

Click Room or Table. The Inspector shows what is assigned:

  • the pack's cover, name and author;
  • its pinned version, and the commit that version resolved to;
  • its licence;
  • Change… / Remove, two ways to open the pack's own editor, and the two content-move buttons described under Moving content in and out of a pack.

With no pin the inspector reads Default — no room/table pack is assigned, so every peer uses the platform default, Modern Room/Square Table — and the Hierarchy row reads (default: Modern Room) or (default: Square Table). It is a normal state rather than an empty slot, and Remove always gets you back to it in one click.

The viewport shows the table you assigned#

Assigning, bumping or removing a table re-reads the pinned pack's document and rebuilds the table in the viewport — its model, its colliders and its play surface — so what you author on is what your players will get. The pack is read at the pinned commit, not at whatever is on its branch today.

If that document cannot be read — the pack is gone, the version is missing, the file is malformed — the table is refused and named, and the editor does not quietly put a default table in its place. Object positions are authored against the play surface, so a viewport guessing a height you have not assigned would write positions no player ever sees into your mod.

The viewport shows the room you assigned, too#

The same is true of a room, and it replaces more than the walls. Assigning one swaps the whole room the viewport renders: its floor, ceiling and walls with their materials and posters, its lights, its openings, its static scenery (the pack's decor placements), and the environment fields a room owns — the skybox, the fog and the ambient light. The room you authored in this project is not used while a pack is assigned.

Nothing is migrated or destroyed: your own room stays in the document exactly as you left it. It does not come back when you Remove the assignment, though — with no pin the game plays in the default room, Modern Room.

A room that cannot be read behaves differently from a table that cannot be read, on purpose: the room degrades. You are told which pack failed and why, and the editor falls back to the room authored in your project so you still have a viewport you can work in. Nothing in a room moves a drag target, so there is nothing here that could write a wrong number into your mod — which is exactly why the table refuses instead.

The two Table Surface environment fields are not the room's. A room owns the sky, the fog and the ambient; the table owns how its own play surface looks. One writer per field.

A room pack's scenery brings its own materials and textures with it, and it needs to. Model import strips a GLB's embedded images out into separate files, so an imported model's textures are re-attached from its <model>.meta.json sidecar, which names materials from the pack's own library by id. Both the pack's library and its sidecars are loaded alongside the room — you do not have to copy anything into your project, and a model that ships no sidecar simply keeps the materials it was exported with.

Choosing a pack#

Change… opens the picker. It lists every published pack of the right type — a room picker never shows a table pack, and neither ever shows a whole game — with Default always first. Its card reads Modern Room, the platform default (or Square Table, the platform default), and its button Use the default room / Use the default table clears the pin.

Every card carries the licence. That is deliberate: your game's listing credits the packs it uses automatically, so the picker is where you learn what you are agreeing to. Before you can apply a pack you tick an acknowledgement naming its licence and its author.

DiceyTable does not check whether one licence is compatible with another. A machine verdict on licence compatibility would be confident and often wrong, and every file involved is public on GitHub either way. The licence is shown, prominently, and the judgement is yours.

The platform defaults: Modern Room and Square Table#

DiceyTable has no built-in room or table of its own any more. A game that assigns no room plays in Modern Room (modern-room 1.0.2), and one that assigns no table plays at Square Table (square-table 0.1.6). Both are ordinary published packs, pinned to an exact version and commit like any assignment, so every peer resolves the same bytes. A blank table — /table with no room and no game — loads the same two.

You will rarely see a game without the pins, because the editor writes them in for you:

  • New games are created pinned to Modern Room and Square Table.
  • Opening an older game that pins neither shows the defaults in the viewport straight away. The pins are saved with your next save; opening alone does not mark the project as changed.
  • At play time and in the preview, a game with no pin gets the same defaults on every peer.

Older games are lifted onto Square Table. A game that never assigned a table was laid out on the old built-in table, whose play surface was at y = -0.02. Square Table's is at y = 2.0723, 2.09 ft higher, so the pieces are moved up by exactly that difference — the same straight-up move the editor offers when you change the table. Only what the old table was holding up moves: anything at or above its surface and inside its 5.46 × 2.88 ft footprint, with the seat ring, snap points, snap-point grids and table zones carried along. Floor and room content stays where it is.

The built-in Dining Table#

The Table picker always lists one pack that is not published by anyone: Dining Table, by DiceyTable. It is an oak table at a real dining table's height - the play surface sits at y = 1.5, 2.45 ft above the floor (Square Table's is at y = 2.0723).

It behaves like any other table pack - a pin to an exact version (diceytable.dining-table 1.0.0), shown in the Table row and removable in one click - with three differences:

  • It ships with DiceyTable. Its document and model are served by the app itself, so it needs no registry, no GitHub and no network. There is no licence to acknowledge, and it is never "unavailable".
  • Its collider runs from the play surface to the floor, so nothing slides under the table.
  • A version never changes. If DiceyTable ever ships a different height it will be a new version you choose to move to; a game pinned to 1.0.0 keeps exactly this table.

New games no longer start on it - they start on Square Table - but a game that pins it keeps it, because every position in a game is an absolute height against the table it was authored on.

To move a game onto it:

  1. Open the game in the Game Editor and click the Table row.
  2. Change… → Dining Table → Use this table.
  3. Read the preview that appears under the row: it lists every piece and the height it moves to (-0.57 ft coming from Square Table), and moves your seat ring by the same amount.
  4. Apply to switch the table and move them in one step - or Cancel to keep the table you have, with every piece exactly where it was.

To go back, Remove the assignment: that returns to the default table, Square Table, and offers the opposite move.

Pins, and why there are no version ranges#

An assignment names one exact version — 1.2.0, never ^1.2.0 or 1.x.

A range would make your table non-reproducible: two players who resolved it a week apart could be running different builds of the same room, and for a table that is not cosmetic — the table supplies the play-surface height every peer computes drag targets against.

So a pin never moves on its own. When a newer version exists, the inspector says so and offers a button:

(i) 1.3.0 is available.   [ Update pin to 1.3.0 ]

Until you press it, your game keeps using the version you chose. A published version is immutable — the label can never be re-pointed at different content — so a pin you made last month still means exactly what it meant then.

If a pinned pack disappears from the registry the row is badged unavailable and the inspector names the id that failed. The pin is kept, and the game cannot load that room or table until the pack is published again or you assign another. Silently swapping in the default would hide a problem you need to know about.

"Unavailable" is only ever said when the registry actually answered. If the list of published packs could not be loaded at all — you are offline, or the API is having a moment — the inspector says so instead, with a Try again button, and your pin is shown exactly as you saved it:

Could not load published packs. This pin has not been checked — it is shown exactly as saved, and nothing has been changed.

That is a different message on purpose. A failed request is not evidence that anybody's pack was unpublished, and a red "your pin is broken" warning raised by a dropped connection would send you looking for a problem that does not exist.

Two ways to open the pack's own editor#

Both are on the assign inspector, and they do different things:

  • Open Room pack / Table pack tab — an in-app editor tab, alongside your model and script tabs. No reload, no re-authentication, and your unsaved work in this project is untouched. It is the fuller view of the assignment: cover, summary, licence, pin, and the same controls.
  • Open in Room Editor / Table Editor — a browser tab, on the pack's own project.

The second one is only available for a pack that is one of your projects. Someone else's published pack cannot be edited here at all; fork its repository to make your own version.

Why a browser tab and not an in-app one? Each mod has its own local file tree, and one editor tab owns one tree. The pack is a different mod, so editing it means a second tab on a different tree — never a second view of the game you have open. Two tabs on one tree cannot both save; see One mod, one writing tab.

Moving content in and out of a pack#

Two buttons on the assign inspector move content between your game and a pack. They are two ends of the same operation, and both show you exactly what will and will not come along before anything changes.

Extract to a pack#

Available only when the row has no pin — the button is disabled while a pack is assigned, and opening a game pins the defaults, so Remove the assignment first.

It creates a new pack project from your game's own room or table content and leaves your game unpinned, which means the platform default (Modern Room / Square Table). Use it when something you built inside a game turns out to be worth publishing on its own.

Some things cannot come with it, and the review step lists every one of them by name with the reason:

  • Table pieces never move into a room or table pack. They are your game's, and they stay in your game — nothing is deleted.
  • A room pack cannot carry seats, zones, snap points, prefabs or scripts; a table pack cannot carry a room, zones, snap points, prefabs or scripts. What it can carry — for a room, the room model and the environment; for a table, the seat ring — moves across.

The first step is the new pack's GitHub repository, exactly as when you create a mod: every mod lives in its own public repository. The review dialog opens with a New repository name (a slug of the pack's name, e.g. noir-parlour-room); if GitHub is not connected yet it shows Connect GitHub and a link to create a free account instead, and the confirm button waits. Confirming then:

  1. creates the public repository,
  2. creates the pack project, linked to it,
  3. uploads the pack and every file it uses from your game — models, textures and the material files that name them — to the repository's wip branch.

Your game is only changed once all three have succeeded. If the upload fails, the repository and pack project are kept and the dialog stays open: confirm again to retry the upload without creating a second repository.

No pin is written. A pin names an exact published version, and your new pack has not been published yet. Publish it, then assign it from this same row.

Detach & vendor#

The reverse: it copies an assigned pack's content into your game and removes the pin, so your game stops depending on it.

This is the way out when a pack you depend on is unpublished or deleted. A pinned version is immutable and can never be re-pointed, which is a guarantee — but it also means a pin whose pack has vanished stays broken until you do something. Vendoring is that something, and it needs nothing from the pack's author.

It needs the pack's files, so it is only available for a pack that is one of your own projects. If it is not, the button says so rather than sitting there dead.

Detaching a table is lossy, and it says so. The seat ring comes across; the table's model, colliders, trigger volumes, play-surface metrics and budget do not — a game scene has nowhere to put them, because the assigned table pack is the single owner of the play-surface height. Your game falls back to the default table, Square Table, until you assign another table pack. Detaching a room loses nothing from the document — but with no room pin the game plays in the default room, Modern Room.

Changing the table leaves your seats behind — and offers to fix it#

Seat positions are derived from the assigned table's footprint, its ring layout and its seat count. Changing the table does not move them for you; it shows you that they no longer match and offers to put them back, with a before/after preview rather than a silent rewrite.

The offer lives on the Player Zones folder, under SEAT LAYOUT, and it names the table the seats are currently derived against — so a game pinned to a round table with its seats still spread around a rectangle says so on screen.

Two strengths, and the second is the one for a table that changed shape:

  • Move seats onto this table's ring — the warning that appears on its own. Moves each seat and keeps every size, rotation, type and extra zone you authored. Right after a resize.
  • Reset seats to this table's default… — rebuilds each seat as a fresh seat on the new table, including its rotation, its zone size and its name label, and deletes zones beyond the first. Right when you swap a square table for a round one, where moving a zone stretched along a long edge cannot fix its shape.

Seat colours, custom label text and each seat's first zone type survive both. Objects — card holders and anything standing in a zone — are never touched by either. See Player Zones and Seats.

Changing the table can leave your pieces floating — and it offers to fix it#

Tables are not all the same height. Assign a table whose play surface sits 1.17 ft higher than the one you laid your board out on, and every piece stays exactly where you put it — which now means hovering in mid-air. A lower table buries them inside it instead.

Nothing is moved for you. When the two surfaces differ, the Table row shows a preview:

  • the two heights, and the difference between them;
  • a row per object, by name, with its height before and after;
  • Apply and Cancel — and Cancel is a real answer.

The table is not switched until you Apply. While the preview is open the viewport keeps the table your pieces are standing on, so a taller table's collider never pushes them around before you have decided. Apply switches the table and moves the pieces in one step; Cancel keeps the current table and every position exactly as they were. A table whose play surface is at the same height is switched straight away, because nothing needs to move.

Applying moves the objects straight up or down by exactly the height difference, and nothing else. No piece is turned, resized, slid sideways, or dropped onto the new surface. A token 0.1 ft above the old table ends up 0.1 ft above the new one; a piece you deliberately left floating stays floating by the same amount. Your layout is yours — the editor can carry it to a new height, but it will not redesign it.

Your seat ring moves with it: every seat's zone boxes, name label and seat pivot go up or down by the same height, so the player zones stay on the table. (Zones are footprints - what counts as inside one never depended on height - but they are drawn where they were authored.)

So do your snap points and table zones (the deck slot, the discard pile). Both store an absolute height and are attached to nothing, so a chessboard's 64 square markers left at the old height would sit inside a taller tabletop. They are decided by the same rules as a piece, below: one more than 0.1 ft under the old surface, or outside its play area, stays where it is. The preview does not list them one by one. It adds a summary row for each (64 snap point(s), 2 table zone(s)) with the height change.

Already switched tables and your snap points are under the top? Scenes that changed tables before snap points were carried along keep the old height. Open the snap-point flyout on the transform rail and press Lift N onto table. See The Transform Rail.

What it leaves alone, and why#

Two kinds of object are listed but not moved, because the old table was not holding them up:

  • anything more than 0.1 ft below the old play surface — floor tokens, a piece under the table;
  • anything outside the old table's play area — the rectangle the table pack declares. A shelf ornament against the wall is above the surface too, and moving it with the table would send it through the ceiling.

Parented objects are decided as a group: a piece follows whatever its top-level parent does, so a board and everything standing on it move together or not at all.

It cannot see everything, and it says so. A piece resting on a stand that stands on the table looks exactly like a piece resting on the table, and it will be moved with it. Read the rows before you press Apply.

If the new table is smaller, some pieces will end up past its edge. The preview names them and moves none of them sideways — repositioning a layout is a decision, not an adjustment.

Undo (Ctrl+Z) puts the previous table and the heights back. It does not bring the preview back; re-pick the table from Change… if you want to see it again.

What the Table row deliberately does not offer#

There is no play-surface height field on the Table row, and there never will be.

The assigned table pack is the single owner of that number. Every peer reads it from the same pinned pack at load and uses it to work out where a dragged piece is going. A second place to set it would be a second answer, and a peer with a different answer sends the table wrong drag positions — which looks like a physics bug and is not one.

The model, the colliders, the triggers, the play surface and the seat ring all belong to the pack, and all of them are edited in the Table Editor.

Nobody can change these during a session#

The room and the table are fixed by the game mod. Once a table is running, there is no way to swap either one — not for a player, not for a spectator, not for the host. There is no menu entry, no keyboard shortcut and no setting, because there is no mechanism underneath one: every peer derives the room and the table locally from the same pinned mod, and nothing about them is sent over the network.

Adding a mod mid-session still works and still contributes pieces, prefabs and scripts — but it can never become the room or table provider. That is decided when the table is created, and if a mod's room or table is being ignored the mod list says so.

Collections: which mod supplies the room and the table#

Everything above is about one mod's assignment. A collection is a different thing: a named bundle of mod ids that share one table. It is the only way to put more than one mod on a table, and it raises a question a single mod never has to answer — if three mods are on the table and two of them assign a room, whose room is it?

The answer is a field, not a rule of thumb. Open Mod ▸ Collections… in the menu bar of the Game Editor and pick a collection; the Room & table provider row names exactly one member. Every other member's room and table are ignored, and the members list says so on each of them.

DiceyTable never breaks the tie for you — not by list order, not by "the last one added", not by which one you assigned most recently. A room chosen by an implementation detail is indistinguishable from a broken one, and you would find out from a player.

There are four outcomes, and the row tells you which one you are in:

Members carrying a room or table What happens
exactly one it is designated automatically, and the row says so — you can still change it
two or more, none chosen publishing is refused, and both candidates are named
none the platform defaults, Modern Room and Square Table, are used
the designated member is no longer in the collection publishing is refused — it is never re-assigned for you

That last row is the one worth reading twice. Removing the designated provider from a collection does not quietly promote another member, however obvious the alternative looks. A published version is immutable, so a guess made here would be frozen into every table that ever pins this version.

Every other member says "room/table ignored"#

Each member that is not the provider carries a room/table ignored chip, whether or not the editor can see that it has a room. This is deliberate: a room that is quietly ignored looks exactly like a room that is broken, and the bug report you get is "my room doesn't load".

While no provider is designated at all, the members are marked provider unresolved instead — nothing has been decided yet, and publishing will not proceed until it has.

But your materials are never ignored#

room/table ignored means exactly what it says, and no more. It covers the room model, the environment, the table and the seat ring. It does not cover the materials and textures your pieces are painted with — those travel with the pieces, so a non-provider member's tokens look the way you authored them.

This matters because material names are not unique across mods. Every new project starts with the same four seeded materials — Floor, Wall, Ceiling and Default — so on a collection table there are as many different materials called Default as there are members. DiceyTable keeps each member's materials to itself: a piece from member B painted Default gets B's Default, never the provider's, even though both are called the same thing and both were seeded the same way. You do not have to rename anything, and renaming would not have helped anyway.

The one thing a collection does share is the built-in preset library (Felt, Metal, Oak and the rest). A built-in is the same material everywhere by design, so two members both using Felt are using one material, not two.

If a piece renders with its plain shipped look instead of the material you assigned, the material is genuinely missing from that member — it is never another member's material wearing the same name. Check that the piece and the material are in the same mod.

The designation belongs to the version#

The provider is stored on the collection version, not on the collection. A published version can never be re-pointed, so:

  • the designation is frozen with the version, exactly like the version's member list;
  • a table that pinned version 1.0.0 keeps 1.0.0's provider forever;
  • changing the provider means publishing a new version — a deliberate act, with the same blast-radius preview as any other version bump.

And it is locked when the table is created#

The room and the table are resolved once, when the table is created, from the mod (or the pinned collection version) it was created with. Mods added later contribute pieces, prefabs and scripts and can never change the room or the table — see Nobody can change these during a session above.

Did this page answer your question?