๐ฒ Solo Dungeon Master
An AI-powered solo tabletop RPG app that runs entirely in your browser, using the Cypher System rules. Your API key never leaves your device โ all requests go directly from your browser to the Anthropic API.
Live: apps.fuzzyworld.net/dm/
How it works
On your first visit you'll be asked for an Anthropic API key. The key is saved to your browser's localStorage (AES-GCM encrypted) so you only enter it once. After that, the game UI appears immediately on every return visit, resuming your previous adventure automatically.
The game is powered by claude-haiku-4-5-20251001 and uses Claude's tool-use API to maintain a structured character sheet (Might/Speed/Intellect pools, XP, cyphers, equipment) while generating freeform narrative. Costs roughly a few cents per session.
Features
- Cypher System character creation โ pick a Descriptor (34 options), Type (Warrior, Adept, Explorer, Speaker), and Focus (69 options) to form the sentence "I am a Clever Warrior who Hunts."
- Setting selector โ choose Classic Fantasy, Ninth World (Numenera), Modern Thriller, or Science Fiction at character creation; adjusts currency, tone, special-ability vocabulary, and available Foci
- Three stat pools โ Might, Speed, and Intellect each with current/max and Edge displayed; colour-coded bars shift green โ amber โ red as pools deplete
- Damage track โ one pool at 0 โ Impaired; two at 0 โ Debilitated; all at 0 โ Dead
- Skills โ starting skills populated from Type and Descriptor; sidebar section shows each skill with a colour-coded rank badge (green Trained / gold Specialized / red Inability); overlapping trained skills automatically promote to Specialized
- Cyphers โ one-use items found during play; displayed in the sidebar with Cypher Limit enforcement
- Advancement modal โ spending 4 XP opens a choice dialog: increase a pool max by 4, add +1 Edge to a stat, train a new skill, specialize in a trained skill, or describe a custom improvement; four improvements advance your Tier (max Tier 6)
- Session persistence โ adventure state and conversation history saved to
localStorage; reloading the page resumes mid-scene; save version guard offers Markdown export before discarding incompatible sessions - Cost display โ per-turn and session cost estimates shown in the sidebar (based on token counts from the SSE stream)
- Dice roller โ d4 through d100, configurable count
- World Notes โ orange-bordered GM meta-context panel for providing background lore, world physics, and house rules that Claude treats as absolute truth
- Share links โ generate an encrypted
#k=โฆURL so someone else can use the app with your API key; they enter a passphrase you share separately; the key is never in the URL - Report Issue โ in-game button that collects debug info (character state, recent errors, session cost) and opens a pre-filled bug-report email
Running locally
npm run dev # serves public/ on http://localhost:3000
Requires Node.js. No build step โ the entire app is a single public/index.html.
Architecture
| Concern | Approach |
|---|---|
| AI backend | Anthropic Messages API, streaming SSE |
| Key storage | AES-GCM + PBKDF2 (Web Crypto API); falls back to XOR stream cipher on plain HTTP |
| Share links | AES-GCM encrypted blob in the URL hash (#k=); hash is never sent to the server |
| Session state | localStorage โ character sheet, conversation history, rendered HTML |
| Analytics | metadata.user_id in each API request carries p_<playerId>:g_<gameId> for Anthropic Console |
| Deployment | apps.fuzzyworld.net โ npm run deploy publishes public/ |
Why a single file?
public/index.html is currently ~3,500 lines of vanilla JS โ no build step, no bundler, no TypeScript. This is intentional. The constraint keeps the CI pipeline trivial (push public/ โ GitLab Pages deploys it) and makes the project easy to fork and self-host without a Node.js toolchain beyond the dev server.
The tradeoffs are real โ no type safety, no module splitting, global state everywhere โ but acceptable for a project of this size and pace. If the file grows significantly or type errors become a recurring problem, the natural upgrade path is Vite + TypeScript: split index.html into modules, add a vite.config.ts, update the CI script: step to run vite build, and point GitLab Pages at dist/ instead of public/. That migration is well-understood and can be done incrementally.
Reporting issues
Use the ๐ Report button in the top bar โ it collects debug info automatically.
License
The source code is licensed under the GNU Affero General Public License v3.0. If you run a modified version of this app as a network service, you must publish the modified source under the same license.
The game rules content (Cypher System types, descriptors, foci, mechanics) is used under the Cypher System Open License ยฉ Monte Cook Games. The CSRD is free for use in digital products; see the CSOL for full terms.
ยฉ 2026 Pavel Safronov
About
This game is written by Pavel asking Claude to implement features. This paragraph - written by Pavel - is the only hand-written code in this repo. Part of the experiment here is being able to create a complex RPG game with Claude, while also utilizing Claude in the game itself. Let's see how this goes. Enjoy!