State, References, and Computed Fields
Craft is most reliable when each mechanic has a clear home. Shared definitions belong in reusable files. Mutable campaign or character facts belong in writable state. Derived values belong in computed fields. Presentation belongs in layouts. Keeping those layers separate prevents both rules drift and AI bookkeeping errors.
Stored state
Store a value when it must remain true until something in play changes it. Current Hit Points, S.D.C., M.D.C., P.P.E., I.S.P., ammunition, armor condition, XP, applied level, learned-at-level, permanent attribute rolls, permanent advancement dice, and similar values are state.
A random permanent value must be rolled once and stored. If you put 1D6 in a computed formula for a permanent Hit Point increase, the sheet has no memory of the original roll. That is not character advancement; it is rerolling history.
Computed values
Use computed fields for deterministic totals: current skill percentages, class-derived bonuses, attribute bonuses, carrying limits, attacks per melee, save bonuses, movement, or the next XP threshold when all required inputs are available. A computed value should be reproducible from stored state and referenced definitions.
Do not write computed fields into content records. Let Craft evaluate them from the schema. If the layout binds to a property inside a computed object, declare that property in the computed field's object schema so the path actually exists.
Reference depth
Keep frequent Character dependencies direct. Craft's computed reference loading is intentionally shallow. A chain like Character → O.C.C. → Hand-to-Hand Style may be fine for human reading, but if a Character formula needs Hand-to-Hand data every time, give Character a direct active-style reference. The same principle applies to Rules Profile, Attribute Rule Set, Character Creation Profile, Environment, Species, and other definitions used by Character calculations.
This is not redundant data in the bad sense: the reference says which definition is active. It avoids hidden multi-hop dependencies that the expression engine cannot reliably traverse.
Modifiers need target and type
Avoid a bag of anonymous +2 values. A reusable modifier should say what it affects, what unit it uses, its source, and any condition. Strike, parry, dodge, saving throws, skill percentages, S.D.C., and P.P.E. are different targets. A dice expression, a flat number, a percentage, and a text exception are different units.
The Character engine should sum only compatible numeric modifiers. Text and dice modifiers remain data for the appropriate resolver rather than being coerced into a number.
Auditability
Creation state and advancement logs exist because permanent changes must be traceable. When a player asks why an attribute is 19 or why Hit Points increased, the sheet should be able to point to the stored roll and the source that granted it. Audit fields are not decoration; they protect continuity across long AI-run campaigns.
When a World adds a new subsystem, decide first which values are definition, mutable state, deterministic computation, and presentation. That four-way decision usually reveals the correct schema before you write any files.
For persistent class resources, give each resource progression a stable resourceKey; store per-character current/maximum values in resourceState. The Character's computed additionalResources zips selected O.C.C./R.C.C./P.C.C./Species definitions with that stored map. This follows Craft's recommended definition-plus-state pattern and avoids one field per resource.