ObjectAction (table script)
ObjectAction is the union a table script may pass through the script host — 13 of the engine's 19
actions. It is declared inside DICEYTABLE_SCRIPT_API_DTS and re-checked at run time against
SCRIPT_SAFE_OBJECT_ACTIONS in apps/web/src/scripting/TableScriptHost.ts, and the two lists match
exactly, so a compromised sandbox frame cannot broaden the set.
This union does not exist on the mod surface. A mod's ten-action list is
SANDBOX_SAFE_OBJECT_ACTIONS, which is a different
list with a different enforcement path.
The values#
The How a script calls it column is the practical limit: an action with no method is in the union and would pass the allowlist, but the typed API offers no way to request it.
| Value | What the host does | Kinds it is meaningful for | How a script calls it |
|---|---|---|---|
flip |
Toggles faceDown and rotates 180° about local X. |
card, deck; on any other kind the rotation and the flag both still change. |
handle.flip() |
rotate |
Rotates 90° about local Y. | every kind. | handle.rotate() |
lock |
Marks the entity locked and switches its rigidbody to static. | every kind. | handle.lock() |
unlock |
Clears the lock and restores the authored body type. | every kind. | handle.unlock() |
tap |
Sets tapped to true. |
every kind. | no method |
untap |
Sets tapped to false. |
every kind. | no method |
shuffle |
Shuffles a deck's contents. Refused outright on every other kind — the runtime returns before it changes anything, so a bag makes no sound and does not move. | deck. |
handle.shuffle() |
draw |
Draws the first item off the container. Does nothing on any other kind. | deck, bag. |
handle.draw() |
deal |
Deals from the container to the seated players. Does nothing on any other kind. | deck, bag. |
handle.deal() |
split |
Splits a stacked deck in two. Does nothing unless the deck holds more than one card. | deck. |
no method |
combine |
Merges the entity into a stack. | card, deck. |
no method |
roll |
Throws the die with a randomized impulse. On a card it throws the card. | die. |
handle.roll() |
delete |
Destroys the entity, re-parents its children, removes its joints. | every kind. | handle.destroy() — the method name differs from the action name |
9 of the 13 have a method. tap, untap, split and combine do not.
Known gap.
tap,untap,splitandcombineare declared inObjectActionand are on the script host's allowlist (apps/web/src/scripting/TableScriptHost.ts,SCRIPT_SAFE_OBJECT_ACTIONS), butObjectHandleexposes no method for any of them (packages/shared/src/scripting.ts). Every layer below the typed API is ready for them — the allowlist passes them and the runtime applies them correctly — and only the calling surface is missing.deletelooks like the same problem and is not: it is reachable, asdestroy(). Until a method exists, model tapping as your own state — a tag, or saved data — and read it back withhandle.refresh(). A mod can callsplitandcombine, because mod scripting passes the action name as a string. See Known limitations.
What the engine has and this union does not#
lift, flick, press, reveal-all, reveal-team-a and reveal-team-b are the six engine actions a
table script cannot request.
By design.
liftandflickare drag mechanics — the physical result of a pointer gesture, meaningless without the gesture that produced it.pressis a button's own click — a script observes it throughButtonObject.onPressedand reacts, rather than synthesizing one. The threereveal-*actions are hidden-information reveals, and hidden information is the one part of the table the host must own outright: an action that can flip who sees a card is an action that can be used to cheat. Scripts do not get them, and that is not expected to change. Model a reveal as your own state — a tag, or saved data — and let the host's reveal path stay the only thing that changes card visibility.
Receiving an action is wider than requesting one#
globalEvents.onObjectAction and ObjectHandle.onAction are not typed with this union. They are typed
with ObservedObjectAction, which is this union plus the
six engine actions above — the event is raised for all 19, so a handler can be handed a lift, a flick, a
press or a reveal-* it could never have asked for.
That is why there are two types rather than one: collapsing them would either hide six real events or
advertise six calls the host's allowlist refuses. Annotate with ObjectAction what you are about to
request and with ObservedObjectAction what an event gave you, and keep a default branch in the switch —
the engine's list and this union are maintained by hand in two files.
See also#
- Action vocabularies — the three lists side by side.
ObservedObjectAction— the union an event delivers.- TableObjectAction (engine) — all 19.
- Sandbox-safe object actions — the mod list of 10.
ObjectHandle— the nine methods in the last column.- Object actions — what each action does, per kind.
