# Weapon

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

**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 |
| --- | --- | --- | --- |
| `category` | `WeaponCategory` | required | The SRD weapon category — proficiency gates on it. |
| `cost_cp` | `uint32` | required | Cost in copper pieces (1 gp = 100 cp, 1 sp = 10 cp). |
| `damage` | `Damage` | optional | The weapon's damage; absent = none (the net). |
| `id` | `string` | required |  |
| `name` | `string` | required |  |
| `properties` | `WeaponProperty[]` | required | The SRD weapon properties (finesse, heavy, thrown, …). |
| `quality_overrides` | `TierEffects[]` | optional | Per-item quality-profile overrides; absent = the class profile. |
| `recipes` | `Recipe[]` | required | The weapon's crafting recipes (ORIGINAL content, not SRD). |
| `weight_lb` | `number` | optional | Weight in pounds; absent = negligible (the sling). |

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

### CraftTier

The tool-proficiency ladder — one ladder, two homes (this IS the engine's `TradeTier`).

`Untrained`, `Proficient`, `Expert`

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

### QualityTier

The seven quality tiers (semantic — engine code branches on it).

`Trash`, `Poor`, `Normal`, `Good`, `Excellent`, `Masterwork`, `Legendary`

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

### Recipe

A recipe embedded on a good/weapon/armor. Craftable IS having recipes — there is no craftable flag (README).

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `ability` | `Ability` | optional | The ability whose mod feeds output; absent = untrained extraction. |
| `building` | `string` | required | The building TYPE that produces this good (a `data/buildings/` id, boot-resolved): a recipe names its building directly, and the build-time derivation mints one `Produces` edge at every venue of that type. Producing vs merely crafting is NOT authored: every recipe is a candidate `Produces` edge and the opportunity-cost engine (`best_row`) decides what a shift makes. The only recipes that do not derive an edge are those the 2-input edge model cannot hold (3+ distinct inputs) — a substrate limit, ledgered, not a producibility flag. |
| `forbids_terrain` | `string[]` | default `[]` | The exclusion half of the terrain GATE (see `requires_terrain`): the recipe is skipped at any venue whose town bears one of these tags. |
| `hours` | `uint32` | required | Labour hours one batch takes. |
| `inputs` | `any[][]` | required | The (input, qty) pairs consumed per batch — boot-resolved. EMPTY = raw extraction (nature's own yield): such a recipe names WHERE and HOW FAST a raw is won, carries no `CRAFTED` flag, and keeps the extraction lottery. A recipe WITH inputs is a craft (sets `CRAFTED`). |
| `rate` | `double` | required | Units per worked hour, before the work multiplier. The recipe carries it, so production truth lives in one place. |
| `requires_terrain` | `string[]` | default `[]` | Terrain GATE: this recipe is wired only at venues whose town bears every `requires_terrain` tag and NONE of `forbids_terrain`. Lets a good be made two ways by place — coast/vale bread bakes `flour` where an `arable` mill stands; the mountain bakes `grain` direct where it does not. Empty gates = wire wherever the building stands. |
| `strike` | `Strike` | optional | The face's RARE find: each produced unit has `odds` chance of striking this good instead of the bulk yield — the mithral vein in the stone. Absent on ordinary recipes. |
| `terrain_mods` | `any[][]` | default `[]` | Terrain-tag rate MODIFIERS: the effective production rate at a venue is `rate × Π(multiplier for each town terrain tag present)`. Regional divergence emerges from the GROUND, not hand-wired per venue — grain grows richer on `arable`, an ore seam runs faster in `mountains`. Empty = the base rate stands everywhere the recipe is wired. |
| `tier` | `CraftTier` | required | The tool-proficiency floor to run this recipe. |
| `tool` | `string` | optional | A goods/ id (e.g. "smiths_tools"); absent = bare hands. |
| `yield` | `uint32` | required | Units the batch yields: one run of `inputs` + `hours` makes this many of the good — the ammunition fix the pricing ledger named (arrows come 20 to a batch, so their per-unit worth is sane). The derivation (`recipe_worth_cp`) divides material + labour by it, so a per-unit anchor round-trips. Explicit in EVERY recipe — the RON key is `yield`; the no-serde-default contract's one exception is `quality_overrides`, and this is not it (`1` for a single-unit craft). |

### RecipeInput

A recipe input: a SPECIFIC good (process inputs) or ANY material of a class (constructive inputs — the family wall).

#### RecipeInput::Good

A SPECIFIC good by id — the exact material a process consumes.

Carries `string`.

#### RecipeInput::Class

ANY good of a material CLASS by id — the constructive input (the family wall): whichever member of the class is on hand.

Carries `string`.

### Strike

A strike table entry: the rare good and its per-unit odds.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `good` | `string` | required | The rare good struck — a goods/ id, boot-resolved. |
| `odds` | `double` | required | Per-unit chance (0..1) of striking `good` instead of the bulk yield. |

### TierEffects

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `ac_delta` | `integer` | optional | AC delta at this tier (armor); absent = n/a. |
| `attack_delta` | `integer` | optional | Attack-roll delta at this tier (weapons); absent = n/a. |
| `damage_delta` | `integer` | optional | Damage delta at this tier (weapons); absent = n/a. |
| `dc_delta` | `integer` | optional | Lock DC delta vs the Normal DC 10 base at this tier (locks); absent = n/a. |
| `integrity_factor` | `number` | optional | Max-integrity multiplier (the `structure` class) — defaulted so the arms/tool/lock profiles never spell it. |
| `tier` | `QualityTier` | required | The quality tier this row describes. |
| `value_factor` | `double` | required | Worth multiplier at this tier (every class). |
| `work_factor` | `number` | optional | Work-output multiplier at this tier (tools); absent = n/a. |

### WeaponCategory

The four SRD weapon categories (simple/martial × melee/ranged) — proficiency gates on this.

`SimpleMelee`, `SimpleRanged`, `MartialMelee`, `MartialRanged`

### WeaponProperty

An SRD weapon property (finesse, heavy, thrown, …) — a tag that bends how a weapon is wielded or rolled.

#### WeaponProperty::Ammunition

Fires ammunition within the given [`Range`] (bows, crossbows, slings).

Carries `Range`.

#### WeaponProperty::Finesse

May use Dexterity instead of Strength for attack and damage rolls.

#### WeaponProperty::Heavy

Small creatures attack with disadvantage (too large to wield well).

#### WeaponProperty::Light

Light enough for two-weapon fighting (the off-hand bonus attack).

#### WeaponProperty::Loading

Only one shot per action, however many attacks the wielder has.

#### WeaponProperty::Reach

Adds 5 ft to the wielder's reach for attacks and opportunity attacks.

#### WeaponProperty::Special

Carries special rules given in the weapon's own text (SRD "Special").

#### WeaponProperty::Thrown

May be thrown for a ranged attack within the given [`Range`].

Carries `Range`.

#### WeaponProperty::TwoHanded

Requires two hands to wield.

#### WeaponProperty::Versatile

May be wielded one- or two-handed; the two-handed damage die is the given `NdM` string.

Carries `string`.

