Saxonberg Server API
    Preparing search index...

    Creature concrete class — a living body. Character extends this and adds agency. Agent already registers the top-level branch; Creature does not re-register.

    Hierarchy

    • CreatureBase
      • Creature
    Index

    Constructors

    Properties

    Accessors

    Methods

    _setRestingOn absorbDigestion absorbToxin addAlternateName addContainable adjustReserve afflict applyAntidote applyContainer applyDeath basalDrain bodyTau canEvict canOccupy clearAffliction clearBurdens clearDisguise contentsCapacity coupledRecovery currentRestQuality destroy drainForTraversal driftCore effectiveAmbient effectiveR emitCue ensureAffliction exhale findAffliction getAge getAllOccupants getAlternateNames getBAC getBarrier getBorneBurden getBreathableMedia getCarryCapacity getCauseOfDeath getConditionBand getConditions getConsciousness getContainer getContents getContentsTemperature getDeepContents getDisguise getFullName getHonorific getIllustration getInjuredParts getLastMealLabel getLastTouched getLifecycleState getLoadRatio getLong getLongDescription getMarkupLong getMass getMaterial getName getNameSuffix getOccupant getOccupantCount getOccupants getPart getParts getPostmortemProgressions getPosture getPresentation getPresentationMml getReserve getReserves getRestingOn getRootContainer getSetpoint getSex getShort getShortDescription getSlotNames getSlotSpec getSpecies getStaticSlots getStrainCeiling getSurfaceTemperature getSurname getTau getTemperature getTemplatePath getValidSexSet getVitalBand getVitalSign getZone hasAlternateName hasCondition hasContainable hasReserve ingest inhale installBiologicalReserves integrateSlice integrateThermalSlice isDestroyed isHoldingBreath isRespiring isSlotDisabledByAnatomy isSlotFull isSlotOccupied mediumConductivity metabolicNowSeconds noteShiver noteSweat occupy onDestruct onMoved onTraversed readCore reassess reconcileAnoxiaCascade reconcileCascade reconcileMetabolism reconcileThermal reconcileThermalCascade reconcileThermalRegulation reconcileToxinConditions regNowSeconds relieve removeAlternateName removeContainable removeReserve reserveCurrent resolveToxinBehavior respirationDrainTick respirationNowSeconds respirationRecoverTick restamp routeIntake routeTag seedMassFromBodyPlan setAge setAlternateNames setBarrier setCachedHumidity setCauseOfDeath setContainer setContentsTemperature setCore setDigestionPools setDisguise setEffectiveAmbientK setHonorific setIllustration setLastAmbientK setLastMealLabel setLifecycleState setLiquidVolume setLongDescription setMass setMaterial setMetabolicClockStamp setName setNameSuffix setPosture setReserve setRespirationClockStamp setSetpoint setSetpointK setSex setShortDescription setSolidVolume setSpecies setStampedTemperatureK setStaticSlots setSurname setTemplatePath setThermalClockStamp setThermalRegStamp setToxinBurdens setVitalSign setZone spo2Throttle strategy thermalCapacity thermalMultiplier thermalNowSeconds toString touch vacate vacateSole vomit wetBulbK wornInsulationKelvin wouldExceedCeiling cleanupOnDestruct

    Constructors

    Properties

    _bloodPressureDiastolic: Quantity<"mmHg"> = ...
    _bloodPressureSystolic: Quantity<"mmHg"> = ...
    _bloodVolume: Quantity<"L"> = ...
    _coreTemperature: Quantity<"K"> = ...
    _detailMaterialPaths: Record<string, string> = {}

    Per-Detail Material overrides — flat map from detailKey to the Material's templatePath. Stored as a plain Record (not a Map) so default JSON serialization handles it without a marshaller.

    _heartRate: Quantity<"bpm"> = ...
    _materialPath: string | null = null

    Path to the bulk default Material singleton. Resolved lazily on each getMaterial() call so HMR replacement is observed immediately.

    _respiratoryRate: Quantity<"bpm"> = ...
    _restingOn: Stuff & Surfaced | null = null

    Runtime-only auxiliary support pointer — Pattern B live ref. Holds a direct reference to the supporting Surfaced host (null when no support). NOT in persistentFields; resets to null on hydrate. R2.3 self-heal in getRestingOn clears the slot if the supporter has been destructed.

    Pattern B chosen over Pattern A templatePath stamping because non-singleton surfaces (e.g., multiple identical tables in a dining hall) can't be addressed unambiguously by templatePath. The cross-restart loss is small — items reappear in their container, just without the on-surface precision.

    _speciesPath: string | null = null

    Path to the Species singleton this organism belongs to. Resolved lazily on each getSpecies() call so HMR replacement is observed immediately.

    _spo2: Quantity<"%"> = ...
    age: number = 0

    Years (or species-appropriate units; v1 doesn't enforce). 0 at birth/clone-time. Aging is deferred to follow-on builds.

    alternateNames: AlternateName[] = []
    barrier: string | null = null

    Medium-tag override ('air'/'water'/'vacuum'); null = default.

    bodyPartDeltas: Record<string, BodyPartDelta> = {}
    cachedHumidity: number = 50

    Cached resolved humidity (%) for the wet-bulb read.

    causeOfDeath: string | null = null
    conditions: ActiveCondition[] = []
    contents: Set<Stuff & Containable> = ...

    The contained items. Read access goes through getContents(); mutation goes through addContainable / removeContainable, which only Containable.setContainer may legitimately invoke.

    digestionPools: Record<string, number> = {}

    The digestion-buffer per-tag pools (%-fill to deliver per tag).

    effectiveAmbientK: number = THERMAL_DEFAULTS.SETPOINT_K

    Cached effective ambient (raw K) — biome + warmth + clo + transforms.

    environment: Stuff & Container | null = null

    Live reference to the container. NOT a persistent field — cross-Stuff references would round-trip badly through the Hydrator's reflection. The container relationship is rebuilt at clone time via the applyContainer instruction-field path (see static instructionFields above) or by direct ContainmentApi.move calls after hydration.

    Auxiliary restingOn is different — it's a Pattern A path-string (_restingOnPath) that DOES persist; see static persistentFields below.

    honorific?: string
    illustration: string | null = null
    lastAmbientK: number = THERMAL_DEFAULTS.DEFAULT_TEMPERATURE_K

    Cached resolved ambient (raw K) the object is drifting toward.

    lastMealLabel: string | null = null

    Last-eaten material name — for vomit prose only (no accounting).

    lifecycleState: string = ''

    Current lifecycle state — one of the species' valid set ('alive', 'dead', 'undead', 'powered', 'unpowered', 'destroyed'). Initial value lives on the leaf template's data per slate. Empty default keeps unhydrated test fixtures trivially constructable.

    liquidVolume: number = 0

    Liquid sub-volume (litres) — filled by drink / sip.

    longDescription: string = ''
    metabolicClockStamp: number = 0

    Game-time (seconds) of the last reconcile; 0 = unseeded.

    name: string = ''
    nameSuffix?: string
    posture: string = Postures.Stand
    reserves: Record<string, ReserveStored> = {}

    Storage — public for the Hydrator.

    respirationClockStamp: number = 0

    The only persisted field — the drain's elapsed anchor.

    setpointK: number = THERMAL_DEFAULTS.SETPOINT_K

    Setpoint (K) the body defends — the movable fever/magic seam.

    sex: string | null = null
    shortDescription: string = ''
    slots: Map<string, Set<Stuff & Slottable>> = ...

    Live runtime occupancy. Direct refs (proxy framework intercepts on use). Each slot's value is the set of current occupants; empty set when unoccupied. Not in persistentFields — starts empty on clone / hydrate.

    solidVolume: number = 0

    Solid sub-volume (litres) — filled by eat.

    stampedTemperatureK: number = THERMAL_DEFAULTS.DEFAULT_TEMPERATURE_K

    Stamped temperature T0 (raw K) — the decomposed scalar.

    staticSlots: SlotSpec[] = []

    Authoring data — only used by the default getSlotNames / getSlotSpec implementation. Hosts that override the universe surface (BodyPlanSlots, Adornable) leave this empty.

    stuffId: string

    Runtime ID for this object (generated using nanoid). This is NOT the MongoDB _id - it's a runtime identifier.

    surname?: string
    thermalClockStamp: number = 0

    Game-time (seconds) of the last reconcile / re-stamp; 0 = unseeded.

    thermalRegStamp: number = 0

    Game-time (seconds) of the last regulation reconcile; 0 = unseeded.

    toxinBurdens: Record<string, number> = {}

    Sparse per-toxin body burdens (Wave 2; created on first exposure).

    _mixinName: string = 'LoadBearingMixin'
    commandContributions: CommandContributions = ...

    Command provider for inventory management commands

    fieldMarshallers: {
        _bloodPressureDiastolic: string;
        _bloodPressureSystolic: string;
        _bloodVolume: string;
        _coreTemperature: string;
        _heartRate: string;
        _respiratoryRate: string;
        _spo2: string;
    } & { mass: string } = ...

    Field-marshaller binding. mass round-trips via the kg-bound QuantityMarshaller; the runtime accessor pair stays strict on Quantity<'kg'>. Authoring-shape coercion (mass: heavy, mass: "12000 g", bare numeric) lives in the marshaller's fromStored and only runs on the persistence path.

    instructionFields: string[] = ...

    Instruction field — declarative spawn target. Consumed by Phase 2 of the Hydrator. There is NO paired getContainer(path) declaration accessor; the live getContainer() ref is the only runtime getter.

    markupAugmenters: MarkupAugmenter[] = ...

    Markup-augmenter contribution. senseStripAugmenter reads the per-call filter from AugmentOpts and the viewer's sensorium (derived from BodyPlan.getModalities()), and drops <sense channel="X">…</sense> regions and <detail sense="X"> wrappings whose channel isn't in filter ∩ sensorium.

    Lives on VisibleMixin (not DetailedMixin) because <sense> regions can appear in any Visible-mixed long, with or without detail authoring. Ordering: VisibleMixin sits above Detailed in the typical composition chain, so the parent-first walker runs senseStripAugmenter BEFORE wrapDetailKeysAugmenter — strip-then-wrap is correct because wrapping inside a region destined for the strip is wasted work.

    persistentFields: string[] = ...

    Persistent fields declared by this mixin. Used by PersistApi for automatic synchronization.

    subscribableFields: SubscribableFieldDescriptor[] = ...

    Derived readouts surfaced through the live-query / inspection substrate (the Tangible.mass precedent). No event wiring in v1 — these are pure derived reads re-resolved on demand.

    Accessors

    • get fullName(): string

      Host-internal accessor for the formal canonical form. Public surface is getFullName(). Used at introductions, character info screens, disambiguation — not the default for everyday prose. Most callers should read getName() directly.

      Layout:

      [honorific] [name] [surname][, nameSuffix]

      The comma before nameSuffix is universal for credentials ("John Smith, MD", "John Smith, PhD", "John Smith, Esq.") and a defensible older-style for generational suffixes ("John Smith, Jr.") — common in legal documents and personal signatures even where AP/Chicago have dropped it. Regnal numerals ("Henry VIII") would render incorrectly here, but those aren't a v1 use case; if they become one, model them via alternateNames rather than nameSuffix.

      Returns string

    Methods

    • Privileged setter for the auxiliary restingOn pointer. Reachable only from ContainmentApi.move / ContainmentApi.placeOn. Pass null to clear.

      Stores the supporting Surfaced ref directly (Pattern B); runtime-only — see the field declaration's JSDoc for the persistence rationale.

      Parameters

      Returns void

    • Step 1 — drain each pooled tag toward its reserve at its own rate, and shrink the sub-volumes proportionally so the stomach empties as it digests (reopening the cap). Wave 2 routes toxin pools into burdens here.

      Parameters

      • stepMin: number

      Returns void

    • Drain a toxin's un-absorbed pool dose into its body burden. Alcohol (storeRaw) accumulates the raw absorbed grams; every other toxin accumulates absorbed × potency / bodyMass (dose-response). The burden entry is created on first exposure and never widened.

      Parameters

      Returns void

    • State-mutation primitive. Locked down — only callable from Containable.setContainer. Use ContainmentApi.move(item, container) from application code.

      Fires FieldChangedEvent { field: 'contents' } after a real addition so the MQL subscription substrate's dependency index picks up containment-shape changes for the contents descriptor. The substrate matches on (KIND, 'field', 'contents') only — oldValue / newValue are inspected by the diff pass via re-projection of the host, not by the index, so the count delta carried here is informational (debugging / future coarse-grain optimizations) rather than load-bearing.

      Parameters

      Returns void

    • Antidote = accelerated clearance. Crashes a toxin burden in one shot (far faster than natural clearance would), so its banded condition clears on the next reconcile. The minimal consumer of the vitals ResolutionSpec treatment seam (no treatment verb is required by this build — the callable seam + crash mechanism is).

      Parameters

      • toxinType: string

      Returns void

    • Phase 2 applier — see the interface docstring for semantics. Compare-and-move idempotency: no-op when the current container's templatePath matches the declared path; otherwise resolve the target via StuffApi.singleton and ContainmentApi.move into it. The singleton-target invariant is enforced at template-save time by TemplateApi.validateSingletonContainerTarget.

      Parameters

      • path: string

      Returns Promise<void>

    • Step 2 — basal metabolic drain on satiation + hydration, scaled by body mass and the (inert v1) thermal-strategy multiplier.

      Parameters

      • stepMin: number

      Returns void

    • Passive-drift time constant (R·C) for the body — the rate the core floats toward effective ambient when regulation is off. Reuses ThermalMixin.getTau (the body's mass × material × medium/wall resistance); a heavier body drifts slower.

      Returns number

    • Clear path once value re-enters threshold by the hysteresis margin.

      Parameters

      • path: string
      • value: number
      • threshold: number

      Returns void

    • Step 4 — burden clearance. Each live burden falls at its seed's (zero-order) clearanceRate; the entry is deleted at zero.

      Parameters

      • stepMin: number

      Returns void

    • Step 3 — coupled recovery: at rest the body rebuilds endurance by spending satiation + hydration (hydration the tighter leash), rate-limited and scaled by posture × restQuality × spo2-throttle (the last inert in v1). This is the keystone — why recovery lives in metabolism, not encumbrance.

      Parameters

      • stepMin: number

      Returns void

    • The restQuality of the host whose posture slot this body occupies, or 1.0 (the floor / standing with no host). Only an actor that can occupy slots (Slottable) has a host; a bare Creature reads the default.

      Returns number

    • Destroy this object.

      Locked down by @CallSecurity(ApiOnly) — only callers under mud/api/ (in practice, StuffApi.destruct) may invoke it. @Unshadowable because the unregistration path must always run; a shadow that intercepts and skips it would leak the object into the registry forever. @Final because subclass overrides would defeat the same invariant — the loader hook throws FinalViolationError at import time on any subclass redefinition.

      Subclass cleanup belongs on the optional onDestruct() witness (consulted by StuffApi.destruct while the target is still live); refusal logic belongs on canDestruct(). This terminal destroy() is the unshadowable mark-and-unregister step only.

      Returns void

    • Passive Newton's drift of the core toward the effective ambient.

      Parameters

      • coreK: number
      • ambientK: number
      • sliceSec: number

      Returns void

    • Resolve the body's effective ambient — biome ambient + occupied warming-slot warmth + the wind-chill (cold side) / heat-index (hot side) transforms, read through the surrounding medium's conductivity (immersion). async and run only at re-stamp events (placement/move, ambient shift, don/doff); the per-slice reconcile reads the cache effectiveAmbientK synchronously. (Worn clo is applied as a band-widening in integrateThermalSlice, not here.)

      Returns Promise<Quantity<"K">>

    • Blood-alcohol concentration via Widmark — the alcohol burden stores ethanol mass (grams), normalized at the read by body mass and the sex-derived r. BAC (g/L) = grams / (mass_kg × r); converted to g/dL (the 'bac' scale unit). Storing mass keeps the read state-dependent (a lighter / dryer body reads higher).

      Returns Quantity<"g/dL">

    • The accessible band over blood-volume fraction + vitals-out-of- band. Reserves and trauma fold additional load in at the marked seam. A corpse (lifecycleState: 'dead') reads dead; otherwise the band reflects the substrate — it can read critical from a floored vital with NO lifecycle transition (the deferred driver owns transitions).

      Returns ConditionBand

    • Vomit — flush the un-absorbed digestion pools (those tags never reach their handlers) and empty both sub-volumes. Leaves absorbed state intact: reserves already filled and toxinBurdens already accumulated stay. That asymmetry IS the purge mechanic — inducing it early (pools un-absorbed) saves you; late doesn't. Called by the vomit verb and by the involuntary cascade trigger.

      Returns string | null

    • Read the recency timestamp. Read by the residency sweep — which calls it on the raw target (via RAW_TARGET) so the sweep's own introspection never counts as a touch.

      Returns number

    • Affordance-annotated long description — see the interface docstring for the augmenter pipeline contract. Calls Mml.augment with the host (this), the supplied viewer, and the per-call opts (the senses build threads opts.filter through here for verb-specific sense filtering). Every contributing mixin's augmenters run in parent-first → child-last order.

      Parameters

      Returns string

    • Mass override that lazy-seeds the body-grounded default. When the instance authored no mass of its own (still 0), resolve species → bodyPlan → baseMass and adopt it; an explicitly-authored mass is the deviation that wins (the guard short-circuits and this is a plain super.getMass()).

      Runs lazily here rather than from a post-hydrate hook: the postRegister chain is not uniformly threaded below CommandGiver (e.g. Avatar.postRegister does not super-call), so a read-time seed is the one seam that makes mass honest for every reader of every Creature subclass, the moment a body plan is resolvable. The "is mass still 0?" check is the idempotency guard — no persistent "seeded" flag (the project rule); a genuinely 0-mass sessile body simply re-checks cheaply.

      Returns Quantity<"kg">

    • Postmortem-progression seam. Death is living-stop + postmortem-start: living processes freeze and postmortem changes (algor / rigor / livor / decomposition) would begin here. v1 ships ZERO — returns []; the seam exists for a future forensics wave.

      Returns readonly string[]

    • Self-presentation — the casual-register render string for this object, the answer to "what does this Stuff call itself?" Three- step resolution:

      1. Named.name if present and non-empty — the object's proper name ("Alice", "Excalibur", "Town Square").
      2. Visible.shortDescription if present and non-empty — the object's visual identity ("a heavy oak door").
      3. The baked-in fallback (DEFAULT_PRESENTATION).

      For a Globbable stack (quantity !== 1) the count folds in as an affix — "30 coins" — pluralized via GrammarApi.pluralize (which honors host-side getPluralForm() overrides for irregulars). Named takes precedence over Visible so a Named-with-description renders by its proper name; code that needs the formal register calls getFullName() when typed as Named.

      Viewer-blind by design. This is the shared baseline every Stuff exposes; the viewer-aware naming step (recognition / identification — see docs/subsystems/belief.md) composes on top of it. Left shadowable (NOT @Final) so masking / disguise effects can override the rendered identity via a method shadow.

      Returns string

    • Build the composable Mml fragment for this object's display name — the Mml sibling of getPresentation. Mml.ref (and so every <item> / <name> / … identity tag) renders this, not a raw string, so a name joins the compose chain as a fragment like everything else. The label is the already-resolved, viewer-aware name (recognition runs in the render layer and hands it in).

      Return null for the plain default — Mml.ref then wraps the label in Mml.text, which escapes it exactly once, so player-authored names / status decoration are safe by construction and the fragment is never re-escaped downstream. Override to build a richer fragment (a TPA terminal wraps its name in <color> to tint by state). The plain-string getPresentation stays the surface for non-prose consumers (logs, context.note, MQL scalars).

      Parameters

      • _label: string

      Returns Mml | null

    • Resolve the auxiliary restingOn pointer. Pattern B live ref; R2.3 self-heal clears the slot if the supporting surface has been destructed since the last set.

      Returns null when no support OR the supporter has been destructed. The caller can't tell the two apart from the return value; that's deliberate — absence of support is the same observable as a stale ref.

      Returns Stuff & Surfaced | null

    • Walk the container chain to the topmost non-null environment. Returns null when already at the root.

      Containment is acyclic by construction (a Container can't contain its own ancestor — setContainer's atomic update is the chokepoint), so the loop is bounded by the depth of the world's nesting.

      Returns Stuff & Container | null

    • Read seam. Instance method, but unwraps via ProxyApi.unwrap before reaching the # slot — this inside an instance method called through the proxy is the proxy, and the # slot lives on the raw target.

      Returns string | null

    • Lookup the valid sex set from the host's species' sex-determination system. If the host doesn't compose OrganismMixin (degenerate), or the species is unset, returns an empty set — the setter then rejects every value.

      Returns readonly string[]

    • The survivable band for a sign — from the host's species vitalProfile, or the universe default. Requires OrganismMixin (runtime-guarded). The "always composed with Organism" rule lives here, not in a comment.

      Parameters

      • sign:
            | "coreTemperature"
            | "heartRate"
            | "respiratoryRate"
            | "bloodPressureSystolic"
            | "bloodPressureDiastolic"
            | "spo2"
            | "bloodVolume"

      Returns VitalBand

    • Parameters

      • sign:
            | "coreTemperature"
            | "heartRate"
            | "respiratoryRate"
            | "bloodPressureSystolic"
            | "bloodPressureDiastolic"
            | "spo2"
            | "bloodVolume"

      Returns Quantity<Unit>

    • Make ingest real: route the consumed material into the digestion buffer. Picks the sub-volume by phase (the verb decides — eat solid, drink/sip liquid), caps intake at the remaining sub-capacity (the bulk partial-transfer shape — refuse the excess), and fans the material's nutrient tags into per-tag pools scaled by the accepted volume.

      Returns the litres actually accepted, so a caller can hold to result.applied-style semantics (the eat verb consumes a discrete item only on full acceptance).

      Parameters

      Returns number

    • Install the default biological reserves if absent (idempotent).

      Returns void

    • One integration slice (game-seconds), flows in fixed order: (1) digestion absorption, (2) basal drain, (3) coupled recovery. (Wave 2 inserts toxin clearance at step 4.) Each slice is small enough that the per-flow linear approximation is honest and the coupling is respected slice-to-slice.

      Parameters

      • sliceSec: number

      Returns void

    • One integration slice (game-seconds). Resolves the effective ambient (cached), the setpoint, and the clo-widened band, then branches on strategy: an ectotherm / dead / no-fuel body drifts; an endotherm spends to hold the setpoint within the affordable regimes.

      Parameters

      • sliceSec: number

      Returns void

    • Check if this object has been destroyed.

      @Unshadowable: the destroyed-state read is a framework invariant — any shadow that lied about it would let consumers touch a torn-down Stuff. @Final: subclasses overriding this would defeat the same invariant; the loader hook throws FinalViolationError at import time on any subclass that redefines it.

      Returns boolean

    • Coarse part→slot coupling: a missing part disables its slots.

      Parameters

      • slot: string

      Returns boolean

    • The dominant series conductivity (W/(m·K)): the barrier medium when sealed (a Sealable host that is closed → vacuum), else the barrier override, else air (the default surrounding medium for a bare Phase-1 object; the body lifts this to its resolved immersion medium in Phase 2).

      Returns number

    • In-session game-time (seconds), or null when no world clock is present in the world. Metabolism ticks only when a WorldClock registry is bootstrapped (indexed by templatePath) — production always has one; a unit test that hasn't set one up reads null and stays idle (no getNow lazy-create with a wall-clock anchor).

      Returns number | null

    • Terminal onDestruct no-op. Exists so subclasses and mixins overriding onDestruct can call super.onDestruct() without the cast-to-optional-callable dance — the chain is guaranteed to bottom out here. StuffApi.destruct invokes the hook via the optional-method dispatcher in api/stuff.ts; that path still works (always finds a function on the prototype).

      Override (not extend with super) at any layer that wants cleanup; chain to super.onDestruct() from the override so intermediate layers in a mixin chain run too.

      Returns void

      Invoked by StuffApi.destruct (and forceDestruct) while the target is still live, after canDestruct passes and before shadow-detach + destroy(). Witness — the return value is ignored (it cannot veto; canDestruct is the veto seam). Override to release resources/listeners and chain super.onDestruct() so mixin layers run.

    • Containment-move witness — the onMoved hook ContainmentApi.move fires on every mover (carried items, dropped corpses, vessels, bodies). Re-stamps so the object freezes its current temperature under the old scope's ambient and starts drifting toward the new scope's. Load-bearing under the cached-ambient model (Step 1.6 trigger 1): with a sync read there is no lazy re-resolve, so a move that didn't re-stamp would drift toward a stale ambient forever. This is the one event thermal listens to (the genuine divergence from metabolism's pure-lazy model). Chains any inner onMoved witness first.

      Parameters

      Returns void

    • Mirror MetabolicMixin.reconcileCascade for the single anoxia affliction: while spo2 dwells at/below the lethal floor, accrue dwell-time on the asphyxiation affliction and fire the death seam when it exceeds the lethal dwell; clear it on recovery above the floor. Returns whether death fired this tick.

      Parameters

      Returns boolean

    • The cascade — metabolism is the first condition-driver. After the sub-stepped integration, ensure each floored biological reserve's floorEffect-named condition exists, clear it on recovery (hysteresis), and progress the lethal ones toward the death seam.

      Parameters

      • elapsedSec: number

      Returns void

    • Integrate elapsed in-session game-time since the last reconcile. Sub-steps the gap into fixed slices so the coupled flows (basal drain, digestion absorption, recovery, burden clearance) stay honest over a long mixed-activity gap. Freezes on absence (linkdead now; logout via the far-past guard) — real-life absence never starves you. Cheap no-op when too little time has passed or the world clock isn't running.

      Returns void

    • After the slices, spawn / clear the thermal conditions off the driven core (hypothermia / torpor below survivableMin, hyperthermia above survivableMax), accrue dwell, and fire the death seam on lethal accrual. Mirrors metabolism's cascade.

      Parameters

      • elapsedSec: number

      Returns void

    • For each live toxin burden, ensure its one banded condition exists and recompute its severity live — from the derived BAC for alcohol (storeRaw), or the raw burden otherwise — against the seed-authored bands. Cleared when the level falls below the lowest band (no per-band spawn/clear churn; one condition per toxin, severity is a live read on stage).

      Returns void

    • Remove the first alternate matching value. Returns true if something was removed.

      Parameters

      • value: string

      Returns boolean

    • In-session game-time (seconds), or null when no world clock runs (pre-boot, or a unit test that hasn't bootstrapped one) — the metabolism presence guard verbatim, so unit tests stay idle.

      Returns number | null

    • Fan the accepted intake through the per-tag router into the digestion pools. Wave 1 routes the energy tags; Wave 2 extends routeTag to the full macro set + toxins. A static switch over the curated vocabulary, NOT a registry — unknown tags are a no-op so authoring a novel tag never crashes intake.

      Parameters

      Returns void

    • The static tag dispatch — one caller (the ingest decomposition), so a private method, not a security-gated Api. Maps a known nutrient tag to its routing; unknown tags return null (no-op).

      Parameters

      • tag: string

      Returns NutrientRoute | null

    • Resolve the body-plan baseMass and adopt it as this body's mass, returning the seeded quantity (or null when there is no plan / baseMass is absent or 0). Does not read getMass() — the zero-guard lives in getMass, so this stays recursion-free and is the single place the body-grounded default is applied.

      Returns Quantity<"kg"> | null

    • State-mutation chokepoint. Reachable only from ContainmentApi.move; cross-Container contents mutation must not be subclass-extensible (@Final) or shadow-bypassable (@Unshadowable).

      Atomic across three updates: detach from the old container, attach to the new, update the field. null argument is the detach case; the policy rejects calls from anywhere other than ContainmentApi, so setContainer(null) outside the Api throws — the legitimate detach is ContainmentApi.move(item, null).

      Parameters

      Returns void

    • Set the fluid temperature directly and re-anchor the drift clock — the bulk-coupling primitive (refill to incoming, calorimetric mix blend, pour-preserve-at-reduced-C). Freezes the current temperature to now under the existing ambient first, then adopts the supplied value and restarts drift from it.

      Parameters

      • k: number

      Returns void

    • Strict on Quantity<'kg'>. Callers holding a raw number wrap via Quantity.of(n, 'kg') at the call site; tag / alt-unit authoring is the marshaller's job, not a runtime API concern.

      Parameters

      Returns void

    • Stamp this Stuff's templatePath and re-key the byTemplatePath index so future findByTemplatePath lookups see the new path. No-op when path matches the current value.

      Locked down by @CallSecurity(ApiOnly) because flipping a Stuff's identity post-clone would break FromTemplate policies and any caller-side caching of template-path identity. @Final @Unshadowable because the index update has to run for every successful set — a subclass override that forgot the index call (or a shadow that intercepted) would silently desync byTemplatePath.

      Unwraps via ProxyApi.unwrap so the #-slot access lands on the raw target (see comment on #templatePath above).

      Parameters

      • path: string

      Returns void

    • Parameters

      • sign:
            | "coreTemperature"
            | "heartRate"
            | "respiratoryRate"
            | "bloodPressureSystolic"
            | "bloodPressureDiastolic"
            | "spo2"
            | "bloodVolume"
      • value: Quantity<Unit>

      Returns void

    • Set the spatial zone. Gated by FromSpatialZone — only the SpatialZone class and its subclasses (CartesianZone, SphericalZone) may call this through the proxy. The addLocation / removeLocation chokepoints on the zone side are the legitimate callers; everyone else is rejected.

      Clone-time seeding from StuffApi.#cloneInner doesn't go through this method — it uses the caller-allowlisted _stampZone seam below.

      @Final @Unshadowable because the index of substrate invariants that consult getZone() (containment's cross-zone gate, Mobile.traverse, MQL scope walks) trusts the slot's value; a subclass override or shadow that lied about it could break those invariants. No legitimate subclass needs to extend this anyway — the only legitimate write paths are the SpatialZone chokepoints and clone-time.

      Parameters

      Returns void

    • Respiration read — low spo2 would throttle recovery. v1 reads the sign for the seam's presence but returns 1.0 unconditionally; lights up when respiration drives spo2.

      Returns number

    • Heat capacity C = mass × specificHeat (J/K). For a vessel whose Thermal IS its contents (Bulkable interior with fluid), C derives from the held fluid — more contents → larger C → slower cooling, free (a full thermos holds heat longer than a near-empty one). Falls back to the host's own mass × material when empty / not a vessel.

      Returns number

    • Q10 temperature coefficient on basal metabolic rate. Reads the driven coreTemperature (the thermal build's getVitalSign override drives it) and scales basal drain by Q10 ^ ((core − reference) / 10). For an endotherm pinned at its setpoint this is ≈ 1 (the core sits at the reference); for an ectotherm whose core floats to the weather, basal drain swings — a cold reptile burns far less fuel. The strategy difference falls out of where the core sits, so no branch is needed here. The dials live in METABOLIC_DEFAULTS (metabolism owns its rates).

      Returns number

    • In-session game-time (seconds), or null when no world clock is bootstrapped — thermal stays idle (the metabolism now-source guard verbatim). Production always has a clock; a unit test that hasn't set one up reads null and never drifts.

      Returns number | null

    • Refresh the recency timestamp to now. Timestamp-fixed (no caller-supplied value). Called on the raw target by the security gate on every successful dispatch (Phase 2) and by the residency presence walk.

      Returns void