Builder's Manual · Chapter 2

The Character Sheet

The character type is the most opinionated thing in this project, and the piece most likely to need extending. Here is why it is shaped the way it is.

Abilities are stored flat

strength, agility, presence, toughness, spirit are five top-level numbers bounded to -3..+6 — not a nested abilities object.

In most d20 systems you store a score and compute a modifier. In Pirate Borg the modifier is the only thing that exists — the 3d6 sum is discarded at creation and never referenced again. So there is nothing to derive, and a nested object would only add a path segment to every binding and expression. They render as steppers with min -3 and max 6, which is also the entire legal range, so the sheet cannot express an illegal character.

What is computed, and why

Nothing derived is stored. The computed fields are:

  • carryingCapacity8 + strength.
  • breathMinutesmax(1, 1 + toughness).
  • armorTier, armorDie, arcanaBlocked — read through load($self.armor).
  • defenseDr12 + (load($self.armor)?.defenseDrPenalty ?? 0).
  • luckDie — read off the referenced class.
  • className — the class's name, or "Landlubber".

If you add a derived value, add it as an expression field. Do not add a number the player has to remember to update.

The armor penalty trap

armor carries two penalty fields and they do not stack.

agilityDrPenalty is the penalty on general Agility tests. defenseDrPenalty is the total penalty on defense specifically — it replaces the Agility penalty rather than adding to it.

This exists because conquistador plate is +4 DR on Agility tests but only +2 on defense. If you add new armor, set both fields explicitly. Setting only one will silently give you the wrong defense DR.

Daily resources are stored counts

ritualUses, prayerUses, and spellUses are plain numbers rendered as tappable dots, not a computed resource array zipped against a class definition.

That is a deliberate exception to the usual Craft idiom, because these maximums are rolled, not derived: d4 + Spirit each dawn for rituals, d2 + Spirit for prayers and spells. There is no fixed maximum to compute against. The player rolls, sets the dots, and spends them down.

If you add a resource with a fixed maximum, do it the normal way instead: define the rows on the class file and zip them with a stored state map.

Conditions

conditions is a string array driven by ConditionToggles with a fixed option list. Add to the options in the layout when your setting introduces a new status; the schema needs no change.

Manual updated Aug 1, 2026.