← 20 Below

Visual System

The Tool Ecosystem

Two sources of truth, three delivery paths

Every app, script, and Owlbear Rodeo extension in the 20 Below project, and exactly what feeds each one — confirmed against the actual source code and READMEs, not assumed from what the apps merely look like they should do.

Rules data & character tools
Manuscript & publishing
Reads character JSON
Deliberately standalone
Rules Data & Session Tools Manuscript & Publishing Deliberately Standalone rules/ hand-authored data contract Character Creator app/ (browser) + desktop/ (Tauri) live fetch† character JSON Battle Tracker tracker/ + desktop 20 Below Roster Owlbear extension, separate repo Encounter Difficulty Calculator prep/ + prep-desktop/ Scrivener Manuscript 20 Below Mansuscript.scriv scriv2web.py tools/ converter scriv2brew.py tools/ converter Web Book webbook/, build output Brewery markdown opened by hand, not auto-piped The Brewery brew/ + brewer-desktop/ Print-ready pages PDF, two column, bleed 20 Below Dice Owlbear extension, separate repo no character-JSON integration — by design 20 Below Bestiary Owlbear extension, separate repo scene assets, not part of the JSON chain
† Live fetch: 20 Below Roster reads its Health/Poise/Sanity threshold definitions live from the Character Creator app at runtime, falling back to identical local copies if that fetch fails — so Roster can’t quietly disagree with the app about what “Dead” or “Shattered” means.
Known, unresolved divergence: scriv2web.py and scriv2brew.py format the same manuscript source differently in places — the current example is Gift lists, which the web edition renders as bullet points while The Brewery prints them as run-in prose. Both may be intentional (print density vs. web scanability), but the two outputs have not been reconciled or documented as a deliberate choice yet.