The Attribute data interface.
Binds this logic to its parent data model and builds the actions map from the parent's intrinsic and scripted action definitions, selecting a default action.
Reserved base data (unused by the base class).
Must provide options.parent, the data model this logic
is embedded in; the parent's actionDefs are used to build
actions.
Executable actions for this document, keyed by shortcode — context-menu entries, chat-card buttons, and lifecycle hooks. A script action shadows (wholly overrides) the intrinsic action of the same shortcode (see the constructor).
Fate-adjusted mastery level for this attribute, as a sohl.entity.modifier.MasteryLevelModifier. Seeded in finalize from the actor's Aura attribute, exactly as a skill's is; disabled outright for the Aura attribute itself, which can never be fated (#1106).
Mastery level derived from this attribute, as a sohl.entity.modifier.MasteryLevelModifier. Its base is set in finalize to the effective score multiplied by five.
The attribute's score as a sohl.entity.modifier.ValueModifier, seeded from AttributeData.scoreBase.
The owning SohlActor — the document itself when it is an actor,
otherwise its owning actor (for an item, combatant, or effect), or null.
The logic of the owning actor — the Foundry-free way to reach the actor
layer from any logic. For an actor's own logic this is itself; for an
item's logic it is the owning actor's logic; otherwise null.
Resolved through the SohlLogicData port, so logic code
can navigate to the actor (and iterate items via allLogics /
logicTypes / getItemLogic) without touching the Foundry document.
The Fate Mysteries on the actor that may be spent on this attribute's tests — a general Fate Point, or one associated with this attribute's shortcode, that still has a charge (#1106).
The rules allow Fate on any skill or attribute test, so this is the same eligibility set a skill exposes, evaluated against this attribute's shortcode.
The eligible-and-charged Fate MysteryLogic instances (empty off an actor).
This logic's typed data — its *Data interface (e.g. SkillData), the same
persisted object as document.system. Prefer document.logic.data when
reading a document's fields from a macro, Script Action, or module: it is the
typed, API-documented surface (autocomplete and reference links resolve),
whereas document.system is typed as the internal DataModel.
Convenience accessor for parent.
The owning document's id.
The owning SohlItem.
The owning document's kind (its actor or item type id).
Localized display label combining the typeLabel and the document's name.
The owning document's name.
A SohlSpeaker for the owning actor/item (a blank speaker if neither resolves).
Localized type (and sub-type, when present) label for the owning document.
The owning document's UUID — the opaque identity token from the data port.
Build an update() payload that adds a value description entry to
AttributeData.valueDesc.
The label/maxValue pair to append.
The display label for the value-description band.
The upper bound this band applies up to.
An update() payload writing the extended system.valueDesc array.
Delete the owning document, after confirming with the user.
The action context; unused.
Open the sheet for the owning document.
The action context; unused.
Compute derived values that depend on sibling items being initialized.
Called on every item after ALL items have completed initialize.
Safe to access: sibling items' initialized state (e.g., reading trait attribute values for a skill base formula).
Not safe to access: sibling items' evaluated state — another item's
evaluate() may not have run yet. Dependencies on evaluated state
belong in finalize.
Example: a Skill reads trait attribute values to compute its skill
base; a gear item resolves its containerId to find its parent container.
Execute an action by shortcode, using the provided context or creating a new one.
The shortcode of the action to execute.
Optionalcontext: sohl.entity.action.SohlActionContextThe action context to use, if any.
The result of the action execution, or undefined if the action was not found or could not be executed.
Spend Fate on this attribute's test — the shared post-roll bump flow (sohl.document.item.logic.performFateTest); the die is never re-rolled.
Intrinsic-action executor for the fateTest action, triggered by the
player from the test card's Fate button or the attribute's Actions menu.
The action context; context.scope.priorTestResult is
the original result being fated.
Resolves once the Fate test, any consumption, and the re-post complete.
Resolve cross-item dependencies that require all items to have been evaluated.
Called on every item after ALL items have completed evaluate.
Safe to access: all sibling items' initialized and evaluated state.
Example: fate mastery level (which depends on an already-evaluated Aura trait); encumbrance totals summed across all evaluated gear.
The context-menu options — the actions currently available — for this logic's document.
The available context-menu entries.
Set up base state from persisted data: create ValueModifiers, set base values.
Called on every item before any item's evaluate runs.
Safe to access: own persisted data fields (this.data.*).
Not safe to access: sibling items on the same actor — they may not have initialized yet. Cross-item reads belong in evaluate.
Example: a Skill creates its MasteryLevelModifier
from persisted fields; it does not yet read trait attribute values.
Begins an opposed test backed by this attribute's mastery level.
Intrinsic-action executor for the opposedTestStart action. Opposed tests
are token-based: this delegates into the actor's token logic
sohl.document.token.logic.SohlTokenDocumentLogic.opposedTestStart, passing this attribute's
logicUuid as the source — the same delegation the skill uses.
The action context (speaker, scope) for the test.
The opposed test result, or null if cancelled or unavailable.
Post this item's description to the chat log — a human-triggered, informational card (no follow-up buttons) built by buildItemDescCardData. Assist, never act: this only shows the item's own text; it takes no action on any character.
The action context; unused.
Post the Fate result card for this attribute. Delegates to the shared implementation; defined here so the card post is spy-able per logic type.
The evaluated Fate test result.
The resolved fate outcome.
The Fate Mystery a point was consumed from, if any.
Resolves once the card has been handed to the speaker.
Intrinsic action performed after finalize lifecycle stage. This is intended for modules to hook into (or ActionItems to override) to perform additional logic after the main lifecycle stages have completed.
The action context for the post-finalize hook.
Build an update() payload that removes a value description from
AttributeData.valueDesc by its label.
The label of the entry to remove.
An update() payload writing system.valueDesc with the matching entry filtered out.
GM result-edit for a posted test card (#856) — the higher-fidelity
counterpart to Fate. Re-opens the standard test dialog pre-filled with the
result's current situational and success-level modifiers; on submit it
applies the new modifiers and re-evaluates on the SAME frozen roll
(never a re-roll, no Fate cost), then reposts the card. The prior result
rides in context.scope.priorTestResult (the reconstruction seam), so this
works for any standard test card — skill, attribute, or combat strike mode.
Changing the situational modifier changes the effective target, so the base success level re-derives from the frozen roll; the success-level modifier is a flat offset applied after. Clicking OK without a change is a no-op (nothing re-evaluated, nothing reposted).
GM-only. The pencil is render-hidden from non-GMs (sohl.document.chat.gateEditActionPencil); this is the click-time half of that gate — a synthesized click from a non-GM is refused here.
The action context; context.scope.priorTestResult is the
result being edited. When skipDialog is set, the new
situationalModifier / successLevelMod / rollMode are taken from
context.scope instead of the dialog.
The re-evaluated result, or undefined when refused (non-GM),
cancelled (dialog dismissed), or unchanged (no-op).
Performs a success test against this attribute's mastery level.
Intrinsic-action executor for the successTest action; delegates to
sohl.entity.modifier.MasteryLevelModifier.successTest. An
attribute's mastery level is its effective score × 5 (the "TL" shown on
the attribute card), so this rolls the attribute against its own target
level exactly the way sohl.document.item.logic.SkillLogic.successTest
rolls a skill.
The action context (speaker, scope) for the test.
The test result, undefined if cancelled, or false on error.
Serialize this logic to a plain reference.
A uuid-keyed reference to this logic.
A logic is a behavior wrapper over a live Foundry document; it is never
revived from its own JSON (its constructor needs that document). Wherever a
logic is persisted — a chat card, an action sohl.entity.action.SohlActionContext.scope
— it is re-resolved from its uuid (e.g. via fvttLogicFromUuidSync), not
rebuilt from a payload. So it serializes as a compact, resolvable reference
(name/kind are carried for display and debugging); the owning document
holds the actual persisted state.
StaticdefineDefine and return all intrinsic actions for this logic type.
The attribute intrinsic-action definitions.
An innate characteristic.
Attributes represent intrinsic properties of a character that are not learned through training: physical attributes (Strength, Stamina, Dexterity), mental attributes (Intelligence, Aura, Will), physical features (Height, Frame), and special qualities (Flaws, Virtues).
Attributes are foundational to the SoHL system: they form the skill base formulas for skills, contribute to derived values like health and encumbrance, and serve as prerequisites for abilities and actions.