A harness that turns Claude Code into a persistent Game Master β a holodeck door and a fresh 1980s D&D table.
You do not load a wiki. You step through a door. Someone you came to meet is already talking. The book stays on the GM's chair; the campaign file is a journal of where you've been, not an encyclopedia of every city the book named.
This is not a chatbot you roleplay with. It's a harness: a thin, opinionated shell around Claude Code that gives the model the three things it lacks to run a real campaign β durable memory, a custom rulebook, and a world that keeps moving when you look away. Claude runs the table. The harness makes it stick.
There are two ways into a world, and both get the same living-world treatment:
- π Author something original β
/new-game. A genre-aware questionnaire interviews you, then Claude authors a book's worth of brand-new canon and a custom ruleset β and runs it through an anti-generic pipeline whose explicit job is to keep your world from collapsing into off-the-shelf high fantasy. This is the headline act. (jump β) - π Import a book you own β
/import. Drop in a PDF. The book goes on the shelf. Claude asks who you came to be (or meet), opens that page, and you talk. The rest of the book walks on when you do. (jump β)
Pick either. The persistence, the custom rulebook, the living world, the dying-and-handoff stakes β all identical underneath.
YOU THE HARNESS CLAUDE (Opus)
"I attack the β routes the beat, loads only β decides, narrates,
Terror Clown" the rules it needs, hands voices the NPC,
Claude the scene + memory rolls the dice
β β
reads & writes campaign state β "persist before you
(HP, NPCs, threads, clocks, narrate" β every
consequences) on disk change saved first
Every turn runs the same loop: gather context β decide β execute β persist state β narrate. The harness enforces the boring, critical part β nothing happened until it's written to disk β so the story survives across days, machines, and context windows. Claude handles the part it's extraordinary at: making it feel alive.
-
A memory that outlives the conversation. NPCs, locations, plot threads, facts, your character sheet, your whole history β all persisted as plain JSON per campaign. At each session's end the GM writes an arc entry (what changed, who matters now, what debts are open), and recall over your campaign's history is semantic β ask about "the clown" and it finds the summary that says Grimaldi. It tracks what's canon-from-the-book versus what you made happen. Close the laptop mid-fight; pick it up next week exactly where you left off.
-
A rulebook written for your world, not D&D. Whether you import a book or author one from scratch, Claude produces a World Bible (voice, tone, factions, geography, timeline) and from it a World Kit β a custom ruleset with its own stats, its own way of leveling, its own signature systems. A Dune import plays like Dune; a Dungeon Crawler Carl import plays like Dungeon Crawler Carl; and an original world plays like itself. D&D 5e is just one possible kit, not the foundation.
-
A world that pushes context to the model. The old failure mode of LLM roleplay is amnesia β the GM remembers your HP but forgot the cliffhanger. Here, every scene arrives pre-loaded: previously onβ¦, open threads, key facts, which NPCs are present and how they talk, the clocks ticking in the background, and any consequence about to land. Claude doesn't have to remember to look β the harness puts it on the table.
-
A world that keeps living. Consequences you set in motion fire on their own when you return to a place or enough time passes. Named threat clocks tick whether you're watching or not. Between sessions, a small, bounded set of off-screen developments advance. The place feels alive because it is still running.
-
Specialist sub-agents on tap. A fight starts and a monster-manual agent grabs stats; you cast something and a spell-caster looks up the mechanics; you go shopping and a gear-master handles inventory; a haunting vista appears and a scene-illustrator paints it in the background. They're book-first β they read your world's own rules before reaching for anything external β and they spin up invisibly so the story never stops.
-
Real stakes. The character can die. Telegraphed, earned, never by GM fiat β but death is a valid forward outcome, and when it lands the harness runs a hand-off so the show goes on (take over a party member, roll a newcomer, step in as a canon figure). The world remembers the fallen.
-
An illustrated campaign, drawn in-world. If you drop an
OPENAI_API_KEYinto.env, the GM is encouraged to illustrate big beats β a new location, a boss reveal, a haunting vista, your styled flourish β with real generated images, presented diegetically as the work of an in-world chronicler: a named artist with a locked art style and persona, both designed at world-creation time to fit your plot and tone. The same hand "draws" every image across the campaign, so your gallery reads like one artist's sketchbook of your story. No key, no problem β the GM just keeps narrating in text and never mentions images.
A campaign imported from Dungeon Crawler Carl. Tandy the sasquatch rips the skin off a Terror Clown, forces Carl to wear it as a disguise, then performs a sasquatch mating dance to distract Grimaldi while Donut frees the dragon. Standard Tuesday. (Images generated in-world, on the fly, by the scene-illustrator agent.)
Anyone can ask an LLM for "a fantasy setting" and get the same tired tavern, the same chosen one, the same five elemental kingdoms. The interesting problem isn't generating a world β it's generating one that doesn't drift to generic. That's what this pipeline is built to defeat.
You don't write the world. You answer a short genre-aware questionnaire (powered by interactive multiple-choice prompts), and Claude builds outward from your answers:
- A one-line premise in your own words β "Conan but on a drowned coast," "cozy folk-horror in a town that forgets its dead," "corporate clans fighting over charged ruins."
- The genre bend β the single most important anti-generic lever. Sword-and-sorcery (magic is blood-priced and villainous), high fantasy (deep lineage and old songs), sci-fantasy (nanomagic and clan politics), folk/cosmic horror (a wrongness beneath a fragile community) β each bend pushes the whole world somewhere specific.
- A narrative voice β whose voice should narrate this world? Howard, Le Guin, Gibson, Pratchett, or your own pick. Claude writes original prose in that author's fingerprint, and narrates every beat in it. Your world doesn't read like a generic narrator; it reads like a book.
- A locked art style β a deliberately surprising mashup ("a gilded medieval illuminated manuscript depicting cyberpunk megacities") and an in-world chronicler who "draws" every image, so the whole gallery reads like one artist's sketchbook.
From those answers Claude builds one stage, not a planet β seed β skeleton β play pack β handoff:
- Seed. Your answers become a structured world-seed β premise, tone, genre bend, voice, art style, chronicler. No gazetteer; the world's shape emerges at the table.
- Skeleton. Claude authors the world's coherent spine in one pass while the seed is fresh β name, voice, themes, factions, signature systems β then shows it to you for approval before going further.
- Play pack. Claude derives a custom World Kit from your world (never a silent 5e default), then stages exactly what tonight needs: one room you can stand in, the people in it, the exits you can see, and a hook that won't wait β never a continent.
- Handoff. Claude locks the chronicler and art style, then asks the one question β who are you in this world? β and the story begins.
The world is a world with its own voice, its own rules, and its own art, and it grows as you play: when a long-game opportunity appears, Claude seeds a threat clock, a story thread, or a new plot and lets it tick. That is the campaign's real long-term planning β authored at the table, not pre-built. /create-character remains an opt-in full sheet whenever you want one.
You: /new-game
GM: A few questions first. One line β what's the world?
You: Wandering swordsmen in a desert of glass where the gods drowned.
GM: Genre bend? (1) sword-and-sorcery (2) high fantasy (3) sci-fantasy (4) folk/cosmic horror
...
Got a favorite novel, a classic adventure module, a weird pulp paperback from the 70s? Drop the PDF into source-material/. Claude indexes the real text (the binder), writes a World Bible and World Kit so the room sounds like that book, then asks the only question that matters: who did you come to meet? You get that room, those voices, one hook. Not a gazetteer. Not a reskin. When you walk toward Stygia, Stygia is read from the book and written into the journal β not scraped on night zero.
Where to find books: the Internet Archive is a goldmine β thousands of free books, modules, and old pulp novels. Jump into IT and help the bad guys. Drop into Lord of the Rings and play from Gollum's perspective. It's your call.
Prerequisites: Claude Code
git clone https://github.com/Sstobo/Claude-Code-Game-Master.git
cd Claude-Code-Game-Master
./install.shThe install script sets up everything β Python, uv, jq, and all dependencies. It works on macOS and Linux with zero prior setup. (You can also just launch Claude Code and ask it to set things up.)
Then launch and play:
- Run
claudeto launch Claude Code - Run
/gmβ the harness takes it from there
/gm is the only command you need. It offers a New Adventure β author an original world (/new-game), import a book you've dropped in source-material/ (/import), or spin up a quick one-shot β then builds your character and runs the game. First thing it asks once a world exists: "Who are you in this world?" β play a character lifted straight from the source, an original of your own, or a nameless traveler who wanders in. The mechanics get figured out behind the scenes.
A single mega-prompt can fake a GM for one session. It can't remember your campaign next week, it can't enforce its own rules, and it drowns the model in mechanics it doesn't need this turn. The harness solves each of those directly:
- Thin always-on core, heavy rules on demand. A lean router stays in context; combat, social, skill checks, conditions, leveling, dungeon crawls, and narration craft load only for the moment that needs them. The model spends its attention on the scene, not the manual.
- State on disk, not in the context window. Memory is bounded by your filesystem, not the token limit. Campaigns can run indefinitely.
- Persist-before-narrate, enforced. Every state change is written before a word reaches you, so a crash or a context reset never loses your progress.
- Grounded in a real corpus. Scenes draw on actual passages β your imported book, or the canon Claude authored for your original world β via a local retrieval index, so narration stays true to the source until your choices change it.
You never see any of this. You just see the story.
Everything below is handled automatically by /gm. These are here if you want manual control.
There's really just one command you ever need:
| Command | What it does |
|---|---|
/gm |
Everything. Start or continue your story. The harness imports a book, builds a world, creates your character, runs a one-shot, saves, and shows your sheet β just talk to it. |
/gm also takes shortcuts if you want them: /gm save, /gm character, /gm overview.
Under the hood, /gm calls these for you β you never have to run them yourself, but they exist for manual control:
| Command | What it does |
|---|---|
/import |
Import a PDF/document as a new campaign |
/new-game |
Build a world from scratch |
/create-character |
Build a character in detail |
/enhance |
Enrich entities with source-material passages |
/world-check |
Validate campaign consistency |
/reset |
Clear campaign state |
/setup |
Verify/fix installation |
/help |
Full command reference |
The lean core loads these only when the moment calls for it:
| Skill | Loaded when |
|---|---|
gm-combat |
A fight breaks out |
gm-spellcasting |
You cast something |
gm-social |
You talk to / read an NPC |
gm-skills |
You attempt something uncertain |
gm-dungeon |
You enter a cave, ruin, or complex |
gm-conditions |
A status effect is applied |
gm-levelup |
You hit a milestone |
gm-craft |
Narration and pacing wisdom |
Spawn automatically during play, invisibly:
| Agent | Triggered by |
|---|---|
monster-manual |
Combat encounters |
spell-caster |
Casting spells |
rules-master |
Mechanical edge cases |
gear-master |
Shopping, identifying gear |
loot-dropper |
Victory, treasure |
npc-builder |
Meeting new NPCs |
world-builder |
Exploring new areas |
dungeon-architect |
Entering dungeons |
scene-illustrator |
High-impact visual beats |
create-character |
New characters |
The harness is plumbing you can poke at: bash wrappers (tools/) β Python managers (lib/) β per-campaign JSON (world-state/campaigns/<name>/). All tools follow the pattern bash tools/gm-<tool>.sh <command> [args]. Most accept --json for structured output.
| Tool | Purpose |
|---|---|
gm-campaign.sh |
Create, list, switch, delete campaigns |
gm-session.sh |
Session lifecycle, party movement, save/restore |
gm-context.sh |
Assemble scene context (world state + source passages) |
gm-player.sh |
Player stats β health, progression, gold, inventory |
gm-npc.sh |
NPCs β creation, updates, mood/goal/voice, party members |
gm-location.sh |
Locations and connections |
gm-plot.sh |
Quest and storyline tracking |
gm-combat.sh |
Persisted, resumable combat tracking |
gm-condition.sh |
Player conditions (poisoned, stunned, etc.) |
gm-consequence.sh |
Schedule future events and triggers |
gm-recall.sh |
Campaign memory β semantic recall, arc entries, memoir |
gm-clock.sh |
Threat clocks β pressure that mounts as time passes |
gm-lore.sh |
Grounded chapter briefs from the source book |
gm-note.sh |
Record world facts by category |
gm-time.sh |
Advance in-game time |
gm-search.sh |
Search world state and/or source material |
gm-enhance.sh |
RAG-powered entity enrichment |
gm-extract.sh |
Document import and extraction pipeline |
gm-overview.sh |
Quick world-state summary |
gm-image.sh |
Generate a scene image with gpt-image-2 and print a clickable link |
gm-reset.sh |
Reset campaign data |
At high-impact beats β a new location, a boss reveal, a big find β the GM can illustrate the moment with a real image instead of describing it in text:
bash tools/gm-image.sh generate --title "The Sunken Crypt" \
--prompt "A flooded stone crypt lit by green torchlight, dark fantasy, cinematic"It calls OpenAI's gpt-image-2, saves the PNG into the campaign's images/ folder, and prints a clickable file:// link you open to view it (the VS Code terminal linkifies the path). Every generation is logged with an estimated cost β run gm-image.sh log for the running total. Requires OPENAI_API_KEY in .env; without it the GM just keeps narrating in text. Use --quality low for quick drafts, high for marquee moments.
If your world is D&D-flavored, declare "kit": "dnd5e" in the campaign's ruleset.json and the harness pulls official rules, monsters, spells, and gear from the D&D 5e API β grounding numbers in real mechanics instead of guessing. For every other book, your World Kit runs the show, and the D&D mechanics refuse to load (so a bespoke world can't be silently overwritten by 5e).
Everything about how the harness works lives in docs/ β a knowledge layer where every doc declares the source files whose change would make it wrong, and staleness is machine-checked against git (OKF). Start with the flows (a play turn, importing a book, authoring a world, the death hand-off) and read docs/gotchas/ before debugging anything. Docs are updated in the same commit as the code they describe; okf drift reports when the two diverge.
Installed automatically during setup via uv:
Core: anthropic (Claude API client), pdfplumber + pypdf2 (PDF extraction), python-docx (Word docs), python-dotenv (env loading), requests (D&D 5e API).
RAG (document import): sentence-transformers (embeddings), chromadb (vector index for source lookups).
Licensed under CC BY-NC-SA 4.0 β free to share and adapt for non-commercial use. See LICENSE for details.
Built by Sean Stobo. Your story awaits. Run /gm to begin.


