Dicey Table

SCRIPT

SCRIPT is an Engine component section (tone="engine") on every object selection. Unlike LIGHT/CAMERA it is not part of TableObjectState.components[] — it is its own attachment mechanism, on metadata.scriptId, with its own dedicated Inspector section rather than being routed through the generic optional-component renderer.

script is deliberately not an addable component. OBJECT_COMPONENT_TYPES is ["light", "camera"]script was considered and rejected for that list so there would be one attachment story for scripts, not a modern components-array one and a legacy metadata.scriptId one living side by side. If you see script listed as addable anywhere, that is wrong; packages/shared/src/componentInspector.ts's script descriptor exists only to explain, grayed out in the + ADD COMPONENT popover, why it cannot be added there: "Attach a script from the SCRIPT section — one per entity."

Source: the SCRIPT EmCollapsible in TableEditModeShell.tsx's object Inspector branch.

Fields#

Field Type Values Default Runtime effect Replicates
Script select None, or any project script None Attaches a Table Script to this specific object. That script's refObject global resolves to this object — the defining difference from a scene script, which has no refObject. Yes — metadata.scriptId, part of TableObjectState.metadata

A script written for a kind shows that kind in the dropdown — deck-1.ts (deck) — so attaching one to a different kind is a visible choice rather than a silent one.

Buttons#

  • Edit — opens the attached script in the Monaco item-editor tab. Disabled when no script is attached.
  • + New — creates a new project script for this object's kind and attaches it in one action. The new script is not empty: it opens with a starter body written against the delegates that kind raises (a deck's reads refObject.cards in an onCardDrawn handler; a die's handles onRolled), and its refKind is recorded so the editor types refObject as that kind's handle. This is the difference between + New here and New ▾ ▸ Script on the asset bar, which creates a global script with no refObject of its own.

The Inspector's own hint names the type: "Runs on the host while playing; the script's refObject is this object, typed as DeckObject." One object can carry at most one script — reassigning Script replaces the previous attachment rather than adding a second.

A mismatched attachment is warned about, not blocked. Attach a script written for a deck to a card and the section says so; the script still runs, because refKind only ever governed the editor's typing and the starter body. The narrowed members simply describe something this entity is not — refObject.cards on a card resolves to an empty array.

Object script vs scene script#

This section attaches a script to one object. A separate mechanism — SCENE SCRIPTS, documented on platform-panels.md — attaches one or more scripts to the scene as a whole, running with world/globalEvents but no refObject. The two use the same script assets and the same Monaco editor tab; only the attachment target and the resulting refObject availability differ. Full detail on the scripting execution model — host authority, world/globalEvents/refObject, sync vs async — belongs to the scripting-api concepts pages, not this guide.

See also#

  • The Inspector — where SCRIPT sits in the fixed section order (always present, right after the sound sections).
  • platform-panels.mdSCENE SCRIPTS, the scene-level counterpart.
  • Object Types — the handle type refObject is declared as, per kind, and what each one adds.
  • Scripts — the whole authoring loop for both flavours.