Dicey Table

Scripting API

DiceyTable has two scripting surfaces. They are separate products that happen to share a table: different languages, different globals, different security models, different event names. Nothing you learn about one transfers automatically to the other, and moving a game from one to the other is a rewrite rather than a port.

Read Choosing a surface first if you have not picked one.

The two surfaces#

Table Scripting Mod Scripting
Language TypeScript, transpiled in the editor JavaScript, a file in the mod's GitHub repo
Globals world, globalEvents, refObject api, passed to exports.setup(api, manifest)
Event style Delegates — globalEvents.onX.add(fn) Callback registry — api.on("onX", fn)
Entities A live ObjectHandle with mutators Plain TableObjectState data plus api.objectAction(id, action)
Security No capability model; a three-type intent allowlist Ten capabilities declared in the manifest
Where it runs The host peer only Every peer that loaded the mod, in a sandboxed iframe

world does not exist in a mod's runtime. api does not exist in a table script's runtime. Their event names look alike and are unrelated: the mod hook is onTurnStart, the table-script delegate is onTurnStarted.

Table Scripting — Surface A#

  • World — the ten methods on the world global: find, spawn, read the room, log, broadcast, persist and pace.
  • ObjectHandle — one entity, with fourteen methods, ten read-only ObjectData fields and eight entity-scoped delegates.
  • Object Types — the per-kind handles ObjectHandle narrows into, what a card and a container each add, and how refObject gets one.
  • Events — the sixteen globalEvents delegates, what each payload carries, and which peer raises it.
  • TypesVec3, ObjectKind, ObjectAction, SpawnObjectOptions, PlayerInfo and TurnInfo.

Mod Scripting — Surface B#

  • The mod api object — every method, each with the capability that gates it and what the host does with the call.
  • Mod hooks and capabilities — the hook events, their exact payload shapes, the unbounded custom UI-hook channel, and the twelve capability slugs.

How to read a reference entry#

Every member carries a four-row badge table — authority, timing, capability, availability — under a byline that names its surface. Each value is defined exactly once, on the concepts page that owns the idea, and the entry links there rather than restating it. Every runnable example is compiled against the same declaration the editor's autocomplete uses, and every mod example is additionally run through the scanner that gates real publishing. See Reading these docs.

Where a surface has a gap — a stale declaration, a type union with no way to call part of it, an event that fires correctly and reports null — it is disclosed on the entry and collected on one dated page.

See also#