Beat logging was too broad: dialog cards, DM-only secrets and suggestions carried a log affordance, so the session recap filled with runbook chatter instead of table events. One predicate now decides it — the read-aloud, prose story blocks, the encounter trigger, and the gist as a single tick. check and interaction lose it too: they tell the DM how to run a moment, they are not something the party experienced. Complete Scene gains an already-ticked "log everything on this scene" row that adds only what is still un-ticked, in one write on the session chain, leaving hand-made ticks with their own timestamps. Unticking writes nothing. The gist gets its own tick and is deliberately not folded into the bulk row — running the gist is the alternative to running the scene, so claiming both happened would be a lie. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| demos | ||
| docs | ||
| resources/audio | ||
| src | ||
| tests | ||
| tmp | ||
| .gitignore | ||
| bun.lock | ||
| CREDITS.md | ||
| electron-builder.yml | ||
| HANDOFF.md | ||
| LLMS.txt | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
| tsup.config.ts | ||
| vite.config.ts | ||
DnD Toolkit
Local desktop toolkit for Dungeon Masters — author custom creatures/items, run encounters, roll dice, draw maps, and present a curated Player view on a second monitor while keeping secrets on the DM screen. Electron + Bun + Chakra UI v3 + react-hook-form, JSON-file storage, bundle-able to a distributable app.
Core design principle
The Player window may be live-streamed, so secret data never reaches the Player renderer at all — the main process computes a structurally redacted DTO (secret fields physically absent) and pushes that to the Player window. Redaction is omission, not masking.
Stack
- Electron + electron-builder (distributable bundling)
- Bun — package manager + tooling runtime (Electron itself runs on Node)
- Chakra UI v3 (
createSystemtheme) + react-hook-form - @excalidraw/excalidraw for maps (Phase 5)
- JSON files only — no SQL, so zero native modules (
npmRebuild: false)
Layout
src/main/ Electron main: windows, IPC handlers, stores, redaction, engine
src/preload/ Two preloads — master (full) and player (redacted-read only)
src/web/ React renderers: index.html → Master, player.html → Player
src/shared/ IPC contract + domain + player-DTO types
tests/ bun test units (redaction, later: engine, templates)
Scripts
bun install
bun run dev # build renderer + main, launch Electron
bun run tsc # typecheck (must pass)
bun test # unit tests
bun run dist # electron-builder distributable
Features
- Campaigns + "Shared Data" — multiple campaigns; a Shared-Data (library) scope whose characters/items/maps appear across every campaign. Never "no campaign".
- Unified Characters — ONE entity for monsters/bosses/NPCs/allies/players (
kind). All fields optional. Image (copied into app data), tags, role/description, attacks & abilities (with pregenerated presets), per-attribute Player Visibility, view-vs-edit preview, duplicate, templates (generic slots → instantiate). Auto-generate stats by level; preview shows estimated level + CR. - Items — rarity select, tags, properties, Player Visibility; search + tag filter.
- Encounter runner — initiative, HP/damage/heal, statuses, turn tracking, "set live".
- Event engine — HP crossing 50%/25% or a status landing → prompts the DM to reveal a colored ring / status to players (decline = players never learn).
- Maps — Excalidraw battle maps, character-linked tokens, "mirror to Player" (fast) with
dmOnly-element redaction; tags + search. - Player window — detachable, redacted view (initiative board + revealed bands/rings/statuses + art only when shared + mirrored map); blank-screen toggle.
- Tools — floating quick-dice button (bottom-right, click dice to stack a roll); Tools tab has a dice roller, encounter generator (84-monster tables) + estimator (slated for rework — see plan).
- Search / tags / dice everywhere —
TagInputautocomplete, regex-validatedDiceFieldwith a click-to-build popover (plain-English reading). - UI — modern dark theme, slim icon sidebar + fully-hidden hamburger/Drawer mode.
Status
Core + two refinement iterations done; next up: Campaign/Instance ("Play") layer, then Loot
section + plot boards. Verified: bun run tsc clean, bun test green, bun run build succeeds,
Electron boots (use --disable-gpu if the GPU process is flaky). Render with bun run dev on a
desktop. Roadmap, deferred backlog, and per-iteration status: ~/.claude/plans/shiny-beaming-hippo.md.
Architecture/file-map/conventions: docs/.