Derivations
The content tree — the contract for the
data/ tree.
Rationale (the designer’s): derivation creates systems, systems
create emergence — a guard without his shield is AC 14 with no special
case, and the book’s printed blocks become the proof of faithfulness
rather than the data. The archetype files store primitives ONLY; the
engine derives everything below, and a lock test must reproduce every
printed value in expected/npc_blocks.srd.ron from them.
With mod(s) = floor((s - 10) / 2) (the SRD ability-modifier formula):
- Hit dice count =
level. The stat blocks and the adventure ladder are ONE system: future leveling grows HP and PB with zero new rules. - Hit die = f(size), the SRD’s Hit Dice by Size table (p. 255): Tiny d4, Small d6, Medium d8, Large d10, Huge d12, Gargantuan d20. Size comes from the composed race (below).
- HP = roll
level × d(hit die) + con_mod × level; the printed AVERAGE convention isfloor(level × avg(die)) + con_mod × levelwithavg(dN) = N/2 + 0.5(the SRD’s own “2d8 → 9 (2 × 4½)” and “Constitution modifier… multiplied by the number of Hit Dice”, p. 255). - Proficiency bonus = f(level), exactly the proficiency ladder:
2 + floor((level - 1) / 4)— 2 at levels 1-4. (For monsters statted by CR, the SRD’s Proficiency Bonus by Challenge Rating table p. 256 gives the same +2 at CR 0-4 through +9 at CR 29-30.) - AC =
10 + dex_modunarmored; else the armor table’s formula —Base(base, dex)with dex Full/Max2/None — plusBonus(2)if a shield is carried. - Attack to-hit =
pb + mod(ability)where ability is Str for a melee-category weapon, Dex for a ranged-category weapon, and the better of the two if the weapon has Finesse. Thrown melee weapons use the melee rule. - Damage = weapon damage dice + the same ability modifier; the
printed average is
floor(avg(dice) + mod); a zero modifier prints bare dice. - Skill bonus =
mod(governing ability)(fromtables/skills.srd.ron)+ pbif the skill is in the proficiency set (SRD p. 256). - Passive Perception =
10 + Perception bonus. Never stored. - Speed comes from the composed race (races/*.srd.ron) — the printed 30 ft. assumes human; a dwarf guard walks at 25.
- XP =
tables/cr_xp.srd52.ron[cr]— that mapping is SRD data, not a formula. CR 0 prints “0 or 10”: 0 without effective attacks, 10 with.
Stored exceptions (the rule that proves the derivations): monsters
store NATURAL armor, their own size, and their own speed — they
are raceless, so there is nothing to derive from. For humanoids the
derivation is the system; natural armor is the exception, stored where
the SRD prints it. Everything else still derives: a monster’s to-hit and
damage come from its natural-attack dice + the named ability’s mod +
pb_for_cr(cr) (the CR proficiency-bonus table, not the level ladder —
), its AC from natural_armor + Dex, its HP from level × the
size’s hit die + Con, and its XP from cr_xp[cr] — every value verified
against the SRD’s printed block in expected/npc_blocks.srd.ron.
Licensing boundary — why CR is stored: deriving CR from stats uses
the DMG’s monster-building table, which is NOT part of the SRD/CC-BY-4.0
corpus. CR therefore stays a stored primitive whose only job is to feed
xp(cr) (and future encounter math), never a derivation target.