# ClassDef

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

`classes/<id>.srd.ron` — one class per file; stem == id. The identity axis a soul takes up (`CLASS` prop) through three doors: genesis for the class-shaped vocations, induction/recruitment for the rest, the creator for the player — the ordinary majority stays the calibrated classless commoner until the story touches them.

**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 |
| --- | --- | --- | --- |
| `armor` | `ArmorCategory[]` | required | Armor training by category; `Shield` rides the list. |
| `features` | `FeatureGrant[]` | required | Features granted by class level. |
| `hit_die` | `uint32` | required | The class hit die (d6 wizard … d10 fighter) — overrides the size die for classed souls (`combat::hit_die_of`); classless souls keep the size die. |
| `id` | `string` | required |  |
| `kit` | `StartingKit` | required | The starting kit the classed-but-unarmed borrow (its own trainings — validated: a class never starts in a coat it can't wear). |
| `multiclass_prereq` | `MulticlassPrereq` | optional | The SRD Multiclassing ability prerequisite — the minimum score(s) to add or keep this class in a multiclass. Absent = none (a single-class assign never reads it, so pre-0241 files are unaffected). |
| `multiclass_proficiencies` | `MulticlassProficiencies` | optional | The REDUCED proficiencies this class grants when taken as a MULTICLASS — distinct from the full initial-class set above. Absent = nothing granted on multiclass-in. |
| `name` | `string` | required |  |
| `primary` | `Ability` | required | The quick-build primary ability — the deterministic ASI target. |
| `saves` | `Ability[]` | required | Saving-throw proficiencies (two per SRD class). |
| `skills` | `SkillChoice` | required | The class's skill-training choice. |
| `source` | `Source` | required |  |
| `spellcasting` | `Spellcasting` | optional | The class's spellcasting block; absent = non-caster. |
| `subclass` | `Subclass` | required | The class's one SRD subclass, auto-applied at its level. |
| `weapons` | `WeaponTraining` | required | Weapon training (category flags + named ids). |

## 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`

### ArmorCategory

The SRD armor categories — light/medium/heavy body armor and the shield.

`Light`, `Medium`, `Heavy`, `Shield`

### FeatureGrant

A feature granted at a class level: `id` resolves against the engine's implemented feature registry (`classes::Feature`) at boot — OR defines itself as a pure PASSIVE: an open id carrying its own `name` and `modifiers` (a mod's fighting style is a data row). The validator enforces the fork: a registry id may not re-name itself; an open id must self-define and can never spend `uses` (spend mechanics are engine code).

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | required |  |
| `level` | `uint32` | required | The class level at which the feature is granted. |
| `modifiers` | `Modifier[]` | optional | The passive mechanics this grant carries. |
| `name` | `string` | optional | The sheet name of an OPEN-id passive; absent on registry grants (the registry names its own). |
| `uses` | `integer` | optional | Uses per rest FROM this level — overrides the registry default, so the SRD's "twice between rests" steps (Action Surge at 17th) are data, not code. Absent = the registry's count; only meaningful on registry features that spend uses (validator-enforced). |

### ModHook

Where a passive modifier lands — the closed hook set: one variant per NUMBER the engine already reads. A hook without a consumer stays out (ledger-don't-fake): attack/damage hooks arrive with the kit's weapon-identity read so the skirmish and the bubble apply them alike; save/check/heal hooks with theirs.

#### ModHook::Ac

Armor class — the shared fighter build and the sheet (one derivation).

#### ModHook::CritRange

The critical floor drops by `amount` (Improved Critical's 1 → 19-20).

#### ModHook::CritDice

Extra weapon damage dice on a critical hit (Savage Attacks' shape).

#### ModHook::Speed

Foot-speed in FEET: the barbarian's Fast Movement and the monk's Unarmored Movement, each a `when: Unarmored` bonus read at the bubble's move budget (the combat consumer; the travel-speed read is ledgered — sim-neutral, no worldgen soul takes these classes).

### ModWhen

When a modifier applies.

#### ModWhen::Always

The modifier always applies (the default).

#### ModWhen::Armored

Only while wearing body armor (the Defense style's clause).

#### ModWhen::Unarmored

Only while wearing NO body armor: the barbarian/monk's speed bonuses, the inverse of [`ModWhen::Armored`].

### Modifier

One passive adjustment: `amount` onto `hook` while `when` holds — the data half of a feature's mechanics. Registry features may carry their mechanics here (Defense, Improved Critical do); an OPEN-id grant (a mod's own passive) must.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `amount` | `int64` | required | The signed amount added onto `hook`. |
| `hook` | `ModHook` | required | Where the adjustment lands. |
| `when` | `ModWhen` | optional | The clause under which it applies (default Always). |

### MulticlassPrereq

The SRD Multiclassing ability prerequisite (SRD "Multiclassing"): the minimum ability score(s) a soul must MEET to add — or keep — this class in a multiclass. `all` entries are ALL required (Monk's Dex 13 AND Wis 13); `any_of`, if non-empty, needs at least ONE (Fighter's Str 13 OR Dex 13). `assign_class` gates on it (`classes::multiclass_prereq_refusal`). Absent = no prerequisite (a single-class assign never consults it). A single-class soul is unaffected: prereqs bite only when a SECOND class is added.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `all` | `any[][]` | optional | Ability minimums ALL required to add/keep this class. |
| `any_of` | `any[][]` | optional | Ability minimums where at least ONE must be met (Fighter's Str 13 OR Dex 13). |

### MulticlassProficiencies

The REDUCED proficiencies a class grants when taken as a MULTICLASS (SRD "Multiclassing" proficiencies table) — a subset of the initial-class set, with NO saving-throw proficiencies (SRD). `armor` is the reduced armor training (unioned into `classes::trained_armor` for the casting gate); `skills` is how many of the class's own `skills.from` the multiclass-in grants (the deterministic front pick — 0 for the classes that grant none). The reduced WEAPON set and tool/instrument grants are SRD too but have no runtime gate yet (ledgered, never faked). Absent = nothing granted on multiclass-in.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `armor` | `ArmorCategory[]` | optional | Reduced armor training granted on multiclass-in (unioned into `trained_armor`). |
| `skills` | `uint32` | default `0` | How many of the class's own `skills.from` the multiclass-in grants (front picks). |

### Skill

The eighteen SRD skills.

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

### SkillChoice

A class's skill training: pick `count` from `from` — the list membership is the SRD's; its ORDER is our quick-build priority, which the deterministic auto-pick takes from the front (player choice is ledgered).

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `count` | `uint32` | required | How many skills to pick from `from`. |
| `from` | `Skill[]` | required | The skills to choose among; ORDER is our quick-build priority. |

### SlotProgression

Slot progression — which slot grid a caster derives capacity from. `Full` reads `tables/spell_slots.srd.ron` (cleric/wizard); `Half` reads `tables/spell_slots_half.srd.ron` (paladin/ranger — no slots at 1st, up to 5th-level slots by 17th); `Pact` reads `tables/pact_magic.srd.ron` (the warlock — a small number of slots, ALL at one rising slot level, that recharge on a SHORT rest).

`Full`, `Half`, `Pact`

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

### Spellcasting

A class's spellcasting block. Prepared-count = ability mod + class level (min 1) DERIVES (the SRD's own rule for cleric/wizard) — never stored.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `ability` | `Ability` | required | The spellcasting ability. |
| `cantrips_known` | `any[][]` | required | Cantrips known by class level, as (level, count) steps — the SRD class-table column ("3 at 1st, 4 at 4th, 5 at 10th"). |
| `progression` | `SlotProgression` | required | Which slot grid capacity derives from. |

### StartingKit

The class's SRD starting kit — the class page's "Equipment" block at its (a) options, as arms-table ids. What a classed-but-unarmed soul BORROWS (`combat::loadout` — the class dresses its own, ahead of the org-archetype block): the rogue watchman walks in leather with a rapier, not the guard block's chain shirt and spear. The wizard's armor list is empty — robes are no armor at all.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `armor` | `string[]` | required | The (a)-option armor as arms-table ids; empty = no armor (the wizard's robes). |
| `weapon` | `string` | required | The (a)-option starting weapon, an arms-table id. |

### Subclass

The class's SRD subclass (each SRD 5.1 class prints exactly one), applied automatically at `level` — the subrace precedent: carried inside the class file, no selection substrate until a second subclass exists to choose.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `armor` | `ArmorCategory[]` | required | Extra armor training the subclass grants (Life's heavy armor). |
| `features` | `FeatureGrant[]` | required | The features the subclass grants. |
| `id` | `string` | required |  |
| `level` | `uint32` | required | The class level at which the subclass applies. |
| `name` | `string` | required |  |

### WeaponTraining

Weapon training: the category flags plus any named ids (the rogue's hand-crossbow/longsword/rapier/shortsword list).

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `ids` | `string[]` | required | Extra individual weapon ids trained (the rogue's rapier/shortsword list). |
| `martial` | `boolean` | required | True = trained in all martial weapons. |
| `simple` | `boolean` | required | True = trained in all simple weapons. |

