Builder's Manual · Chapter 2

How the Character Sheet Thinks

The character schema has one design rule: store what the dice gave you; derive everything else.

A character file stores the six ability bonuses, current and maximum HP, XP, level, copper, traits, notes, and references to carried gear. That is all. Everything else on the sheet is a computed field:

  • Each defense is its bonus + 10.
  • itemSlots is the Constitution defense — raise conBonus and pack space follows, with nothing to remember.
  • slotsUsed sums the slots value of every referenced weapon, armor piece, spellbook, and item.
  • armorDefense reads the equipped armor file (11 if none) and adds +1 each for a helmet and shield; armorBonus is always that minus 10.

Storing a derivable number is the classic way these systems rot: two fields disagree and nobody knows which one lied. Here the stored bonuses are the single source of truth, and a rules change is a one-line schema edit that updates every sheet in the project at once.

The sheet talks to the referee

Three computed fields exist purely to be read aloud: attackRolls turns every equipped weapon into its exact roll ("d20 + 2 vs. armor defense, damage d8"), defendRoll phrases the player-facing defense roll, and spellSave phrases the caster's opposed Intelligence roll. The referee is instructed to read these off the sheet rather than improvise arithmetic — so if you house-rule, say, finesse weapons that attack with Dexterity, you edit one expression and every sheet in every session is already following the new rule. Open @Missing file and count what he actually stores; it is shorter than his rumor list.

References, not copies

Gear on a sheet is a reference to the shared record — the dagger on Bram's sheet is the Dagger file. Damage dice, slots, costs, and defense values live in the gear file alone; fix a typo once and every sheet holding that item is already correct.

The mirror rule: per-character state lives on the character, never on the shared record. Each entry in a character's spellbook list pairs the book reference with its own castToday flag — because if daily use were written to the spellbook file itself, two knaves carrying the same spell would be casting from the same tank. When you add anything consumable — charges, ammunition, blessings, wear — keep that split: the shared file describes the thing; the character tracks this copy's state.

Changing the schema

Schema edits push with craft push --include-types, which validates the new schema against every existing file of that type — a field you rename or constrain will name each record it breaks before anything lands. Run craft check first. When you add a mechanic, the order of preference is: a computed field, if it is arithmetic on existing data; a stored field, only for a genuinely new dice-given fact; and never a second copy of something derivable.

Manual updated Jul 29, 2026.