Dicey Table

Mods

A mod is a self-contained tabletop game (or a reusable set of table pieces) that DiceyTable loads at runtime. Every mod is, at minimum, one JSON file — the manifest — sitting at the root of a GitHub repository, plus whatever setup scene, script and assets it declares.

Mods are how DiceyTable stays a generic table instead of one hard-coded game: the built-in table gives you physics, replication and a sandboxed scripting surface; a mod supplies the pieces, the starting layout, and (optionally) the rules.

What a mod is#

At the file level, a mod is:

  • A manifest (diceytable.mod.json) — required. Declares identity, an optional entry point, declared capabilities, and optional discovery metadata (summary, description, category, cover art). See Manifest reference.
  • An optional setup scene (entry.setup, conventionally setup.json) — the objects present when the table loads. Authored in Edit Mode; the modern format is edit-scene. See Required and conventional files.
  • An optional script (entry.script, conventionally scripts/main.js) — sandboxed JavaScript that runs against the mod scripting API (api.*), gated by declared capabilities.
  • Assets — models, textures, audio and sidecar JSON, referenced by repo-relative path.

Both the setup and the script are optional. A mod with neither is legal — see Manifest reference § entry for why, and for what it means when a mod publishes successfully but does nothing at the table.

The three manifest types#

The manifest's type field is one of:

type What it signals
game-pack A complete game: pieces plus (usually) a setup scene and rules script.
component-pack A reusable set of pieces or assets with no inherent game — dice sets, a card back, a model library. Often has no entry at all.
table-pack A table/environment preset (surface, lighting, camera defaults) rather than game pieces.

type is currently descriptive metadata only — nothing in the scanner or runtime branches on it. It exists for discovery and for authors' own organization.

type: "component-pack" is not the same thing as a server-side "package." The word is overloaded: a mod's type describes the shape of a single mod (does it ship a whole game, or just components?), while "package" elsewhere in the platform refers to packageLifecycle.ts — a separate, DB-backed feature for pinning a version-locked bundle of mod IDs to a room. The two concepts don't interact. If you're looking for that feature, it has no author-facing UI today and no docs page.

GitHub is the source of truth#

A mod's manifest, setup, script and assets all live in a GitHub repository the author controls — never on the DiceyTable server, never in our database. This is deliberate:

  • Authoring is local-first. While you work in Edit Mode, your files live in the browser's OPFS (Origin Private File System), mirroring what will become the repo tree.
  • Publishing pushes to GitHub. A publish is a git push to your repo (via OAuth), not an upload to our servers.
  • Multiplayer pulls from GitHub. Every peer in a room independently fetches the mod's tree from raw.githubusercontent.com (or an OPFS pull-cache keyed by commit sha) and verifies content hashes. The DiceyTable server only scans and indexes what's already public on GitHub — it never becomes the file's origin.
  • Repos are public. A mod's repo is created public deliberately: since every peer pulls raw files directly from GitHub, a private repo would silently break multiplayer for anyone without repo access.

One practical consequence: an unpublished draft cannot be played in multiplayer. Until you push to GitHub, there is nothing at a stable URL for other peers to pull.

Where to go next#