A movable inanimate conveyance.

A Vehicle represents a wagon, ship, cart, or any mobile platform that can hold both occupants and embedded items (cargo, equipment, etc.). Vehicles are not Beings — they have no anatomy, skills, or traits.

Occupants are tracked as an array of actor shortcodes. Each shortcode may reference either a Being (a single individual) or a Cohort (which is shorthand for all of that Cohort's members being occupants).

Vehicles can own Protection items (hull armor, reinforced sides), Injuries (structural damage), Container Gear (cargo holds), and 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).

The actor's tactical move (feet per combat round) as a sohl.entity.modifier.ValueModifier so runtime modifiers (haste, encumbrance, etc.) can layer on. Seeded from the active moveProfile when it is enabled.

The actor's overland travel speed (leagues per watch) as a sohl.entity.modifier.ValueModifier. Seeded from the active moveProfile when it is enabled.

moveProfile: MovementProfile

The active movement profile, selected during initialize by this actor's SohlActorData.currentMoveMedium. A disabled MOVEMENT_MEDIUM.NONE profile when the actor has no matching profile (a non-mover).

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

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

  • Resolve cross-item dependencies that require all items to have been evaluated.

    Returns void

    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.

    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.

  • Find an embedded item's logic by its shortcode and item kind.

    Type Parameters

    • K extends ItemKind

      The item kind, inferred from the type argument.

    Parameters

    • shortcode: string

      The item's system.shortcode.

    • type: K

      The ItemKind to match (e.g. ITEM_KIND.SKILL).

    Returns undefined | ItemLogicByKind[K]

    The matching item's logic typed for type, or undefined if no item matches.

    Both arguments are required: a shortcode is only unique within a given item kind, so matching the type as well prevents returning an unexpected item that happens to share the shortcode. The item kind also drives the return type — the concrete logic for that kind is resolved from ItemLogicByKind, so no cast is needed at the call site:

    const stealth = actor.logic.getItemLogic("stealth", ITEM_KIND.SKILL);
    // ^? SkillLogic | undefined
  • Find an embedded item's logic by its id.

    Parameters

    • id: string

      The item's id.

    Returns undefined | SohlItemLogic<any>

    The matching item's logic or undefined if no item matches.

  • Handle a trigger dispatched by the SoHL event queue. Override in subclasses to implement actor-specific trigger handling.

    Parameters

    • kind: string

      Subscription kind identifier

    • _context: SohlTriggerContext

      Trigger context (discriminated by context.name)

    • Optional_payload: Record<string, unknown>

      Optional context data attached when subscribing

    Returns Promise<void>

  • Set this actor's SohlActorData.currentMoveMedium — the active movement profile — to the medium carried in the action scope.

    Intrinsic-action executor for the makeDefaultMedium action.

    Parameters

    Returns Promise<void>

    Resolves once the actor update completes, or immediately when no medium was chosen.

    The Profile-tab star names the medium in scope and applies it directly. Invoked any other way — from the Actions menu, a macro, a script — there is no medium to apply, so the action offers the choice (the prefer-dialog rule) rather than returning silently as it once did (#1098). The prompt lists the no-movement medium plus every medium this actor authors a profile for, preselected at the current one. A caller that suppressed the dialog cannot be prompted, so it gets a notice instead of an unexplained no-op.

  • GM re-edit of a settled opposed contest (#1082) — the edit pencil in the Opposed Action Result card's header, and the two-sided counterpart to the standard card's sohl.document.item.logic.SohlItemBaseLogic.resultEdit (#856).

    Re-opens the standard test dialog for each side in turn, pre-filled with that side's current situational and success-level modifiers, applies the new values, re-evaluates the contest on both frozen rolls (never a re-roll, no Fate cost), and reposts the Opposed Action Result card. The settled contest rides in context.scope.opposedTestResult — the whole result serialized into the pencil's data-scope and revived by the chat-card dispatcher — so the edit acts on that contest.

    The contest lives only in the chat log, never on a document, so an edit mutates nothing persistent: it posts a new, corrected card and leaves the original standing (see the action-card consent model). Dismissing either side's dialog cancels the whole edit — no re-evaluation, no repost.

    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<
          {
              opposedTestResult?: sohl.entity.result.OpposedTestResult;
              source?: { situationalModifier?: number; successLevelMod?: number };
              target?: { situationalModifier?: number; successLevelMod?: number };
          },
      >

      The action context; context.scope.opposedTestResult is the settled contest. When skipDialog is set, each side's new situationalModifier / successLevelMod are taken from context.scope.source / context.scope.target instead of the dialogs.

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

    The re-evaluated contest, or undefined when refused (non-GM), missing a contest, or cancelled (a dialog dismissed).

  • Build an update() payload removing the occupant with the given handle.

    Unlike a cohort, there is no leader to clear alongside it — a vehicle's complement has roles but no single head.

    Parameters

    • actorCodeOrUuid: string

      The handle of the occupant to remove.

    Returns PlainObject

    An update payload (does not itself persist the change).

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