Extending the Ruleset
Adding to the system is normal and healthy — a new field, a new type, a new school. The rules for doing it without breaking the engine are few, and they all flow from the invariants in Chapter 1.
The guardrails
Before you change anything, check it against the six invariants: the roll grammar, the preparation promise, the dynamis cap, the two-school tension, grade gates, and the failure ladder. A change that preserves all six is an extension. A change that breaks one is a new game — which is fine, but it is a fork, not an edit, and the fork belongs in its own project.
The two most fragile spots: dynamis (anything that lets spark bank, be bought, or exceed 4 + grade × 2 unbalances the whole throttle) and grade gates (anything that lets a practitioner use an entry above their grade removes the vertical axis). Protect those two and most other edits are safe.
Adding fields
- Follow the existing shapes. Long-form text is
textarea; short choices areenum; small numbers arenumberwith aminimum(andmaximumwhere it exists — grade is 1–4, allegiance is −10 to +10). - Enums are commitments. A
kindenum that a world wants to extend (a new daimon kind, a new work kind) should be extended deliberately at the schema, and every existing file re-checked. Enums silently reject bad data — that is their job. - Defaults are the contract. New fields get sensible defaults (grade 1, allegiance 0, miasma 0, dynamis 6, rarity common) so existing files without the field still read correctly. The computed fields on the character — dynamisMax, dynamisCycle — already handle a missing value gracefully; keep that habit.
Reference fields
References are how entries point at each other: patron → deity/daimon, inventory → equipment. Conventions:
- Write readable slugs (
deity/athena,daimon/kothos); the platform resolves them to ids. - One target type per field unless a mixed list is genuinely needed.
- A reference that cannot resolve stores as a draft — it resolves once the target exists. Create the target first, or accept the draft and create it soon after.
- References are for wiring, not description. If an entry would inline the whole neighbor, reference it instead.
Computed fields
Computed fields derive values at read time — the character's dynamisMax (4 + grade × 2), dynamisCycle (which court's schedule refills the spark), carryingCapacity and totalInventoryWeight (from inventory). Rules for writing new ones:
- Put the expression on a normally-typed field with an
expressionkey; never put computed fields inrequired. $selfreads the file's own fields;load()reads a referenced file (one level deep). Nulls propagate — default with??.- Never write computed values into data files. They are read-only; change the source fields or the expression. A data-file write that includes a computed field is rejected.
- A computed field should save someone from bookkeeping, not encode a rule the player is supposed to feel.
dynamisMaxis a bookkeeping save. A computed field that renders prose ("your works are dormant") is a presentation string — keep that in the layout, not the schema.
New file types
When the world needs a container that does not exist (a Faction, a Formula catalog, a Treasure), create a file type: give it a name, a schema in the same style, a layout, and a plural folder. Before you do, check that the need isn't already covered — formulas live in the Mystery type (kind = formula), spirits in Daimon, rules in the System document. The type count should stay small and legible; a new type is justified when entries of that shape would otherwise be scattered across notes.
Layouts
The rendered sheet is a layout — cards, field lists, stat grids — and its order is reading order. When you add a field, add it to the layout (the Mystic Trackers card pattern: a field list for the trackers, a stat grid for the computed row). Keep the layout in sync with the schema: a field the sheet never shows might as well not exist; a layout that shows fields the schema lacks will render empty.
Migrating with care
Prefer update over wholesale rewrites: change one field, one property, one card at a time. When you do rewrite, re-read the full document first — a projection written back destroys everything it did not select. The schemas and layouts are the contract with every existing file; treat them with the same care you would treat a live character sheet.