Builds an action, compiling its trigger and visibility predicates and resolving its executor.
The executor is resolved against the target logic selected by
data.scope (SELF → this data model's logic, ITEM → the parent item's
logic, ACTOR → the owning actor's logic). For Intrinsic actions the
executor is the named method on that target (bound to it); for Script
actions it runs the Foundry Macro named by data.executor (a UUID) via
Macro#execute. When no executor is supplied, a no-op resolving to
undefined is used.
The action definition.
Construction options; options.parent is the data
model the action belongs to and supplies the logic targets used to
bind the executor.
The persisted action definition (see SohlAction.Data).
The callable that performs the action. For Intrinsic actions, the named
method on the scoped target logic, bound to that target; for Script
actions, a thunk that runs the referenced Foundry Macro via
Macro#execute (permission-gated; no code is compiled from data). A
no-op resolving to undefined when no executor is defined. See
ActionExecutorFn.
OptionalexecutorThe scope-resolved logic the executor runs on (SELF → this action's
logic, ITEM → the parent item's logic, ACTOR → the parent actor's logic) —
the same target an Intrinsic executor is bound to. Stamped onto the
context as sohl.entity.action.SohlActionContext.thisLogic at
dispatch, so inside an intrinsic method this === ctx.thisLogic, and an
overriding macro calls the intrinsic via ctx.thisLogic.<executor>(ctx).
Availability predicate compiled from data.trigger; gates
execute and composes into visible. See
ActionTriggerFn.
UI-visibility predicate compiled from data.visible, composed with
execute permission and trigger. See ActionVisibilityFn.
Static ReadonlyDEFAULT_Fallback i18n key for unavailableReason — used when a refused
action declares no disabledReason of its own.
Whether the action's trigger currently passes — i.e. whether execute would run it rather than refuse it. Evaluated against the action's own resolved owning documents, so a caller needs no context of its own.
This is the seam a UI surface asks before offering the action: the Actions tab disables a refused action's run control and shows unavailableReason, rather than presenting a live control that silently does nothing (issue #1135). Note it does not include the Script-action permission gate that execute applies first — that gate is already folded into visible, the DOM-driven predicate.
true when the trigger passes.
The serialization discriminator for this instance — the concrete class's static Kind. Written into the JSON by toJSON under the kind key and read back by sohl.utils.defaultFromJSON to select the constructor. Derived from the class, never stored per-instance.
The action's shortcode identifier.
The i18n key explaining why the action is refused while
isAvailable is false — the action's declared
data.disabledReason, or a generic fallback when it declares none.
A key, never localized prose: the value is stored and passed around, and localized only where it is rendered or notified.
The reason's localization key.
Deep-copy this entity, re-parenting the copy under parent with no other
changes. Shorthand for clone({}, { parent }).
The Logic to own the cloned entity.
The cloned entity.
Deep-copy this entity, optionally overriding fields and clone options.
Field overrides applied to the clone.
Clone options (e.g. a new parent).
The cloned entity.
Executes the action.
Gating, in order: for SCRIPT only, the current user must
satisfy data.minActorOwnership (see
userMeetsExecutePermission); then trigger must return
truthy. Either failure causes the action to be skipped (with an
informational log) rather than throw.
The context in which to execute the action.
The result of the executor, or undefined if the action
was gated out.
Serialize this instance to a plain object suitable for JSON serialization.
A plain object representing this instance, consistent with the
Data interface of the subclass.
The base emits only the kind tag. A subclass that adds state
overrides this, chaining ...super.toJSON(), and emits keys matching its
own Data interface in persisted form (a uuid/shortcode where the live
object holds a resolved reference). The governing rule: toJSON() output
must be valid data for the constructor. The transient parent is
deliberately not emitted — it is re-supplied on revival.
StaticcreateBuilds a new action for a given actor, merging the actor's speaker into the action's context. This is a convenience for constructing actions from a document's data model, which is where the speaker is known.
The actor whose speaker is merged into the action's context.
The action definition.
Construction options; options.parent is the data model the action belongs to and supplies the logic targets used to bind the executor.
A new SohlAction instance.
An executable action attached to a document (an actor or item) and surfaced as an entry on that document's context menu (and on chat-card buttons). Choosing the entry runs the action.
A Script action is, in effect, a macro attached to a document: instead of sitting on the macro bar it lives on a specific actor or item and runs with that document as its context. An intrinsic action (below) is the same thing authored in code rather than typed by a GM.
Actions are how a character or item does something — run a skill test, make an attack, activate a mystical ability. They come in two flavors that differ only in where the executor comes from:
defineIntrinsicActions(). Theexecutoris the name of a method on the scoped target logic (e.g.successTeston a Skill), looked up and bound at construction. This is how the system ships its built-in actions.executoris the UUID of a FoundryMacro; running the action invokesMacro#execute(which enforces theMACRO_SCRIPTpermission and ownership) with a SohlActionContext-derived scope. No code is stored on, or compiled from, the document — see the security model's "reference code, never compile it" rule. Stored per-document and permission-gated; there is no end-user authoring UI.Either way, an action carries:
SELF/ITEM/ACTOR) selecting which logic the executor binds to — i.e. whatthisis when it runs (the action's own logic, the owning item's, or the owning actor's);The constructor compiles
trigger/visibleand resolves/bindsexecutorfrom their stored string forms, so a finishedSohlActionis ready to execute. See sohl.core.logic.SohlLogic.getContextOptions for how actions become context-menu entries.A Script action's Macro is an ordinary Foundry script Macro, so it can use the full client API (
actor,token, and the SoHLsohl/.logicsurfaces are passed in scope). If the behavior outgrows a single Macro, reach for a Foundry module instead.Example
Example