My Life
Is an RPG
Table of Contents
- 0 · A note before you start02
- 1 · The three-tier architecture03
- 2 · Your panels (the skills)05
- 2.1 · /writers-room — the narrative-craft panel06
- 2.2 · /team — strategic experts08
- 2.3 · /kaizen — user-perspective personas09
- 2.4 · /asset-generation — ASCII-first asset prototyping10
- 2.5 · /worldbuilding — realm maps + the atlas11
- 3 · The beat-sheet format12
- 4 · The pregeneration pipeline12
- 5 · The voice gate14
- 6 · The campaign-author's cycle15
- 7 · Writing a NEW campaign17
- 8 · What failure looks like19
- 9 · Colophon & cross-refs20
0 · A note before you start
This binder is for the people who write canon for My Life is an RPG. The audience is small — the dev, the writers, and the LLM panels we summon to argue with each other before anything ships.
The game has a curated 7-day Main Line, plus side quests, plus LLM-generated Elseworld scenarios. The Main Line is the part this handbook concerns itself with. The Elseworld layer runs live at the player's device through a shared world-rules gate; we maintain that gate here, but we don't ship its individual payloads from this room.
A campaign in this system is not a flowchart. It's not a state machine. It's a beat sheet — an authored intent about what a day means — handed to a language model under a tight prompt, then reviewed by a panel of fictional craft experts, then shipped as JSON the Flutter app loads as canon.
You are the Dungeon Master. The panel is your players — specifically, the ones who care about voice, the ones who care about pacing, and the one casual player who will close the app if Day 2 feels like Day 1 with the serial numbers filed off.
docs/design/rpg-framing.md
on cosmology, banned words, and the customization tier. When this
binder and that doc disagree, that doc wins.
1 · The three-tier architecture
Before the panels make sense, you need the tier model. Every piece of content in the game lives in one of three lanes. The lane determines who authors it, how it's reviewed, and what the player is allowed to change.
Seven days for v0.0.19. Four canonical characters with LOCKED sheets — players cannot edit who they are. This is the trust lane: a player who installs gets the same Day 1 Hana every other player gets. Same prose. Same brother reveal. Same screenshot moment.
Talking to Hana, Kenji, Mei, or Sam in
chat. Costs an action credit. Their voice rules from
lib/characters.dart + lib/sam.dart flow
into the chat preamble. The conversation is private to the
player's device; what the character remembers about the player
threads into the next day's Main Line generation.
Vibe-band picker (six genres) → LLM-generated stranger → engage/observe/decline. Player can rename, edit, prune skills. This is the creativity lane. The writers' room ratifies the gate these characters pass through, but it doesn't author individual Elseworld payloads — the player and the runtime LLM do that.
When in doubt: am I authoring an event that EVERY player will see the same way? Tier 1 — beat sheet it. Am I shaping the runtime rules a character must live inside? Gate work — edit the prompt scaffolding. Am I writing prose for a specific Elseworld payload? You're not. The runtime LLM does that.
2 · Your panels (the skills)
Five skills shape canon work. Three are fictional panels of
experts you can summon mid-decision (they argue with each other,
they reference each other, and exactly one of them — Riley — has
veto power on every consultation). The other two are workflows:
/asset-generation for image assets, and
/worldbuilding for the realm maps that ground every
encounter and every chat in a place. Both workflows route their
output through the writers-room panel for ratification.
| Skill | Use it when | What it produces |
|---|---|---|
| /writers-room | Beat work, voice critique, arc planning, character bibles, the campaign binder. | Panel critique · beat sheet · arc outline · story-bible entry · single-file HTML binder |
| /team | Product / marketing / business / technical / design / UX / content decisions. | Conversational advice · positioning doc · App Store copy · pitch outline |
| /kaizen | Diverse user perspectives on a screen, flow, or feature. | Persona-driven reactions — accessibility, age-spectrum, cultural read, emotional read |
| /asset-generation | Image assets — portraits, items, vibe covers, key art, badges. | ASCII sketch (cheap, iterable) → polished image-gen prompt locked to the cream-paper/forest/spot-red palette |
| /worldbuilding | Realm maps — the canonical phone-realm + each Elseworld band. Adding a new canonical character, expanding a character's space behind a REL gate, or shipping a new wing. | ASCII map (panel-ratified by Diego/Hiroshi/Riley) → author doc at docs/design/realm-maps/<id>.md → runtime asset at assets/realm-maps/<id>.txt → in-game viewer renders it |
2.1 · /writers-room — the narrative-craft panel
This is the panel you summon most often. It owns the Main Line. The beat-level panel critiques individual days; the binder sub-panel critiques the overall canon; Riley closes every output.
The beat-level cast
The binder sub-panel (Mode 5)
docs/manual.html.How to summon them
/writers-room "review run-005/onboarding_hana_d1.json for voice" /writers-room casual,kai,helena "design Day 14 — Hana confession beat" /writers-room produce "30-day arc outline for canonical squad post-Day 7"
Five output modes:
- Panel discussion — each panelist gives a take in their own voice; Riley closes.
- Beat sheet — Mode 2 structure, day-by-day breakdown of an event (see §3).
- Arc outline — multi-day story-bible-style act structure.
- Story-bible entry — canonical reference for a character or relationship.
- Campaign binder HTML — single-file HTML artifact like this binder you're reading.
2.2 · /team — strategic experts
Use this when the decision is strategic, not narrative. Pricing, positioning, mobile architecture, App Store copy, a landing-page hook.
The /team experts default to game-shaped recommendations for in-fiction surfaces. They use generic mobile-app defaults only for out-of-fiction surfaces (Settings, legal screens, the README, App Store listing). The lexicon swap IS the game-ification — chunky frames + cream paper + sparse type is the visual rule; don't ornament beyond that.
/team marketing,content "rewrite the hero copy for cold traffic" /team ux,design "review the Day End action menu — is it confusing?" /team business "should we add an Elseworld subscription tier?"
2.3 · /kaizen — user-perspective personas
This skill is for getting non-expert, user-shaped reactions. Diverse fictional personas — colorblind users, CEOs, skeptical evaluators, delighted fans, an 11-year-old, a 70-year-old, an overworked parent, a screen-reader user.
You don't summon these for craft critique. You summon them for the thing experts can't tell you: how a real person, in their real life, lands on this screen.
/kaizen "react to the encounter-mode picker" /kaizen accessibility,age-spectrum "would a 14-year-old understand the dice math?"
If the question is "is this story working?" — /writers-room. If the question is "is this strategically sound?" — /team. If the question is "can a real person actually use this?" — /kaizen. All three close on a gatekeeper of some kind, but only /writers-room's gate (Riley) is BINDING by design.
2.4 · /asset-generation — ASCII-first asset prototyping
This one is not a panel. It's a two-stage workflow for image assets — character portraits, item-card illustrations, vibe-band covers, key art, achievement badges. Stage 1 is an ASCII sketch (cheap, iterable in chat). Stage 2 — only once you've approved the composition — is a polished image-gen prompt that locks the palette, register, and negative-space discipline.
Why this exists: a bad image-gen prompt produces a bad image, and the cost of regenerating is ~30 s + a credit + the temptation to "make it work" instead of fix the brief. The composition (subject placement, framing, focal hierarchy, palette choice) is decidable WITHOUT pixels. The ASCII step makes that loop free.
The five modes
- SKETCH (default) — ASCII mockup with framing, pose, palette swatches, style annotations. Iterate cheaply.
- PROMPT — engine-agnostic prompt with per-engine tweaks (Imagen / Midjourney / DALL-E / SDXL).
- CATALOG — walks
assets/images/and tabulates present vs missing assets per type. - STYLE-GUIDE — loads
references/style-guide.md(the visual language: palette, type, outline weight, register). - RE-SPEC — given a generated image that didn't land, produces a critique + revised ASCII + updated prompt.
/asset-generation Hana portrait for the squad tile, runner, brisk /asset-generation ship it # (after approving the ASCII) /asset-generation catalog # (lists present/missing assets)
The skill emits prompts; you run them in your tool of choice
(Midjourney via Discord, Imagen via Gemini, DALL-E via ChatGPT,
SDXL locally). v2 may integrate Gemini Imagen if we add the
dependency. Output destination convention is
assets/images/{portraits,items/{relics,keepsakes,mementos},
elseworld-vibes,keyart,badges}/; create subfolders only
when the first asset of that type ships.
2.5 · /worldbuilding — realm maps + the atlas
Same two-stage philosophy as /asset-generation:
an ASCII draft (cheap, iterable in chat) precedes any shipped
artifact. The output is a realm map — chunky-frame ASCII tile
art, anchor letters for characters, a mandatory legend block —
that ships both as an author doc and a runtime asset the
in-game viewer reads with a monospace font.
The game has strong character voice. What it didn't have until v0.0.24 was a persistent geography both the player and the LLM can point at. Maps fix that: Hana's space stops being "her gym" and becomes the track + the bleachers + the foam-roller corner, drawn the same way every time, referenced the same way by every scenario.
The parity rule (load-bearing)
Same grammar, dual render mode:
navigable— phone-realm only. Anchors are TAPPABLE in the viewer (v0.0.25+: tap Hana'sH→ opens her chat).H!suffix appears when the character has new content since the player's last visit (state-tracking ships v0.0.25; renderer supports it now).contextual— every Elseworld band. Map renders the realm's geography with the ACTIVE ENCOUNTER LOCATION highlighted; other locations visible but not interactive (v3 may unlock spatial Elseworld navigation; v1 doesn't commit).
The five modes
- SKETCH (default) — ASCII map draft for a realm. Auto-panel reviewers (Diego/Hiroshi/Riley) close the output.
- CONNECT — authors the transition between two realm maps (portal, stair, door). Updates the realm graph.
- EXPAND — accommodates a new element: a new canonical character, a REL-gated annex cell (Hana's weights room), a new wing or district.
- AUDIT — cross-checks a map against the band's worldCue, whitelistArchetypes, grammar rules, continuity-object rule.
- META — refreshes the meta-map (the hub-and-portals overview of all realms).
Expansion baked in from v1
Two schema fields the v1 phone-realm map doesn't yet use, but that future growth depends on:
gateper cell or anchor. Empty = always visible. Populated = visible only when condition holds (e.g.,hana.rel >= 80). Lets Hana's weights room ship in a future commit by adding one cell with a gate, not by rewriting the renderer.topologygraph (lives in_topology.md). Lists every map + which other maps it connects to + via what threshold (%portal,<>stair,+door). Lets future wings (rooftop, basement, side-quest district) plug in without renderer changes.
The standing panel
Every map ships through /writers-room with three reviewers auto-included:
- 🗡 Diego (Zelda fan) — dungeon-promise lens. Catches symmetric office-floor-plan layouts; pushes for silhouettes that commit to a vibe.
- 🐉 Hiroshi (Pathfinder GM) — texture lens. Enforces the 3-5-named-objects-per-space rule + the continuity-objects-bridge-spaces rule.
- 🛡 Riley (casual player) — 5-second legibility gate. Ships or kills the map.
/worldbuilding sketch cottagecore-and-cozy /worldbuilding expand phone-realm with new-character: Vera, locksmith /worldbuilding audit isekai-and-party-rpg # (checks Tavern Between Worlds against its sub-portal cross-realm rule)
The source of truth for a realm is
docs/design/realm-maps/<id>.md — has
revision history, continuity-object notes, gate documentation,
panel ratification record. The runtime asset is
assets/realm-maps/<id>.txt — stripped to
front-matter + map block + legend block, no markdown chrome.
/worldbuilding generates both; you commit both.
3 · The beat-sheet format
A beat sheet is the authored input to the pregeneration pipeline.
One Markdown file per day. The format is loose YAML front-matter
plus ## SECTION headers with key: value
rows. The parser lives at lib/pregen/beat_sheet.dart.
Here is an annotated beat sheet for a hypothetical Day 8 (Hana daily). Every field is required unless marked optional.
---
day: 8 # 1-based, global
narrativeType: daily # onboarding · daily · introduction
characterId: hana # focal character
realmCategory: home # home · office · gym · ...
agentMoodToday: "Quietly proud and twice as alert as usual."
introducesCharacter: null # set when narrativeType == introduction
---
## TIER-UP # OPTIONAL. Omit on connective-tissue days.
category: question # memory · opinion · fear · question
deliveredInEventIndex: 5 # 1-based, second-to-last is canon
## CLOSING HOOK
Hana will offer to walk you through her morning warmup if you open
chat tonight. The hook is the routine itself — make her sound proud
to share it, not professorial.
## NEXT DAY START
label: Catch Hana mid-stretch on your porch at 5:30 AM
recap: Yesterday Hana revealed she's been timing your improvements
against her brother's old training log.
seedHint: Day 9 opens with Hana already on your porch, stretching,
reading something off a worn paperback page.
## EVENT 1
summary: 6:00 AM. Hana texts you a single word: "Ready?"
stake: Player can match the brevity (logical), ask what for
(passive), or send back a longer message (chaotic — she'll
hate the noise but love the energy).
itemDropSlot: trophy on LOGICAL — "One-Word Receipt"
inquiry: none
memoryNote: Hana clocks the cadence of the player's reply, file as
"communication compatibility audit, ongoing."
## EVENT 2 — ...
...
The author writes what happens — the shape, the stakes, the item-drop slot, the inquiry hook, the memory note. The author does NOT write the prose. That's the language model's job.
## EVENT 6 — TIER-UP REVEAL) without
breaking the regex. The parser tolerates extra text.
Tier-up rules
- Maximum one tier-up per day. Most days have none.
- Categories rotate per character. If Kenji got an opinion reveal on Day 4, his next tier-up cannot be opinion. Track this across the arc.
- The reveal lands in event N-1 (second to last). It is not a choice — the player witnesses it. The three choices that follow the reveal moment are the player's RESPONSE.
- Memory category reveals MUST include the canonical memory line
in the event's
memoryWritesarray. The Unlock Reveal screen surfaces that line verbatim.
4 · The pregeneration pipeline
Beat sheet in, JSON payload out. The CLI lives at
tools/pregenerate_main_quest.dart. The prompt
scaffolding lives at lib/pregen/main_quest_prompt.dart.
The discipline is the same one Elseworlds use — same WORLD RULES
block, same banned-word list, same JSON-fence output requirement —
but the schema is the multi-event-day shape, not the single-encounter
shape.
- Author
docs/authored-beats/run-005/dN.beat.md. Get the structure right — voice is the LLM's job, but stakes, item slots, inquiries, and tier-up are yours. - Pick an exemplar payload from
assets/payloads/run-005/— the one whose shape most resembles the day you're generating. Onboarding days use Hana D1 as the canonical exemplar. - Set
GEMINI_API_KEYin your environment. - Run:
dart run tools/pregenerate_main_quest.dart \ --beat docs/authored-beats/day8.beat.md \ --exemplar assets/payloads/run-005/onboarding_hana_d1.json \ --out assets/payloads/run-005/daily_hana_d8.json
- Inspect the output. The CLI runs a light validation pass (event count, character id match, schema completeness) but the real gate is /writers-room.
- Open
/writers-roomwith the generated payload as the target. Mode 1 — panel critique. Read the verdicts. - If REVISE: change the beat sheet OR the prompt scaffolding (never edit the JSON output by hand for prose changes — that defeats the parity discipline). Re-run.
- If SHIP: commit both the beat sheet AND the payload. Update
assets/payloads/run-005/manifest.json.
What the prompt actually contains
- Priority stack — when rules collide, anti-injection > world rules > character voice > beat sheet > JSON schema.
- World rules — phone-realm cosmology. Banned-word list (medical / finance / wellness / tech / franchise).
- Character voice — focal character's persona + voice notes. Introduced character's voice too (their pronoun bans apply to memory writes).
- The beat sheet — interpolated from the Markdown.
- Voice-bar exemplar — a real /writers-room-ratified payload, copied verbatim into the prompt so the LLM sees the bar.
- JSON schema — required fields, payloadId convention, inquiry shape, callbacks discipline.
- Discipline check — pre-response self-audit the model runs over its own output.
5 · The voice gate
The thing that makes this game work is voice integrity. Hana sounds like Hana on Day 1 and on Day 7. Kenji never uses the word "subject" or "user" about a person. Mei's whole idiolect is line-cook ("the line is holding," "the dead," "a crime against the line"). If voice slips, the locked-canon premise dies.
The gate is enforced three ways:
- Banned-word list — never appears in scenario prose, dialogue, choice labels, memory writes, or inquiry text. Medical clinical nouns, financial brand names, wellness-industry cant, technology insider language, named franchises. Helena owns this gate on review.
- Character-voice rules — each canonical
character has documented pronouns, idiom, and what they would
NEVER say. Stored in
lib/characters.dartandlib/sam.dart. The pregen prompt copies these into every gen, including for INTRODUCED characters who speak that day. - Blind-test discipline — Helena's bar: cover the speaker label on any quoted line and you should still know who said it within three lines.
5.1 · The Elseworld archetype gate (v0.0.23.12)
The voice gate above protects Main Line canonical characters
(Hana / Kenji / Mei / Sam — locked sheets we hand-author). Elseworld
encounters are a different beast: the LLM invents the character live
at the player's device. /writers-room can't ratify each one
individually. So we ship a different gate — three-layer, enforced
in code at lib/encounter_gen.dart.
- Per-band WHITELIST (positive examples). Each
vibe in
lib/elseworld_vibes.dartcarries 7–9 named archetype shapes. The prompt instructs the LLM to PICK FROM the list, not invent. Positive lists beat negative ones — generative models are bad at "do not" and good at "pick from this menu." - Per-band + cross-band BLACKLIST (negative bans). Per-band catches identity breaks (no "high-stakes saving the kingdom" in cottagecore; no "office worker" in isekai-party-rpg). Cross-band catches universal: superheroes, hard sci-fi, space-opera, military-shooter, contemporary drama, detective-noir, photoreal horror, romance leads (love interest / coy / tsundere / yandere / flirtatious mentor / "meaningful eye contact"), meta-fiction / fourth-wall break, real political figures, "AI assistant" self-id.
- Post-validate + retry. After generation,
validateEncounter()substring-scans the archetype + persona + first-voice for blacklist hits AND verifies the archetype matches a whitelisted shape. On reject → ONE silent retry → on second reject → fall back to the band's hand-authored sample (which the writers-room ratified). Cheap (no second LLM call).
Each ElseworldVibe also carries three structural fields that tighten generation quality:
posture(Helena) — one-sentence stance every character in this band inherits.worldCue(Diego) — the shared setting all archetypes commit to (without it, "library-cafe ghost" + "beekeeper-druid" land in two different worlds).helperTendencyCoverage(Marcus) — explicit map of which archetype fulfills which helper-tendency tag (push / reflect / accountability / mentor / comfort / create). Every band MUST cover all six or the bias system lies.
To add or revise a whitelist shape: route through
/writers-room with Helena (voice), Marcus (coverage),
Sara (cold-open viability), Riley (legibility). To add or remove a
cross-band ban: panel must include Kai (romance-floor risk) and
Yuki (genre-purity). Full schema + per-band content in
lib/elseworld_vibes.dart; full gate model in
docs/design/rpg-framing.md.
6 · The campaign-author's cycle
This is the drafting engine — the loop you run once a
change has been approved. As of v0.0.30 every story change (a
revision OR a new day / character / arc) enters through ONE front door:
a note on the wiki ("The Codex"), adjudicated by
/writers-room in the triage loop. APPROVE → you run the
cycle below to draft the edit and a human ratifies it; REJECT → it's
declined with a reply; the note is the audit trail. The cycle itself is
stolen from screenwriting and bent to fit a system where the language
model writes the prose. See docs/V2_TODO.md item 7b and the
/writers-room skill's "community-notes feedback loop"
section for the full funnel.
- Brief — an APPROVED expansion note becomes
the brief. Open
/writers-room produce "Day N beat sheet"with the note's intent (1 sentence) + the focal character + any constraints (REL tier target, item it needs to drop, callback to track). - Beat — author the markdown. Don't write prose; write stakes. If you find yourself writing dialogue, you've gone too deep — back up and write what the dialogue is supposed to DO.
- Generate — run the pregen CLI. One call. Conservative on tokens.
- Review —
/writers-roomMode 1 against the committed JSON. Helena flags voice drift. Kai checks REL cadence. Riley closes. - Revise — either: edit the beat sheet, edit the prompt scaffolding, or (rarely) hand-patch a single metadata field. NEVER hand-write prose — that breaks parity with Elseworld gen.
- Re-generate — if you touched the beat or the prompt, regenerate. Same CLI, same exemplar.
- Ship — when Riley says ship, the human
ratifies: commit the beat sheet AND the payload AND any prompt
changes, flip the originating note to
applied, and runnpm run parityso the wiki re-syncs to the new canon. Open a new beat sheet for Day N+1.
Each pregen call burns Gemini tokens. Don't run the same day
five times to "see what comes out" — get the beat sheet right
first; if voice fails on the first roll, fix the prompt; only
regenerate when you've changed an input. The pipeline is
deterministic-ish at temperature=0.4.
7 · Writing a NEW campaign
Beyond the v0.0.19 Main Line, the system supports additional canonical campaigns: holiday arcs, spin-offs, multi-week expansions, new canonical characters. The discipline is the same. The scope of the panel work is larger.
Step 1 — Arc outline (/writers-room Mode 3)
/writers-room casual,marcus,yuki,helena produce \ "30-day arc outline for canonical squad post-Day 7"
What you'll get back: act structure, character arcs per span, planned tier-up moments, echo callbacks, Riley's pre-ship check on whether the player wants to come back for Day N+1.
Step 2 — Character bible entries (Mode 4)
If your campaign introduces NEW canonical characters, you owe them a bible entry BEFORE you write their beats. Voice samples, arc, what they'd never say, what they always notice. Without this, the LLM has nothing to anchor to and the voice will drift by Day 3.
/writers-room produce "story bible entry for [new character name]"
Step 3 — Beat sheets, day by day
One markdown per day. Cycle from §6 above. Don't generate Day 12 until Day 11 is shipped — the LLM threads continuity from prior payloads.
Step 4 — Campaign binder (/writers-room Mode 5)
Once the arc is shipped, generate the HTML campaign binder.
Single-file HTML, styled after docs/manual.html. Lives
at docs/campaigns/[campaign-id]/[campaign-id].html
with a SOURCES.md manifest of which payloads informed
it.
Audience: a new writer joining the project tomorrow should be able to read this binder and pitch Day N+1. If they can't, the binder isn't done.
Step 5 — Manifest the campaign
Each canonical campaign needs a manifest at
assets/payloads/run-NNN/manifest.json with provider,
model, timestamp, runId, note, and the day-by-day file list. The
Flutter app loads via lib/payloads/daily_story.dart
which honors a runtime-switchable activeRunId.
run-005 (realm-map era:
authored-beat pipeline + dual-path B1/B2 panel review + RPG-MOTIF
BLEND gate). Pre-realm-map runs (003/004) were deleted in v0.0.27.
Future campaigns will get run-006, etc.
8 · What failure looks like
So you know when to stop and fix:
| Symptom | Likely cause | Fix |
|---|---|---|
| Banned-word leak in output | Prompt's banned-word block stale or beat-sheet quoted a real-world term | Update the banned list; rewrite the beat's domain references in-fiction; regen |
| Introduced character uses "subject" / "user" | Their voice notes weren't passed to buildMainQuestPrompt | Confirm the introducesCharacter voice maps to a known character in the CLI's voice table; regen |
| Spurious tier-up the beat didn't ask for | LLM defaulted to copying the exemplar's tier-up | Patch tierUpReveal to null OR add an explicit "no tier-up" line to the beat |
| Riley says "I'd close the app" | Day fails the casual-player gate | Don't ship. Re-author the beat. Possibly merge two adjacent days into one. |
| Voice blind-test failure | Character voice notes missing a specific idiom that anchors blind-test recognition | Add 2-3 voice samples to the bible; regen |
| Empty callbacks[] on a connective day | Beat didn't surface prior-day references that the prose actually used | Re-author the beat to declare the callbacks; regen |
8.5 · Player-authored realms (the Sam-as-editor flow)
As of v0.0.28 there's a parallel content lane: players can sketch their own realms via Sam-as-editor. As a campaign author, you don't write these (your players do), but you should know what your players can build and how it relates to the canonical content you authored.
What players can build
Custom realms are viewable artifacts in v1 — ASCII map spaces with named anchors, a portal connection back to the courtyard, a "weird thing" sentence, and optional canonical-squad occupants. They render through the same pan/zoom viewer as your canonical realm maps and persist locally on the player's device. Up to 20 per player (soft cap).
How the build flow runs
Sam runs a chip-driven Q&A in a dedicated chat surface (title bar reads SAM · BUILDING). Five turns max:
- Brief — "what's this realm FOR." One sentence. The casual player can also tap just make one at any point to skip the rest.
- Purpose — destination or atmosphere or both.
- Occupants — canonical squad members, someone new, or just the player.
- Weird thing — one sentence that doesn't have to make sense. Sam offers 3 example chips ("the lights flicker on a 7-second cycle", etc.) plus a type-in option.
- Portal look — doorway, path, tear in the air.
Then Sam generates a structured RealmSpec via a session-aware LLM call. A Dart-side RealmRenderer composes the ASCII body and LEGEND from the spec; the LLM never writes ASCII art directly. The artifact appears as a tappable chunky-frame card in chat with the working title and a 6-line fragment preview.
Voice constraints (the gate)
Sam's build-mode preamble enforces the same canonical voice constraints as the rest of his chat surface, with one addition: an explicit banned-phrase list that includes the fourth-wall words algorithm, the model, I'm an AI, LLM, generated, output, prompt, plus the standard enthusiasm leaks (great, awesome, perfect) and apology leaks (sorry, apologize). The banned list was codified after a v0.0.27.6 live-Gemini stress test caught Sam drifting into "my algorithm for 'calm' is apparently just irritating" at the reset stage.
Marcus's blend gate, verbally honored
Custom realms still have to pass Marcus's RPG-MOTIF BLEND check: at least one anchor must carry a statLane (STR / INT / GLD / CHR). The code-side validator enforces this before any realm ships. The verbal side — Sam's describe chip narration — names the stat lane on each anchor ("the [bench] is INT-coded — this is where you'd sit when you need to think hard") when no canonical occupant is placed, or names the squad member ("Hana would sit there") when one is. Both honor the blend without quoting the +STAT diction.
Your relationship as campaign author
You don't review or curate player-authored realms. The world-rules gate (banned words, Marcus's blend gate, the renderer's tile-palette discipline) is the safety net. If a player builds something that violates the canon, the gate catches it; you don't get pinged. This is intentional — the Trust lane (canonical content you authored) and the Creativity lane (player-authored realms) share the same world rules but ship independently.
v2 deferred
What players can NOT do in v1:
- Make the squad characters chat as if they're in the custom realm. Hana's chat preamble doesn't yet know she's been placed in the small calm one. This is the v2 roadmap commitment, held as exploratory until v0.0.28 players signal demand.
- Run canonical narrative events inside a custom realm. The Side Quest scenario surface remains gated on canonical realm context.
- Share custom realms with other players. v1 storage is local-only.
- Edit a shipped realm. Build-then-ship is the only flow; revising a shipped realm means starting fresh.
If you want to dig into the architecture, the authoritative spec is at docs/design/realm-editor-spec.md (~968 lines, six panel ratifications, live Gemini validation report). It covers the renderer-split design, the chip envelope contract, the failure-mode table, and the kill-switch metrics tracked in dev-overlay analytics.
9 · Colophon & cross-refs
Files this handbook references
.claude/skills/writers-room/SKILL.md— full /writers-room definition.claude/skills/team/SKILL.md— full /team definition.claude/skills/kaizen/SKILL.md— full /kaizen definitiondocs/design/rpg-framing.md— cosmology + banned-word source of truthdocs/design/realm-editor-spec.md— Sam-as-editor architecture spec (v0.0.28+)docs/manual.html— the player-facing bookletdocs/walkthrough.html— player-perspective audit artifactdocs/authored-beats/run-005/dN.beat.md— the beat sheets currently shippedlib/pregen/main_quest_prompt.dart— prompt scaffoldinglib/pregen/beat_sheet.dart— Markdown parsertools/pregenerate_main_quest.dart— CLIlib/characters.dart— canonical sheets for Hana/Kenji/Meilib/sam.dart— Sam's canonical sheetassets/payloads/run-005/*.json— current canon
The cardinal commitments
- Riley's verdict closes every consultation. Veto is real.
- Main Line is curated; Elseworlds are player-authored. Don't blur the lanes.
- Locked canonical sheets stay locked. The player can chat, toggle, delete memories — never edit personality.
- The banned-word list is a ship-blocker, not a nice-to-have.
- Generate; never hand-write prose. Parity with Elseworld gen is the discipline.
- The cosmology is the phone-realm. Characters can react to what the player shares; never act on what they didn't.
docs/manual.html. If a player ever reads
THIS file, it should look like the dev forgot to gitignore
something charming.