An instance of harm to a character.

Trauma represents wounds and damage sustained by a character. The subType discriminates the trauma's nature: injury (bodily harm tied to a body location), or a mind/spirit/body condition — fear, morale, pall, psycond (psychological condition), auralshock, fatigue, infection, shock, or coma.

Each trauma tracks:

  • subType — Category of harm (injury | fear | morale | pall | psycond | auralshock | fatigue | infection | shock | coma)
  • injuryLevel — Severity on a graduated scale: M1 (Minor), S2–S3 (Serious), G4–G5 (Grievous), with higher levels causing greater impairment and risk of death
  • healingRate — How quickly the wound heals (influenced by treatment)
  • aspect — The type of damage that caused the trauma (Blunt, Pierce, Cut, Heat, Cold), which affects treatment and healing
  • isTreated — Whether the trauma has received medical treatment (untreated wounds heal slower and risk infection)

Trauma contributes to the character's overall shock state and (for physical subtype) interacts with the anatomy model (body roles, body parts, body locations) to determine hit location effects.

Trauma supports treatment and healing test actions.

Type Parameters

Hierarchy (View Summary)

Indexable

  • [key: symbol]: true

Constructors

Properties

actions: SohlMap<string, sohl.entity.action.SohlAction>

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).

bloodLossAdvanceDurationBase: sohl.entity.modifier.ValueModifier

Effective seconds between blood-loss advances, as a sohl.entity.modifier.ValueModifier, seeded from TraumaData.bloodLossAdvanceDurationBase.

bodyLocation: undefined | sohl.entity.body.BodyLocation

The BodyLocation on the being's body that this trauma affects, resolved from TraumaData.bodyLocationCode. When the code is blank — or no matching location exists in the body — this is undefined, indicating the trauma affects the whole body rather than a specific location. Recomputed in evaluate.

courseDurationBase: sohl.entity.modifier.ValueModifier

Effective seconds between Extended Shock / Coma course checks, as a sohl.entity.modifier.ValueModifier, seeded from TraumaData.courseDurationBase.

The target value of this trauma's Healing Test, as a sohl.entity.modifier.ValueModifierHealing Rate × Healing Base. Active Effects keyed TRAUMA_EFFECT_KEY.HEALING (mod:logic.healing) modify it, so what a wound is tested against is now open to influence rather than an expression buried at the roll (#1181).

healingCheckDurationBase: sohl.entity.modifier.ValueModifier

Effective seconds between healing checks, as a sohl.entity.modifier.ValueModifier, seeded from TraumaData.healingCheckDurationBase.

How quickly the wound heals, as a sohl.entity.modifier.ValueModifier, seeded from TraumaData.healingRateBase.

Trauma severity level (M1=1, S2=2, S3=3, G4=4, G5=5), as a sohl.entity.modifier.ValueModifier, seeded from TraumaData.levelBase.

treatmentModifier: sohl.entity.modifier.ValueModifier

Treatment modifier for the trauma, as a sohl.entity.modifier.ValueModifier, seeded from TraumaData.treatmentModifierBase.

Accessors

  • get actor(): null | SohlActor
  • The owning SohlActor — the document itself when it is an actor, otherwise its owning actor (for an item, combatant, or effect), or null.

    Returns null | SohlActor

  • get actorLogic(): null | SohlActorLogic<any>
  • 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.

    Returns null | SohlActorLogic<any>

    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.

  • get categoryLabel(): string
  • Localized qualitative label for the current sub-category.

    The category field is a sub-type-specific enum: FEAR_CATEGORY for FEAR, MORALE_CATEGORY for MORALE, FATIGUE_CATEGORY for FATIGUE, TRAUMA_PSYCOND_CATEGORY for PSYCHOLOGICAL_CONDITION, TRAUMA_PHYSCOND_CATEGORY for PHYSICAL_CONDITION — each mapped to its localized label. Other subtypes (or an unrecognized value) return the raw category string, or an empty string when unset.

    Returns string

  • get data(): TData
  • 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.

    Returns TData

    Convenience accessor for parent.

  • get document(): TData["parent"]
  • The owning document — the actor or item this logic is embedded in.

    Returns TData["parent"]

  • get healingHalted(): boolean
  • Whether the patient's injury healing is currently halted — true while the owning actor carries any active infection-subtype trauma (an active infection stops all Injury Healing Tests until every infection is defeated).

    Returns boolean

  • get isBleeding(): boolean
  • Whether the wound is actively bleeding. Derived (#482): true when the blood-loss advance timer is armed — i.e. bloodLossAdvanceDurationBase is set. A non-bleeding wound leaves that field null.

    Returns boolean

  • get isTreated(): boolean
  • Whether the trauma has received medical treatment. Derived (#1148): true when a Healing Rate has been determined and a treatmentDate is set.

    The Healing Rate is the source of truth. A null rate means no treatment has established one, so the wound reads as untreated whatever date is on record — a date cannot make a rate-less wound treated. A recorded rate of 0 is a real (catastrophic) rate, not an absent one.

    Returns boolean

  • get item(): SohlItem
  • The owning SohlItem.

    Returns SohlItem

    If this logic is not embedded in an item.

  • get kind(): string
  • The owning document's kind (its actor or item type id).

    Returns string

  • get levelLabel(): string
  • Localized qualitative label for the current effective level.

    The graduated-level subtypes (Injury, Infection, Pall, Auralshock, Fatigue, Psychological Condition) return the numeric level as a string. Fear and Morale carry no numeric level — their qualitative state lives in the category field, so they are labelled by categoryLabel.

    Returns string

  • get nextRecoveryTestAt(): undefined | number
  • The world time (in seconds) of this trauma's next scheduled recovery / heal / course test, or undefined when none is scheduled.

    This is a view-only derivation for the sheets — it reads the recurring ScheduledAction the sub-type's recovery check runs on (mapped by RECOVERY_ACTION_BY_SUBTYPE) from the generic system.scheduledActions store and returns its anchor + interval. The store is the source of truth: nothing is auto-armed (consent model, issue #579), so an unscheduled trauma — or one whose only matching entry is event-driven rather than time-based — reports undefined, which the sheets render as an em-dash.

    Returns undefined | number

  • get typeLabel(): string
  • Localized type (and sub-type, when present) label for the owning document.

    Returns string

  • get uuid(): string
  • The owning document's UUID — the opaque identity token from the data port.

    Returns string

Methods

  • Intrinsic-action executor for the recurring auralShockRecovery — the *Check half of this condition's cycle (#1181).

    A *Check offers, and does nothing else: it posts a card whose button invites the owner to perform one auralShockRecoveryTest. No roll is made and nothing is written, so it imposes nothing and needs no ownership gate — anyone may initiate a Aural Shock Recovery Check. The card carries this occurrence's due time, so the test it offers can anchor its successor there rather than on the moment the button happens to be pressed.

    Parameters

    Returns Promise<void>

    A promise that resolves once the check card is posted.

  • Intrinsic-action executor for the Aural Shock Recovery Test — the *Test half of this condition's recovery cycle (#1181).

    Rolls one headless Will test and applies its outcome; exactly one runs per invocation, however much world time has elapsed. The condition ends when its level reaches 0; otherwise the next test is offered, anchored on this occurrence's due time rather than on now.

    Parameters

    Returns Promise<void>

    A promise that resolves once the outcome and schedule are persisted.

  • Intrinsic-action executor for the Blood Loss Advance Test (#487) — the *Test half of a bleeding wound's cycle.

    Applies one advance: Blood Loss Points accrue, the shock state advances one step per BLP, and 5 Fatigue Levels of weakness (anemia) are inflicted per BLP. Exactly one runs per invocation — a bleeding wound left unattended through several intervals costs one advance per consented test, not a silent cascade of them.

    A physician's Marginal-Success Blood Stoppage stops the bleeding after the next advance (#547), so a pending stoppage is spent here. A wound that has stopped bleeding ends the recurrence; otherwise the next test is offered, anchored on this occurrence's due time.

    Parameters

    Returns Promise<void>

    A promise that resolves once the outcome and schedule are persisted.

  • Intrinsic-action executor for the recurring courseCheck — the *Check half of this condition's cycle (#1181).

    A *Check offers, and does nothing else: it posts a card whose button invites the owner to perform one courseTest. No roll is made and nothing is written, so it imposes nothing and needs no ownership gate — anyone may initiate a Course Check. The card carries this occurrence's due time, so the test it offers can anchor its successor there rather than on the moment the button happens to be pressed.

    Parameters

    Returns Promise<void>

    A promise that resolves once the check card is posted.

  • Intrinsic-action executor for the Course Test (#556/#557) — the *Test half of an Extended Shock, Coma, or Infection's cycle.

    Rolls one test, moves the condition's Healing Rate by the result, and settles the consequence: a rate of 0 or less is death (Extended Shock and Coma only — an infection's rate floors at 1 and never kills), 6 or better is recovery, and anything between leaves the course running and offers the next test anchored on this occurrence's due time.

    A still-active infection saps the body by its Healing-Rate band each test (#557).

    Exactly one test runs per invocation — a condition that can kill never resolves several rolls from a single click.

    Parameters

    Returns Promise<void>

    A promise that resolves once the outcome and schedule are persisted.

  • Compute derived values that depend on sibling items being initialized.

    Returns void

    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.

  • Re-arm this trauma's persisted schedules into the event queue on every preparation, on every client (issue #588 generic store; #579 consent). The recurrence anchor and interval now live in system.scheduledActions (the retired bespoke last*Date anchors are gone); a reschedule update() replicates, every client re-preps, and this generic re-arm restores the queue — the active GM's included, which alone fires. The executors add, offer to re-add, or clear those entries; finalize() never invents a schedule of its own.

    Returns void

  • The context-menu options — the actions currently available — for this logic's document.

    Returns ContextMenuEntry[]

    The available context-menu entries.

    One entry per action whose visible predicate currently passes (an action's trigger / domain preconditions can hide it); SCRIPT actions are additionally permission-gated when executed. Use this to discover which actions can be performed on the document.

  • Intrinsic-action executor for the recurring healingCheck — the *Check half of a wound's recovery cycle (#1181).

    A *Check offers, and does nothing else: it posts a card whose button invites the wound's controller to perform one healingTest. No roll is made, no Injury Level changes, and nothing is written. Because it imposes nothing it carries no ownership gate — anyone may initiate one.

    The card carries the occurrence's due time in its scope, so the test it offers can anchor the next occurrence there rather than on the moment the button happens to be pressed.

    Parameters

    Returns Promise<void>

    A promise that resolves once the check card is posted.

  • Intrinsic-action executor for the Injury Healing Test (#486) — the *Test half of the wound's recovery cycle, and the action that actually mends a wound.

    Rolls one test of Healing Base × Healing Rate — the healing modifier, so an Active Effect can change it — and applies the result: a marginal success reduces the Injury Level by 1 and a critical success by 2; a marginal failure makes no progress. A critical failure on an infectable wound contracts an infection, which then halts all healing.

    An untreated wound has no Healing Rate to test against, so its test resolves against a forced die rather than a cast one (#1148) — a Critical Failure every time, which by the same rule leaves it exposed to infection (UNTREATED, #1146).

    Exactly one test runs per invocation: there is no catch-up over missed intervals. A wound that reaches Level 0 ends the recurrence and may leave a permanent impairment scaled by how long it took to heal (#554); otherwise the next test is offered, anchored on this occurrence's due time rather than on now.

    Parameters

    • context: sohl.entity.action.SohlActionContext

      The action context; scope.dueAt carries the occurrence's due time (supplied by the check card) and scope.schedule pre-answers the follow-on offer.

    Returns Promise<null | { level: number }>

    The resulting Injury Level, or null when the roll was refused.

  • Set up base state from persisted data: create ValueModifiers, set base values.

    Returns void

    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.

  • Intrinsic-action executor for the recurring pallRecovery — the *Check half of this condition's cycle (#1181).

    A *Check offers, and does nothing else: it posts a card whose button invites the owner to perform one pallRecoveryTest. No roll is made and nothing is written, so it imposes nothing and needs no ownership gate — anyone may initiate a Pall Recovery Check. The card carries this occurrence's due time, so the test it offers can anchor its successor there rather than on the moment the button happens to be pressed.

    Parameters

    Returns Promise<void>

    A promise that resolves once the check card is posted.

  • Intrinsic-action executor for the Pall Recovery Test — the *Test half of this condition's recovery cycle (#1181).

    Rolls one headless Will test and applies its outcome; exactly one runs per invocation, however much world time has elapsed. The condition ends when its level reaches 0; otherwise the next test is offered, anchored on this occurrence's due time rather than on now.

    Parameters

    Returns Promise<void>

    A promise that resolves once the outcome and schedule are persisted.

  • Intrinsic-action executor for the recurring psycheRecovery — the *Check half of this condition's cycle (#1181).

    A *Check offers, and does nothing else: it posts a card whose button invites the owner to perform one psycheRecoveryTest. No roll is made and nothing is written, so it imposes nothing and needs no ownership gate — anyone may initiate a Psyche Stress Recovery Check. The card carries this occurrence's due time, so the test it offers can anchor its successor there rather than on the moment the button happens to be pressed.

    Parameters

    Returns Promise<void>

    A promise that resolves once the check card is posted.

  • Intrinsic-action executor for the Psyche Stress Recovery Test (#560) — the *Test half of a psychological condition's recovery.

    Rolls one headless Will test (fatigue does not apply). MS/CS recover −1/−2 PSY; a CF is a Grievous Stress — an indefinite condition becomes permanent, or a permanent one gains +1 PSY. An indefinite condition goes away when its PSY reaches 0; otherwise the next test is offered, anchored on this occurrence's due time.

    Parameters

    Returns Promise<void>

    A promise that resolves once the outcome and schedule are persisted.

  • 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.

    Parameters

    • context: sohl.entity.action.SohlActionContext<
          {
              priorTestResult?: sohl.entity.result.SuccessTestResult;
              rollMode?: string;
              situationalModifier?: number;
              successLevelMod?: number;
          },
      >

      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.

    Returns Promise<undefined | sohl.entity.result.SuccessTestResult>

    The re-evaluated result, or undefined when refused (non-GM), cancelled (dialog dismissed), or unchanged (no-op).

  • Serialize this logic to a plain reference.

    Returns PlainObject

    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.

  • Record a treated Healing Rate on this wound — the Treat Injury action. Self-sufficient: run from the wound's context menu it opens a dialog for the Healing Rate; invoked from a physician's Treatment Result Accept button it reads scope.healingRate with skipDialog, so the patient records the physician's proposed rate with one click. A HEAL sentinel (only reachable from a card) heals the wound outright.

    Every value the dialog can yield is a Healing Rate — including 0, which is the dire rate that leaves the wound making no progress, never a cure. A wound whose rate is still undetermined (healingRateBase null) opens the dialog blank rather than pre-filled with 0, and a blank submission records nothing (issue #1087).

    Parameters

    Returns Promise<undefined | { healingRate: number | "HEAL" }>

    The recorded Healing Rate, or undefined when none was supplied / the dialog was cancelled or left blank.

  • Roll the Physician Treatment Test (#553), establishing this injury's Healing Rate and its special effects.

    Intrinsic-action executor for the treatmenttest action. The wound's aspect and severity band select the required treatment action and its difficulty modifier (requiredTreatment); the owning being's Physician skill is rolled headlessly at that modifier; and the result maps, with the severity band, to the injury's Healing Rate (treatmentOutcome). A HEAL result heals the wound outright. The resulting Healing Rate (with the aspect and any surgical mishap) then determines the special injury effects — a bleeder (which arms the blood-loss timer) and permanent-impairment eligibility.

    With no owning being able to roll (a headless/GM context, until the interactive physician card of #547 exists), the treatment auto-resolves as though the Physician roll were a Critical Failure — the rule that "an untreated wound is resolved as though its treatment roll were a Critical Failure."

    Parameters

    • context: sohl.entity.action.SohlActionContext

      The action context for the test; forwarded to the blood-loss schedule offer when a treatment leaves the wound bleeding.

    Returns Promise<null | sohl.entity.result.SuccessTestResult>

    The success test result, or null for a non-injury/healed trauma or a headless critical-failure resolution.