Resources & Attributes
The heart of worldbuilding - what a resource is, how a variant differs from an edit, and how custom fields stay flexible without becoming a free-for-all.
A resource is the thing a worldbuilder makes: a character, a place, an item, a faction. Almost every decision in this area is about one tension. Creators want the freedom to shape a resource however their world needs, and the system wants enough structure to search, validate, and reveal that resource safely. This page is how Chronicler holds both.
Resources come in families
A character and its evil-timeline counterpart are related, but neither is more "real" than the other. Chronicler models this as a flat, one-hop family. Every member is a first-class resource. Being a variant is a role a resource plays inside the family, not a lesser type it is stored as. A primary pointer, which defaults to the family root, names the current-facing member, so a list can show one canonical version while the alternatives stay reachable.
Editing, evolving, and splitting are different acts
It matters whether a change is a correction, a step forward in the story, or a fork into a new thing. So Chronicler names three intents. An in-place write is either an ordinary edit or an evolution, a marked step in the resource's own timeline. A variant is not a change at all; it is a new resource minted by a split. Because everything is event-sourced, any past state can be rewound from the stream. Evolutions also materialise into listable, addressable versions, so looking at how a resource stood three eras ago is a direct query rather than a replay, and it still obeys reveals.
Attributes are structured, but not rigid
Custom fields, the attributes, are driven by a schema. A value is a string or a list of strings, typed by its field, and validated against the set of values that field allows, taking inheritance down the family into account. The field carries more than a datatype. It holds how the value should look and be authored: an accent colour and icon, whether it takes multiple values, whether it pins to the sidebar, whether text is multi-line, the structured options a select offers, and any default or locked value. Putting presentation on the field means the same attribute looks the same everywhere it appears.
Room for the field the schema forgot
A schema can never anticipate every field a creator will want mid-flow. So a resource may carry ad-hoc fields of its own, outside its schema. An ad-hoc field is a full, rich field, as capable as a schema field, but scoped to the one resource rather than shared. A strict schema can forbid them, for worlds that want the discipline. A resolved attribute always names its origin, whether it came from the schema, from an ad-hoc field, or is an orphan, so nothing is ambiguous. And when an ad-hoc field proves its worth, a config author can promote it into the kind's schema, or rebind the resource to a different schema of its kind. The escape hatch has a path back to structure.
Counting what a card shows
Filtering a resource list by an attribute sounds trivial until inheritance is involved: a facet count has to match what the card actually displays, inherited values included. Chronicler keeps a dedicated read model of each resource's effective, own-plus-inherited values, maintained by a one-hop projector, so a facet bucket is honest. Select and boolean fields return buckets, and text is filter-only.
Game mechanics without picking a system
Stat blocks are kept system-agnostic behind a plugin interface, with D&D 5th Edition as the first system, so a world's mechanics are not welded to one ruleset.
Where this connects
Resources do not stand alone. They link to each other and to notes through The graph, and what a player sees of a resource is governed by Play, reveals and campaigns.
Read the record for the detail
This page is the guide. The full records under docs/adrs carry the exact validation rules, the version storage model, and the alternatives that were weighed and rejected.