Sharpee
Chord / Standard Library / NPCs & Conversation / NPC & combat traits

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