Saxonberg Server API
    Preparing search index...

    Hierarchy

    • __type<typeof NPC, this> & NPC<this>
      • default
    Index

    Constructors

    Properties

    Accessors

    Methods

    _clearEngagement _dispatchBound _executeOne _removeEmployment _runChain _setEmploymentStatus _setEngagement _setRestingOn _upsertEmployment absorbDigestion absorbToxin addAlternateName addContainable adjustReserve afflict allBeliefs announceArrival announceDeparture applyAntidote applyContainer applyDeath autoIntroduceOnArrival autoSenseOnArrival basalDrain bodyTau canEvict canOccupy canSeeOverride clearAffliction clearBeliefs clearBurdens clearDisguise contentsCapacity coupledRecovery currentRestQuality defaultArrivalPeers defaultArrivalSelf defaultDeparturePeers defaultDepartureSelf defaultTeleportInPeers defaultTeleportInSelf defaultTeleportOutPeers defaultTeleportOutSelf destroy dispatchMovementScene drainForTraversal driftCore effectiveAmbient effectiveR emitCue emote emoteFree ensureAffliction executeCommand exhale filterEnvelope filterMessage findAffliction forget forgetField getActiveEmployment getAffordances getAge getAllOccupants getAlternateNames getAspiration getAvailableCommands getBAC getBarrier getBehaviors getBio getBorneBurden getBreathableMedia getCarryCapacity getCauseOfDeath getConditionBand getConditions getConferredMixinNames getConsciousness getContainer getContents getContentsTemperature getDeepContents getDisguise getEmployment getEmployments getEngagedMode getEngagementBySlot getEngagementByType getEngagements getFullName getHaulDraft getHauledCart getHonorific getIllustration getInjuredParts getInstanceContributions getLastMealLabel getLastTouched getLifecycleState getLoadRatio getLong getLongDescription getMarkupLong getMass getMaterial getName getNameSuffix getOccupant getOccupantCount getOccupants getPart getParts getPostmortemProgressions getPosture getPresentation getPresentationMml getPronouns getReserve getReserves getRestingOn getRootContainer getSetpoint getSex getShort getShortDescription getSlotNames getSlotSpec getSpecies getStaticSlots getStatus getStrainCeiling getSurfaceTemperature getSurname getTau getTemperature getTemplatePath getValidSexSet getVisionProfile getVitalBand getVitalSign getZone handleEnvelope handleMessage hasAlternateName hasCondition hasContainable hasEngagement hasReserve hitch ingest inhale installBiologicalReserves integrateSlice integrateThermalSlice introduceSelf isDestroyed isEngagedIn isHitched isHoldingBreath isMaker isOnShift isRespiring isSlotDisabledByAnatomy isSlotFull isSlotOccupied know loadBelief mediumConductivity metabolicNowSeconds noteShiver noteSweat occupy onConnectionAttached onDestruct onEnvelope onMessage onMoved onSlotReleased onTraversed perceivedBandModifier popCommandSource postRegister pushCommandSource readCore reassess recall recallRealm reconcileAnoxiaCascade reconcileCascade reconcileMetabolism reconcileThermal reconcileThermalCascade reconcileThermalRegulation reconcileToxinConditions refreshConferrals regNowSeconds relieve removeAlternateName removeContainable removeReserve renderEmote renderFreeForm reserveCurrent resetCommandSources resolveArrivalMessage resolveDepartureMessage resolveToxinBehavior respirationDrainTick respirationNowSeconds respirationRecoverTick restamp routeIntake routeTag say seedMassFromBodyPlan setAge setAlternateNames setAspiration setAuthoredStatus setBarrier setBio setCachedHumidity setCauseOfDeath setContainer setContentsTemperature setCore setDigestionPools setDisguise setEffectiveAmbientK setEngagedMode setHonorific setIllustration setLastAmbientK setLastMealLabel setLifecycleState setLiquidVolume setLongDescription setMass setMaterial setMetabolicClockStamp setName setNameSuffix setPosture setPronouns setReserve setRespirationClockStamp setSetpoint setSetpointK setSex setShortDescription setSolidVolume setSpecies setStampedTemperatureK setStaticSlots setStatus setSurname setTemplatePath setThermalClockStamp setThermalRegStamp setToxinBurdens setVitalSign setZone shout spo2Throttle strategy teleport thermalCapacity thermalMultiplier thermalNowSeconds toString touch traverse unhitch vacate vacateSole vomit wetBulbK whisper wornInsulationKelvin wouldExceedCeiling __validateComposition__ 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[] = []
    aspiration: string | null = null

    Closed-choice origin/aspiration key (or null if unset).

    authoredStatus: string = ''
    barrier: string | null = null

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

    behaviors: BehaviorSpec[] = []
    bio: string = ''

    Claimed narrative prose. Seeded at char-gen; editable later.

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

    dispositions: ClaimSeed[] = []

    An authored host's established character, as disposition claim seeds — pure data, persisted as-is. Seeded into the trait ledger once at spawn (postRegister) so derive-on-read yields the host's defining traits immediately, while keeping personality derive-don't-track (it came from a seeded history, not a stat). The behavior→trait edge this introduces is the same one the trait-aware brains already establish.

    effectiveAmbientK: number = THERMAL_DEFAULTS.SETPOINT_K

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

    employments: EmploymentData[] | null = null

    Stored employment records (plain data). Sparse: null on an unemployed Character (nothing written to the doc). Wrapped into Employment value objects on read.

    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
    pronouns: Pronouns = Pronouns.They
    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).

    _augmentGated: boolean = true

    Augment-gated: composing MakerMixin is necessary but not sufficient. The role is active only while a conferral grants it (MixinApi.isActive / getActiveMixins) — for the bar staff, the on-shift Position's confers: ['MakerMixin'] surfaced via EmployedMixin.getConferredMixinNames. So an off-shift (or never- employed) Crafter is composed-but-inactive, and MixinApi.isMaker (now routed through isActive) selects only the on-shift bartender as the order fulfiller. See docs/subsystems/augmentation.md.

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

    The bands-only self-view. Zero-arg, read-only, self-only — the chronicle-verb shape. Afforded statically; the conferred verbs (below) are pushed dynamically.

    defaultAliases: DefaultAliasEntry[] = ...

    Default aliases for the 10 canonical cardinal directions (NavigationApi.cardinalDirections()) plus their conventional single/double-letter abbreviations. Every entry expands to go <full-name>, which dispatches through GoController and resolves the actor's currently-engaged locomotion mode at run time — so n does the right thing whether the actor is walking, swimming, or climbing.

    Composed onto any host that also composes AliasMixin (the collector walks the mixin chain). Hosts without alias support pay no cost. Player-set aliases on the same name win.

    The cockpit's <exit> click emits the full go <dir> form for pedagogy; these aliases give keyboard users the short forms they expect from MUD muscle memory.

    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[] = ...

    The declarative spec list — pure data, persisted as-is.

    settings: SettingsSchemaEntry<unknown>[] = ...

    Shell-level settings the command pipeline consumes.

    shell.parser selects which parser turns input text into a ParseResult. Today the only registered parser is 'msh', the Mud SHell tokenizer-driven parser; declared as an enum so the future LLM-backed parser can be added by appending to enumValues.

    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

    • Run a pre-bound { command, model } through the dispatcher's bound tail — resolve → validator-preload → validators → execute — minting a fresh per-command CommandContext and returning it (with its accumulated notes). This is the scripting interpreter's dispatch primitive: a scripted command is resolved (scope re-checked), validated, and executed exactly like a typed one, but the envelope is the script driver's to assemble (the run aggregates per-statement notes), not this method's.

      Distinct from the inline bound branch in executeCommand (which runs on the outer ctx and emits the envelope); this mints its own ctx so each scripted statement carries its own attribution + note set. Mirrors that branch's resolve/validate/execute sequence.

      Parameters

      Returns Promise<CommandContext>

    • Clone-per-execution controller dispatch. The clone is destructed in finally regardless of outcome.

      Option E (per-subcommand controller): when the bound model carries a subcommand and the subcommand declares its own controller:, that template wins; otherwise falls back to the verb-level controller. A subcommanded verb with no resolvable controller (subcommand omitted, no verb-level fallback) returns a player-facing failure rather than throwing.

      Parameters

      Returns Promise<void>

    • Walk the verb's match list at the assemble stage. Shape errors fall through to the next match; the first claiming match (bind succeeds + validators pass) runs _executeOne exclusively. Bind errors stop the chain on the outer ctx.

      Returns the CommandContext whose accumulator the dispatcher uses for the dispatch-response envelope: a fresh per-attempt ctx for the claiming match, or the outer ctx for pre-match failures (unknown verb, all-shape-fall-through, bind error).

      Chain-of-responsibility lives at the assemble stage only; pass: true retired with CommandResult. Content patterns that need "I might handle this depending on state" use dynamic contributions on the recency stack.

      Parameters

      Returns Promise<CommandContext>

    • Set the engagement for slot. Locked down by @CallSecurity(SecurityPolicies.ApiOnly) — only callers under mud/api/ (in practice, SchedulerApi) may invoke. @Final @Unshadowable because the engagement map is a framework invariant — a subclass override or shadow that lied about the write would leave the scheduler's timer set out of sync with the map.

      Parameters

      Returns void

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

    • Auto-introduce on arrival — the player half of the auto-introduce feature (social NPCs use the introduces brain; they have no settings store). A mover who opted in (social.autoIntroduce) names themselves to a room that doesn't already know them; any present opted-in occupant likewise introduces to the newcomer. Real recognition via SoulMixin.introduceSelf. Best-effort — never breaks movement.

      Returns void

    • Fire sense on this mover as a forced command. Used after a successful traversal to render the new room, and by the goto verb's raw-move fallback (-l flag) when Mobile.teleport's polished path was bypassed.

      Switched from look to sense by the senses build so the mover perceives the new room across every channel they possess (vision, hearing, smell, touch, taste) without typing five commands. Existing vision-only rooms render identically because the augmenter's filter ∩ sensorium = vision for any room with no <sense> regions authored.

      No-op for movers that aren't CommandGivers — scripted NPCs can move without auto-sensing. Errors are swallowed: a flaky sense shouldn't fail the movement; the mover already received an arrival narration from announceArrival, so the auto-sense is additive context.

      Resets focus to "here" first when the mover is Focused — bare sense is default: "$focus", so without the reset the auto-sense would carry stale drilled focus from the prior room into the new one (typical case: focus was on widget, the player walks into a room with no widget, the auto-sense comes up empty).

      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

    • Build the Scene at the right topic and dispatch self + peers frames. Mobile is constrained to Containable bases, so toPeers is always the right broadcast scope (see Vessel rule §7.3 — Containable wins).

      Parameters

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

    • In-room free-form emote: render + compose Scene + send.

      Parameters

      • text: string
      • Optionaltarget: Stuff
      • OptionalinReactionTo: string

      Returns void

    • Shadowable extension point for envelope frames. Default returns the envelope unchanged. Treat the input as immutable; return a fresh copy when transforming.

      Parameters

      • envelope: EnvelopeTemplate

      Returns EnvelopeTemplate | null

    • Shadowable extension point. Default checks per-frame modality attribution: when frame.meta.modality is set, drops the frame unless the recipient's PerceptionApi.sensorium includes the named modality. Actor self-frames (carrying audience:actor) always deliver — you always perceive your own acts.

      Game content shadows this to drop frames (return null) or transform them (return a modified copy — treat the input as immutable). Per-recipient interception, lifecycle bound to the shadow's host.

      Parameters

      • frame: MessageFrame

      Returns MessageFrame<unknown> | null

    • Partial forget — clear one field, keep the record. 'knownAs' nulls the name (familiar-face-lost-name); a payload field is removed. No-op when the record doesn't exist.

      Parameters

      Returns void

    • Walk the recency stack newest-first and pair every command with the resolved Stuff that affords it and its bucket. The 'self' sentinel resolves to the giver instance, so every record's source is a concrete Stuff. Standing state — depends only on the current stack, not on any command being in flight. The dispatch chain decides ordering; we don't dedup.

      Lazily seeds the 'self' entry on first read so callers that skip postRegister (test helpers like makeStuff, ad-hoc scripts) still see the giver's own contributions. Production code goes through postRegister; this branch is the safety net.

      Returns Affordance[]

    • 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

    • Get the current container.

      R2.3 self-heal: if environment points at a destroyed Container (a path bypassed the eager evacuation in Container.cleanupOnDestruct), clear the slot and return null. Cheap one-liner backstop for S1 / S8.

      Returns Stuff & Container | null

    • Per-instance dynamic command contributions, merged with the static commandContributions by the containment-delta machinery (the InstanceContributor seam). A Behaved host affords talk to nearby givers exactly when it carries an engage-triggered (dialogue-responder) spec — so a conversational NPC is discoverable and a silent one is not, with no subclass and no manual push/pop. Reads the persisted behaviors: (hydrated before placement, so it is live at containment-delta time), independent of brain wiring. The framework's pop-on-departure / reset-on-move handles teardown; adding/removing a tree on an already-placed host settles on its next (re)placement.

      Returns CommandContributions

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

    • Subclass-override delivery hook for envelope frames. Avatar overrides to multiplex to its connected Interactives; NPCs and other Sensors default to no-op.

      Parameters

      • _envelope: EnvelopeTemplate

      Returns void

    • 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

    • Introduce yourself to everyone in range — a modality-neutral social act (the shared core behind the introduce verb, the NPC introduces brain, and the player auto-introduce hook). Emits the introduction scene and writes each in-range perceiver's recognition of you (learnIdentity). Returns false (no-op) if you have no proper name to give.

      Returns boolean

    • 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

    • Upsert what the viewer knows about referent in realm. A new record stamps firstSeen/lastSeen; an existing one advances lastSeen (preserving firstSeen) and coalesces: a non-null update.knownAs raises the name, an absent/null one leaves a learned name intact. Payload flags merge.

      Parameters

      Returns void

    • 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

    • Mark the schema-subscription gate open. The first connection attach is when client-side schema delivery becomes meaningful — earlier pushes are pre-subscription bookkeeping.

      Parameters

      Returns void

    • Envelope template method — DO NOT override. Override handleEnvelope instead, or shadow filterEnvelope for content-driven interception. Parallels onMessage.

      Parameters

      • envelope: EnvelopeTemplate

      Returns void

    • Template method — DO NOT override in subclasses. Override handleMessage instead, or shadow filterMessage for content- driven interception.

      Parameters

      • frame: MessageFrame

      Returns void

    • 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

    • Identity default — the raw band passes through unchanged. Shadows that intercept this method modulate the answer.

      Parameters

      • raw: "pitch-black" | "very-dim" | "dim" | "lit" | "bright" | "blinding"
      • _loc: Stuff & Container

      Returns "pitch-black" | "very-dim" | "dim" | "lit" | "bright" | "blinding"

    • Point-get, O(1). Returns null for an unknown referent. Lazy liveness-GC: a record whose referent no longer resolves to any live Stuff is dropped and null returned.

      Parameters

      • realm: string
      • referent: string

      Returns BeliefRecord | null

    • 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

    • Re-evaluate this character's competence-conferred verbs and reconcile the affordance stack: drop the prior conferral entry, then re-push the current set (idempotent pop + conditional push, mirroring the hosted-update delta). Called by AdvancementApi after each Transcript append. No-op before the Catalog warms.

      Returns Promise<void>

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

      Parameters

      • value: string

      Returns boolean

    • Drop every entry whose bucket is 'environment' or 'peers'. Used during a self-move; ContainmentApi follows up with the appropriate pushCommandSource calls for the new environment.

      Parameters

      • reason: "self-moved"

      Returns void

    • 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

    • Instantly move to a container. Default: narrate departure (if the mover had a previous environment) and arrival. Pass { silent: true } to suppress both.

      silent: true is what Login spawning uses — newly-cloned avatars shouldn't be announced as "vanishing" from nowhere or "appearing out of thin air" before a player has even seen the location.

      Parameters

      Returns void

    • 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

    • Traverse an Exit. Two-layer hook dispatch:

      • Traversal layer (this method): canTraverse on the mover, canExit on the source location, canEnter on the destination location — all fire before announcement and the containment move. After the move: onTraversed (mover), onExited (source), onEntered (destination).
      • Containment layer: fires from inside ContainmentApi.move. canMove / onMoved on the item; canRemove* / canAdd* / on* on the source/destination.

      The Phase 7 contract stands: the caller has already validated traversal via exit.canTraverse(this) — that's the door's "is this passable?" gate. The new Witness hooks layer additional pre-move vetos, not a replacement.

      Parameters

      Returns Promise<void>

    • Composition constraint: Perceiver requires Sensor to be present on the same host. The perception verbs (look / scry / locate) render scenes to the perceiver's own channel via handleMessage, which lives on Sensor. The public-shape interface declares Perceiver extends Sensor so the type narrowing in MixinApi.isPerceiver exposes the Sensor surface; without runtime co-composition the narrowing would lie. MixinConstructor doesn't carry an enforceable bound here (loose by design — see lib/mixin.ts), so the check rides on __validateComposition__ and fires at first registration.

      Parameters

      Returns void