← Back to Projects
Project

The Living Codex

A tabletop-ready character sheet that runs locally and keeps your campaign data in your hands.

Published

I got tired of opening a character tool and feeling like I was crossing a border checkpoint. Log in. Subscribe. Hand over the sheet. Repeat. I built The Living Codex because I wanted a companion I could keep on my own machine, understand line by line, and trust when the session got messy.

My table rules for this project are simple: no forced cloud, no account gate, no silent tracking, and no pretending the player does not own their own sheet.

Tarakesh standing with staff and shield.

Prologue: Why This Exists

I wanted the feeling of a weathered field journal, not a product funnel. My character sheet should feel like gear I packed for the trip, not software I rent by the month. So I wrote The Living Codex to make ownership obvious: if I need to inspect the rules, change the data, or move my character somewhere else, I can.

Act I: The Engine Room

I kept the guts readable on purpose. Local rules files load first, then the sheet builds from that, then the modifiers and derived values fall into place on screen. When a number looks cursed, I can follow the trail step by step instead of shrugging at a black box.

Act II: Built For Real Sessions

I built this for actual table rhythm, not screenshots. I can spin up a character, manage known and prepared spells, track inventory and session notes, then pack everything up and bring it back later without turning the sheet into unreadable sludge. If I hand the file to future-me, future-me can still read it.

Act III: The Long Campaign

This is a functional beta in the literal sense: I can run real sessions on it now. The core loop is stable. I’m still filling in tricky rules edge cases, smoothing rough spots at the table, and bringing the newer parts of the app up to the same standard as the older ones. It is playable today, and still getting sharper.

Night banner scene with moonlit skyline and owl silhouette.

How To Use It

If you are opening The Living Codex for the first time, start by creating a new character and choosing your ruleset, class, species, and base ability scores. Once the sheet appears, fill your core identity details, then move through spells, inventory, and session log in the same order you would use them at the table.

When you reach a good stopping point, export a ZIP so you have a portable snapshot. On your next session, import that ZIP, sanity-check your spell and inventory sections, and keep going. That simple export/import habit gives you a clean trail of character history and makes it easy to move between machines without drama.

The files inside that ZIP are human-editable by design, so if you are comfortable tweaking JSON or CSV, you can inspect and adjust your data directly before importing again.

PDF export support is on the roadmap and coming soon. For now, ZIP export is the reliable way to save and move your character sheets.

What is inside the ZIP (exact file contract)

If you want to hand-edit a save pack, this is the practical map. Start with the import order, then use the schemas and fix rules.

Import order (v2)

1) character.json loads first and remains canonical.

2) CSV overrides apply next if present.

3) validation/fixes run, then diagnostics are written.

Required file

character.json is mandatory and must pass the v2 schema.

character.schema.json

Optional CSV overrides

inventory.csv using inventory.schema.csv

spells_known.csv + spells_prepared.csv using spells.schema.csv

log.csv using log.schema.csv

Diagnostics

report/import-report.json is optional output, never required input.

Fix policy: import-fix-rules.md

CSV header quick reference

Keep headers exact, keep booleans true/false, and keep numbers numeric.

inventory.csv: id,name,category,qty,weight_each,weight_unit,value,value_currency,attunement,container,equipped,notes
spells_known.csv / spells_prepared.csv: id,name,level,school,casting_time,range,components,duration,concentration,ritual,source,notes
log.csv: id,ts,title,body,tags,location

Import fixes in plain language

Safe fixes are automatic: missing optional arrays/objects can be initialized, minor type coercions can be applied, and known aliases can be normalized.

Guided fixes need your approval: unknown ruleset ids, migrating legacy class fields, and non-trivial slot/race rewrites.

Blocked issues stop import: invalid root JSON shape, missing required metadata, unparseable date values, or malformed CSV headers that cannot be mapped.

Technical details (v2): read this before hand-editing packs

If you ever edit a character pack by hand, this section is meant to be enough to work from directly. It covers storage, import order, exact file contracts, fix behavior, and a safe edit workflow.

Runtime and storage

The Living Codex v2 runs entirely in-browser. Primary persistence is IndexedDB (living-codex-v2) and recovery backup is localStorage (living-codex-v2.backup). Changes autosave (debounced), export triggers a save first, and successful saves update meta.modified_utc.

ZIP contract and import order

Expected pack contents:

character.json (required, canonical), inventory.csv (optional override), spells_known.csv (optional override), spells_prepared.csv (optional override), log.csv (optional override), and report/import-report.json (optional diagnostics output only).

Import precedence is strict:

1) Load character.json 2) Apply present CSV overrides 3) Normalize and validate 4) Accept or block import with diagnostics report.

Contract sources of truth

Runtime headers: js/v2/io/headers.js.

Schemas: character.schema.json, inventory.schema.csv, spells.schema.csv, log.schema.csv.

Exact CSV columns (v2)

inventory.csv (exact order): id,name,category,qty,weight_each,weight_unit,value,value_currency,attunement,container,equipped,notes

spells_known.csv and spells_prepared.csv (exact order): id,name,level,school,source,ritual,concentration,casting_time,range,components,duration,spell_id,page,notes

log.csv (exact order): timestamp_utc,type,label,data_json

Keep headers and file names exactly unchanged if you want import overrides to apply cleanly.

character.json safety guide

Safe edits: text fields (names/notes/labels), numeric counters (HP/slots/tracker counts), and list contents (spells_known, inventory, log).

Be careful with IDs (meta.id, row IDs), booleans (use true/false, not quoted strings), numeric fields (keep numeric), and timestamps (ISO format).

Avoid deleting required roots like meta, core, abilities, and combat.

How import fixes work

Fix behavior is defined in import-fix-rules.md and uses three modes: auto, guided, and blocked.

Auto fixes (safe/deterministic) include: missing optional arrays/objects initialization, numeric string coercion, boolean coercion (yes/no/1/0), duplicate list de-duplication, alias normalization (armour -> armor, saving_throws -> saves, raceId/race_id -> speciesId), ability clamp 1..30, tracker clamp rules, spell level clamp 0..9, generated missing row IDs, and missing meta timestamp fill-ins.

Guided fixes (requires user confirmation) include: unknown ruleset_id, migrating legacy class fields into core.classes, prepared spells not present in known list, invalid tracker reset values, and non-trivial slot overuse corrections.

Blocked issues (import stops) include: invalid root JSON object, missing/unsupported meta.schema, missing meta.id, missing meta.name, missing meta.ruleset_id without fallback, malformed CSV headers that cannot be mapped, and unparseable data_json in log rows when no fallback extraction exists.

Diagnostics report fields

Each fix candidate is reported with code (stable id), path (JSON/CSV location), message, before, after, and mode (auto, guided, blocked), so edits remain auditable.

Practical hand-edit workflow

  1. Export from The Living Codex.
  2. Unzip to a working location.
  3. Edit character.json and/or CSV files.
  4. Keep filenames and CSV headers exact.
  5. Re-zip with files at ZIP root (no extra parent folder).
  6. Import in v2.
  7. Check diagnostics and resolve guided/blocked items.

Forge Your Field Journal

Bring me your Living Codex export, and I’ll turn it into a print-ready campaign chronicle: character sheet, spellbook, session log, and campaign notes, styled to match your Codex theme.

Your ZIP is used only to generate this PDF request.