NPC & combat traits
The actor trait (a person, a kind noun) is what makes
something a someone:
pronouns (they/them default), an optional carrying capacity (the capacity
that triggers give-action refusals), disambiguation text, and a customProperties bag that
conversation and giving preferences read. In Chord,
a person composes exactly this (plus identity); the keeper scene is the whole recipe. Everything richer is layered on top.
The npc trait is reached in Chord via the core behavior adjectives
(a person, a guard, or passive, wanderer with move-chance 50,
follower, patrol with route [ … ]), which are always available with
no use line; it can also be reached in TypeScript. The trait holds the
platform's NPC bookkeeping: hostility flag, movement permissions
(canMove, allowed/forbidden rooms; in Chord, can-move,
allowed-rooms, forbidden-rooms), announced-movement messages, a
behavior id for the NPC turn plugin, and
conversation-state/knowledge/goals bags. Life-state does not live
here; that moved to health (ADR-226). Neither talking nor attacking
reads it; it belongs to the NPC plugin layer, and the multi-turn
behaviors it names (a guard attacking, wanderers wandering, patrols
patrolling) are the NPC plugin layer's territory.
The character-model trait (TypeScript-only) is the deep-NPC option:
personality, disposition, mood, threat assessment, beliefs and goals.
These form the substrate of the character-knowledge systems. It is a
pointer only here; it rides alongside npc and is consumed by its own
subsystem, not by standard actions.
The combatant trait is reached in Chord under use combat (the
deserter scene is a person, combatant with health 8 and skill 30, and hostile true and friends compose the same way); it can also
be defined in TypeScript. It carries combat stats (skill, base damage,
armor, retaliation and inventory-drop flags) and, since ADR-226, nothing
else: health, consciousness, and death live on the required health
trait, and health/max-health on the composition line quietly route
there (the loader attaches it for you). To stdlib its mere presence means
"combat handles this"; the stats are the extension's business.
The weapon trait appears in Chord under use combat: the cutlass
scene is weapon with damage 5 and skill-bonus 2, plus
is-blessed/glows-near-danger, and durability fields are
TypeScript-only. Its damage field drives best-weapon inference, plus
type and the blessed/glowing flags. Prefer equipping to make a weapon the
inferred choice; name it explicitly to make it a consulted command
entity.
The edible trait (edible, an adjective; a liquid composes as
drinkable) carries servings, liquid (the eat/drink
router), taste, effects, and satisfiesHunger/satisfiesThirst.
The behavior-side extras
(remainsType, consumeMessage) are dormant in the stdlib path. One
type wrinkle: the drink-taste vocabulary (refreshing, bitter,
sweet, strong) isn't in the trait's declared taste union. It works
via raw data, and that mismatch is flagged as a known type discrepancy.
The breakable and destructible traits (TypeScript-only) are read
by attacking only (throwing's fragility is name-keyword
inference, not these). breakable is one field, broken; destructible is the
hit-point model (armor, weapon requirements, transformTo,
revealExit).