# Npc

> Kinbarrow modding reference — content tree `45d0fe274f851548`, version `0.2.0+main.c05ef2b`.

`creatures/**/<id>.srd.ron` — one per file; stem == id. PRIMITIVES ONLY; composites derive (README "Derivations").

**Note on syntax:** these files are RON, not JSON. The shapes below are exact,
but punctuation follows RON — read a real `data/*.ron` file alongside.

## Fields

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `abilities` | `any[][]` | required | Base ability scores, BEFORE racial adjustments. |
| `alignment` | `AlignmentConstraint` | required | The block's alignment line as a generation constraint, not a value. |
| `armor` | `string[]` | required | Armor ids, boot-resolved; empty = unarmored. |
| `attacks` | `NaturalAttack[]` | optional | The monster's natural attacks — read at combatant assemble so it strikes with its own bite/claw/slam, not a borrowed weapon. Empty on the humanoid blocks (they fight with `weapons`). |
| `blindsight` | `integer` | optional | Blindsight radius in feet; absent = none. |
| `breath` | `MonsterBreath` | optional | The monster's Breath Weapon — a recharge area-save action (the black dragon wyrmling's Acid Breath, the magma mephit's Fire Breath). ABSENT = none (every humanoid block and most monsters). Assembled into a charged `BreathReady` at bubble open and loosed by the AI like the dragonborn's, but it returns MID-FIGHT on the Recharge roll, not a rest. |
| `condition_immunities` | `string[]` | default `[]` | Conditions this creature can never suffer — `conditions/` ids, checked at the `Afflict` inflict point so an undead is never poisoned and a construct never frightened. Ids resolve against the shipped catalog; SRD immunities to LEDGERED conditions (exhaustion, charmed, deafened) are noted in the file, not listed here. |
| `cr` | `string` | required | The cr_xp key, boot-resolved — the stored primitive that feeds xp(cr). |
| `creature_type` | `string` | required | A `tables/creature_types.srd.ron` id, boot-resolved — the stat block's "Type" line. The seeded blocks are all `"humanoid"`; the bestiary's typed monsters declare their own. |
| `darkvision` | `boolean` | default `false` | SRD senses off the stat block's "Senses" line — darkvision (a bool presence flag; monsters are raceless so it rides the block, not a composed race) and the special senses in FEET of radius. Stamped at `instantiate_creature`, read by `soul::senses_of` and `light::seen`. ABSENT = none. The bestiary prints these where the SRD does; no HUMANOID block carries a special sense (sim-neutral). |
| `id` | `string` | required |  |
| `immunities` | `string[]` | default `[]` | SRD damage immunities / vulnerabilities on the creature stat block — damage-kind ids, read at bubble assemble like the kit (`damage_mods_at`): immunity zeroes the kind, vulnerability doubles it. The typed monsters carry them (a skeleton's poison, a mephit's fire); no HUMANOID block does (sim-neutral). Absent = none. |
| `languages` | `string[]` | default `[]` | SRD known languages off the stat block — `languages.srd.ron` ids, stamped at `instantiate_creature` (`LANGUAGES`). ABSENT MEANS COMMON (the absent-default). The seeded HUMANOID blocks declare none (Common by construction); a typed monster may name its own tongues. |
| `level` | `uint32` | required | Level == hit-dice count. |
| `multiattack` | `integer` | optional | Attacks one Attack action makes — the printed Multiattack count, wired into the NPC turn like Extra Attack. ABSENT = one. A conditional/compound multiattack (grick's beak-on-hit, a dragon's distinct bite+claws) is LEDGERED — this is the simple count. |
| `natural_armor` | `integer` | optional | SRD natural armor: the AC base a monster's hide/scales/plating gives, to which its Dex mod adds (`na + dex_mod`) — the README's named "stored exception" to the derivation. ABSENT = unarmored (`10 + dex_mod`), the zombie/ooze case. |
| `proficiencies` | `Skill[]` | required | The skill-proficiency SET; bonuses derive. |
| `resistances` | `string[]` | default `[]` | SRD damage resistances on the creature stat block — damage-kind ids taken at HALF, read at bubble assemble beside the composed race/class resistances (a dretch halves fire, a gray ooze halves acid/cold/fire). Absent = none. The "from nonmagical attacks" qualifier a few blocks carry is LEDGERED (no magical-weapon distinction yet) — such a resistance is listed plainly or noted in the file. |
| `size` | `Size` | optional | A monster's OWN size — monsters are raceless, so there is no composed race to derive it from; the hit die swings by it. ABSENT means the humanoid "(any race)" assumption (size comes from the composed race, Medium in the printed corpus) — no humanoid block carries it. |
| `source` | `Source` | required |  |
| `speed` | `integer` | optional | A monster's OWN speed in feet — raceless, so stamped from the block. ABSENT = the composed race's speed (the humanoid blocks). |
| `tremorsense` | `integer` | optional | Tremorsense radius in feet; absent = none. |
| `truesight` | `integer` | optional | Truesight radius in feet; absent = none. |
| `vulnerabilities` | `string[]` | default `[]` | Damage-kind ids taken at DOUBLE; absent = none. |
| `weapons` | `string[]` | required | Weapon ids, boot-resolved. |

## Nested shapes

### Ability

The six ability scores (SRD 5.1). The engine's own `stats::Ability` is the runtime type; this is the data-layer mirror, bridged by [`Ability::engine`].

`Str`, `Dex`, `Con`, `Int`, `Wis`, `Cha`

### AlignmentConstraint

The blocks' printed alignment lines as generation constraints (README).

`Any`, `NonLawful`, `NonGood`, `Chaotic`

### Damage

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `dice` | `string` | required | The damage dice, an `NdM` string (e.g. "1d8"). |
| `kind` | `string` | required | A `tables/damage_kinds.srd.ron` id, boot-resolved. |

### MonsterBreath

A MONSTER's Breath Weapon DATA — the recharge area-save action the bestiary blocks ledgered. Unlike the racial breath (dice by level, DC by Con), a monster's stat block PRINTS its `damage` dice; the SAVE ability is data too, and the DC DERIVES at assemble (8 + pb_for_cr(cr) + Con mod — the CR proficiency, which reproduces the printed value). The area is the archetypal 15-ft cone (the SRD per-monster line/cone split stays LEDGERED).

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `damage` | `Damage` | required | The printed damage — dice + a `tables/damage_kinds.srd.ron` kind (validator-checked); a failed save takes it whole, a success half. |
| `recharge` | `uint32` | required | The LOW bound of the SRD recharge range (5 = "Recharge 5-6", 6 = "Recharge 6") — the breath returns on a d6 ≥ this at the breather's turn start. In 1..=6 (validator-checked). |
| `save` | `Ability` | required | The saving-throw ability every creature caught in the cone rolls. |

### NaturalAttack

One natural attack off a monster's stat block: a bite, claw, or slam the creature IS armed with — not a borrowed weapon. PRIMITIVES only: to-hit and the damage average DERIVE (`pb_for_cr` + the governing ability's mod), exactly as a humanoid's weapon line does. The `ability` names which mod feeds both (Str for a slam, Dex for a wolf's quick bite — the finesse rule made explicit for the raceless). `reach_ft` is the melee reach (5 ft on the grid = one square; a longer reach is ledgered); a ranged natural attack carries `range` (none in the starter bestiary — the substrate for a manticore's spikes, ledgered).

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `ability` | `Ability` | required | The ability whose mod feeds to-hit and damage (Str, or Dex for a finesse-like bite). |
| `damage` | `Damage` | required | The attack's damage dice and kind. |
| `name` | `string` | required |  |
| `range` | `Range` | optional | Ranged natural-attack range; absent = melee only. |
| `reach_ft` | `uint32` | required | Melee reach in feet (5 ft = one grid square). |

### Range

Weapon-range band in feet.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `long` | `uint32` | required | Long range in feet — an attack beyond `normal` up to this is at disadvantage. |
| `normal` | `uint32` | required | Normal range in feet — no penalty within it. |

### Size

Creature size — the full SRD ladder (Tiny..Gargantuan). Races span Small/Medium; the bestiary's monsters reach the rest, and the hit die swings by it (`combat::srd::hit_die`).

`Tiny`, `Small`, `Medium`, `Large`, `Huge`, `Gargantuan`

### Skill

The eighteen SRD skills.

`Athletics`, `Acrobatics`, `SleightOfHand`, `Stealth`, `Arcana`, `History`, `Investigation`, `Nature`, `Religion`, `AnimalHandling`, `Insight`, `Medicine`, `Perception`, `Survival`, `Deception`, `Intimidation`, `Performance`, `Persuasion`

### Source

Every file's top-level value carries `source`.

#### Source::Srd51

SRD 5.1 — the System Reference Document, the shipped baseline.

#### Source::Original

Original content authored for this game (not from the SRD).

#### Source::Personal

A player's own transcription or third-party content in a mod tree — provenance stays honest without borrowing the base tree's markers. Never used by shipped files.

