fuzzyworld

dm

App: https://apps.fuzzyworld.net/dm/

Contribute: contrib-68uq+dm@fuzzyworld.net (how) · Report a bug: bugs-k7q4+dm@fuzzyworld.net

phone

git clone https://code.fuzzyworld.net/dm.git

Open in VS Code · Open in VS Code in the browser · License: AGPL-3.0 · CI: ✓ passed

Recent commits

2026-10-27dd06472✓ Rename .gitlab-ci.yml to .fw-ci.ymlPavel Safronov
2026-10-26b6c5244Deploy to apps.fuzzyworld.net with fuzzyworld-toolsPavel Safronov
2026-05-2834071afdocs: explain single-file architecture decision and Vite+TS upgrade pathPavel Safronov
2026-05-2762945a8docs: add About section with author's notePavel Safronov
2026-05-27342a0a0fix: revert README links to blob view URLPavel Safronov

Full log

🎲 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

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!