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.cardsin anonCardDrawnhandler; a die's handlesonRolled), and itsrefKindis recorded so the editor typesrefObjectas that kind's handle. This is the difference between + New here and New ▾ ▸ Script on the asset bar, which creates a global script with norefObjectof 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
SCRIPTsits in the fixed section order (always present, right after the sound sections). - platform-panels.md —
SCENE SCRIPTS, the scene-level counterpart. - Object Types — the handle type
refObjectis declared as, per kind, and what each one adds. - Scripts — the whole authoring loop for both flavours.
