v0.102.0 — Campaign configuration: the settings and the Treasury model
Shipped 2026-09-21 — built on version/0.102.0, twenty-one commits,
merged to main as 0fe2aef5, tagged v0.102.0. The twelfth of the
releases the near-term roadmap sequences from the
August 2026 heuristic evaluation, and part one of
Campaign configuration; the roadmap
page is the settings and the Treasury model.
Part two, the Treasure Manager, is v0.103.0.
The help is Campaigns → Configuration and
The Treasury. Module releases: dnd5e
0.16.0 and system8 0.17.0 (Module API 1.38.0); Action API 0.4.0.
The tabletop properties a group decides at session zero — starting level, which options are open, how characters advance, how treasure moves, what players may do without the GM — had nowhere to live: a campaign carried grid and reference data and nothing a rulebook calls a variant. Now each system module declares its settings and the platform declares three groups of its own, the values are stored once on the campaign, a Configuration set of sections on Edit Campaign renders them, a creation walkthrough asks the session-zero ones first, and — because half of session zero is about treasure — the Treasury's data model ships with them, so the treasure settings govern something. Decisions CC-D1 (defaults at read; a schema change is never a migration) through CC-D8 (what the walkthrough asks) at their recommendations.
The schema and the settings
- Module API 1.38.0 (CC.1) —
SystemModule.campaignConfigurationSchema: a typed, ordered list of settings in groups, each with one of seven kinds (number,boolean,choice,multi-choice,text,filterover a module catalogue faceted by source,tableby level or tier), a default and help text,askedAt: creation,requires,editableBy;getCampaignCataloguefor what a filter ranges over;startingKitForfor what a new character begins with. Pure functions inpackages/shared: validation, resolution (a missing key reads its default — CC-D1), reconciliation on a system change,describeCampaignSettingfor the walkthrough's side card, and a schema-shape check the server runs at load so a broken module schema is logged and left out rather than taking the campaign down. - One column and two routes (CC.2) —
campaigns.configurationholds only the edited keys;GET /api/campaigns/:id/configurationanswers the combined schema, the edited keys, every key resolved,features,canEditandisOwner;PATCHmerges a partial record (nullclears a key), validates strictly, refuses an owner-only key for a non-owner, and commits. - The platform's groups (CC.3) — Players (eight keys, every default
today's behaviour; two of them are grants: a
role-defaultrow on the campaign with principalcollaborator/maporcollaborator/character, which the permission resolver reads at each child, so the tab and the Share dialog read one thing; three gate routes: making maps, inviting, custom channels), Rolls (three, declared; the client routes a roll's frame in v0.103.0), Treasure (six). - The Configuration sections (CC.4) — every group of the combined schema is a section of Edit Campaign under a Configuration heading, one autosaving field per setting by kind (a filter is a catalogue picker with source facets; a table a grid), the help under the label, default until edited and Reset to default after, inert with a reason where a feature is missing or the key is the owner's.
- dnd5e 0.16.0 (CC.5) — six groups, ~40 settings per edition: character
creation (starting level, ability score methods, rerolls, point-buy budget,
filters over sources / classes / species / backgrounds / feats / spells,
multiclassing, HP at level up, starting magic items, starting gold by
level), advancement, combat, rest and recovery, gear and magic,
inspiration; the catalogues from the bundled SRD with
sourceon every entry; the starting kit from the class record (2024's option A; 2014's Equipment section read (a) throughout), items matched to the equipment catalogue for weight and value. system8 0.17.0 (CC.6) — five groups, 23 settings with the docs' values as defaults, the nine classes and Classless, feats and powers by the docs' slug, andstarting-wealth.md's kit and table. Both built against a platform that may not have the types (CI resolves@purple-cat/sharedagainstmain): the setting types are mirrored and the members spread from anobject, typechecked against both hosts. - The creation walkthrough (CC.7) — Create makes the record and stays on
the page; then one step per group asked at creation (the system's before
the platform's — CC-D8), each field the same autosaving one with the
composed explanation beside it, then distance and area, currencies and
reference data as the Edit form's own sections, then a summary and Done.
Walkthrough.tsxis the generic stepper the character walkthrough will reuse. - A system change re-validates (CC.8) — kept, dropped with reasons, said
in the answer and a toast. Action API 0.4.0 (CC.9) —
api.campaign.configuration(key?), read-only, once per run;useCampaignConfiguration()on the client. The.catarchive (CC.10) carriesconfigurationincampaign.ymland the Treasury astreasury/buckets.ymlanditems.yml.
The Treasury's model
- The holder model (CC.11 — CC-D3) —
equipmentgainscampaign_id,holder_type,holder_id,bucket_id,earmarked_character_idandprice;character_idis nullable and kept in step; existing rows backfill toholder_type: character; the inventory reads by holder; an item a bucket holds is refused on the sheet's edit and delete. - Buckets (CC.12) —
treasuries(one per campaign, keyed by its id) andtreasury_buckets(party / hoard / merchant / starting / loot,revealed,carriedByvalidated againsttreasure.partyTreasure); the party bucket comes with the campaign; a member sees the revealed buckets and the party's; a deleted bucket's items become nobody's rather than vanishing./api/treasury/:campaignIdand/buckets. - The transfer (CC.13 — CC-D5, D6, D7) —
POST …/transfer { itemId, quantity?, to }: a conditional write that refuses when someone was first (already-moved), a stack split as a row of its own, a coin item claimed by a character credited to the wallet, the campaign's id on an item entering the Treasury. An Editor moves anything; a member moves their own character's items and claims from a bucket they can see. - The treasury as an entity (CC.14 — CC-D4) — versioned as itself
(
treasury:<campaignId>: the buckets and every item with the campaign's id), its permissions its campaign's; every bucket write and transfer a commit, and a transfer also a commit of a character at either end, whose before-state is read ahead of the write. Listed, diffed, blamed and restored through/api/historylike the rest. - Treasure mode (CC.15) —
treasury-onlyrefuses a player's hand-added item;distribution-onlyalso refuses claims until v0.103.0 gives it a session; earmarks honoured. Starting equipment (CC.16) — on a character's link: the system's kit transferred in and its coins credited (system norms), the coins and a merchant bucket (starting currency), a starting bucket for the GM's earmarks (GM-curated), nothing (free); once per character. The Players gates (CC.17) — characters per player, new characters pending until an Editor accepts (their kit granted then), andsheetEditing: gm-onlylocking the owner's sheet to control in the one access resolver.
Guards and verification
Every platform key names the file that reads it or says why it is declared ahead of its enforcement (CC.18); every module schema is checked at load; the help wiki's Campaigns page describes the walkthrough, the Configuration sections and the Treasury. Verified live: the three platform groups and the 5e and System 8 groups in the nav, a grant-backed toggle writing its row, the 5e Classes picker listing the SRD under its source, a filter saving, the walkthrough's eight steps end to end. Harness tests hold the double-claim, the wallet credit, the stack split, the modes, the gates and the treasury's commits.