A broad anatomical region grouping one or more body parts — e.g. "Head" (holding the head part), "Arms" (holding the left and right arms), "Legs".

Zones are the first stage of hit determination. Each zone owns a contiguous run of zone numbers sized by its BodyZone.Data.probWeight, allocated in persisted order across the whole body — so a body whose zones weigh 3 / 5 / 2 hands out 1–3, 4–8, 9–10. A single roll against sohl.entity.body.BodyStructure.maxZoneNumber therefore selects a zone; the part and location draws follow inside it.

Persistence: zones are stored in the flat body.structure.zones array. A zone does not nest its parts — parts declare their owner via sohl.entity.body.BodyPart.Data.bodyZoneCode, and sohl.entity.body.BodyStructure assembles the hierarchy at construction.

Lifecycle: Rebuilt from persisted schema data on every preparation cycle. May be mutated during the lifecycle (e.g., modifiers applied by active effects), but mutations are not persisted — they are recomputed on the next cycle.

Hierarchy (View Summary)

Constructors

Properties

index: number

Zero-based index of this zone within the flat structure.zones array.

name: string

Display name of this zone (falls back to the shortcode).

Body parts belonging to this zone, in persisted order.

shortcode: string

Unique zone identifier within the body structure (e.g. "arms").

Back-reference to the owning BodyStructure.

zoneNumbers: number[]

The contiguous run of zone numbers this zone answers to, e.g. [4, 5, 6, 7, 8]. Sized by the persisted BodyZone.Data.probWeight and allocated at construction. Empty when the zone has no weight (it can never be rolled).

The weight is deliberately not wrapped in a ValueModifier: a zone's numbers are positional — changing one zone's weight shifts every later zone's run — so the allocation has to come from the persisted value alone. An active effect that could move the ranges mid-cycle would desync every zone above it.

Accessors

  • get kind(): string
  • 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.

    Returns string

  • get parent(): SohlLogic<any>
  • The Logic that owns this entity. Always present (the constructor rejects a missing parent) and transient — it is not serialized and is re-supplied when the entity is revived or cloned.

    Returns SohlLogic<any>

  • get updatePath(): string
  • The dot-notation path prefix for Foundry update() calls targeting this zone's persisted fields, e.g. "system.body.structure.zones.1".

    Returns string

Methods

  • Build an update() payload that appends a new part to this zone, stamping it with this zone's shortcode. The part lands at the end of the flat parts array — and so at the end of this zone's parts.

    Parameters

    • partData: sohl.entity.body.BodyPart.Data

      Persisted data for the part to append; its bodyZoneCode is overwritten with this zone's shortcode.

    Returns PlainObject

    A complete-array update() payload appending the part.

  • Find a part by its position within this zone, or undefined if out of range. Note this is the zone-relative position, not the part's BodyPart.index into the flat parts array.

    Parameters

    • position: number

      Zero-based position of the part within this zone.

    Returns undefined | sohl.entity.body.BodyPart

    The part at that position, or undefined if out of range.

  • Whether the given zone number falls within this zone's allocated run.

    Parameters

    • zoneNumber: number

      The rolled zone number.

    Returns boolean

    true when this zone owns that number.

  • Build an update() payload that removes a part of this zone by shortcode, cascading to that part's hit locations.

    Parameters

    • shortcode: string

      Shortcode of the part to remove.

    Returns PlainObject

    A complete-array update() payload with the part and its locations removed, or {} when this zone has no such part.

  • Serialize this instance to a plain object suitable for JSON serialization.

    Returns PlainObject

    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.