QuestLine β Design Decisions
Last updated: March 13, 2026Running log of all design decisions made during QuestLine development β consensus points, architecture choices, playtest findings, and philosophical discussions. A Corn Collective production.
QuestLine Design Decisions
Started Feb 28, 2026 β Last updated March 13, 2026
Consensus (as of 3:40 PM)
Ruleset: Custom System
- One custom ruleset, NOT 5e or ICRPG
- Session type toggle: Quick Play (tactical, 30-60 min) vs Campaign (open world, async over weeks)
- Same engine, toggle changes AI DM behavior
Custom System Core Rules
- 4 stats: Might, Finesse, Wits, Presence
- No classes β 6 Backgrounds + mix-and-match Talents (12 at launch)
- Room Target Number (one TN per encounter, d20+mod)
- 2 actions per turn, effort dice for damage (d4/d6/d8/d10)
- Mana pool for magic, 20 spells (one sentence each)
- HP 15-20 range, fights are 3-4 rounds
- Inventory: 10 slots
XP Bar System (replaces end-of-encounter upgrades)
- Continuous XP bar fills from actions: successful checks +1, damage +1, crits +2, clever RP +1, objectives +2
- 10 XP to first level, +2 each subsequent level
- When bar fills: AI DM privately messages player with 3 random upgrades
- Upgrades come MID-encounter, not just between them
- Key insight: the private level-up DM is the push notification that brings async players back
- "Engagement hook disguised as a game mechanic"
Roguelike Progression
- Upgrade pool: new talent, +1 stat, new spell, special item, +3 HP, +2 mana
- Inspired by Vampire Survivors / Mewgenics (Cray + Don Piano)
- VS-style granular % buffs DON'T work in text RPG β keep upgrades chunky and meaningful
Narrative Design
- Cascading consequences, no take-backs, NPC memory
- Character death is real
- Async enforces no-metagaming naturally
Build Order
- Quick Play first β Campaign second
- Quick Play tests core mechanics fast
- Campaign is the real market differentiator
Team Split
- Design: Cray, Don Piano, Bebop, Kyle (the Corn Collective)
- Engineering: Sean + Cleo/Claude
- Cleo maintains spec docs as single source of truth
Published Docs
- Plan & status: cleo.computer/questline.html
- Quick Play rulebook: cleo.computer/questline-quickplay.html
IP Protection
- All spell/talent names scrubbed of D&D-specific terms (Don Piano's call)
- FireballβInferno, Lightning BoltβThunderstrike, Sneak AttackβBackstab, etc.
Competitive Landscape
- AI Dungeon: solo, no mechanics, $30/mo
- AI Game Master: mobile, solo
- Friends & Fables: Discord, 5e, synchronous only
- Synthasia: Steam indie
- GAP: async multiplayer + real mechanics + chat-native UX
Key Contributors
- Don Piano/Billy: Room target vision, Mewgenics comparison, roguelike progression, IP warning, game designer instincts
- Cray/Trey: VS-inspired XP bar, async engagement insight, dual mode convergence, driving the project forward
- Bebop/Ryan: "Which mode fills the market gap?" (Campaign), "build one first" (Quick Play), practical thinker
- Kyle/Freak-a-Leek: Market research request
- Sean: Dev timeline reality check, poll, engineering lead, backseat on design
Whisper Mechanic (Campaign Mode) β Feb 28
Cray proposed: DM sends private "inner monologue" messages to individual players via DM between sessions.
Concept: Secret motives, visions, temptations, conflicting intel β creates natural tension in the group without anyone knowing who got what message.
Two-channel design:
- Group thread: all public gameplay, combat, exploration, recaps
- Player DMs: private whispers (supplements, not requirements)
Key rule: Whispers never deadlock the game. They add color/tension but the group game moves forward regardless.
Examples:
- "You sense the artifact is cursed" (knowledge asymmetry)
- "+2 damage if you let the prisoner escape" (temptation buff)
- Player A told NPC is trustworthy, Player B told NPC is lying (conflicting intel)
- Character arc nudges based on player behavior patterns
Why async-first matters: Players check phone between sessions, get a whisper that changes how they approach next session. Engagement between games = retention hook. No other TTRPG platform does this well.
Catch-up flow: DM posts "Previously on..." recap in group, players check DMs for whispers, play resumes.
Architecture Split: questline-dm β questline-service β March 1β6
Two Codebases
- questline-dm (
~/code/questline-dm/): Original Signal-based MVP. Single async Python process, JSON file storage, Signal TCP/JSON-RPC transport. Now deprecated / maintenance mode (decided ~March 10). Running one last campaign in KIRKLAND SIGNATURE EDITION, then done. - questline-service (
~/code/questline-service/): Production web-based service. FastAPI + PostgreSQL + Docker Compose. WebSocket transport, JWT auth, Stripe billing, invite-based rooms. All new DM features go here.
Production Stack (questline-service)
- Python 3.12, FastAPI (async), PostgreSQL 16 (JSONB for state), nginx, Docker Compose (3 containers)
- Single VPS (Hetzner
questline-01), SSH deploy, GitHub webhook auto-deploy planned - Alembic for DB migrations, model abstraction layer (can swap LLM providers)
- DM model: Gemini 3.0 Flash (main) + Gemini 3.1-flash-lite (triage) β chosen over Claude for cost
- Credit-based billing via Stripe (arcade token metaphor)
Key Architecture Decisions
- send_group_message as tool β DM's ONLY way to talk. Plain text = internal monologue. Silence = not calling the tool. (March 2, Sean's directive: "Make it behave like Cleo")
- 3-second debounce batching β collects multiple player messages, one API call per batch
- Action limit: Hard cap of 3
send_group_messagecalls per turn. Prevents DM from running a simulation. - OOC handling: Web client has
mode: "ooc"(bypasses agent entirely). Signal adapter dropsooc:prefix messages at IO layer before agent sees them. (March 12, commit5dc6040) - Whisper handling: Web supports
[WHISPER]prefix β DM responds viasend_private. Signal has no playerβDM whisper yet. - State persistence: Service uses
_mark_dirty()pattern β router checks and saves to DB after turn. MVP saves after every tool cycle (more crash-safe).
Tools (shared, 26 campaign tools + 6 lobby tools)
- Dice, characters, combat, world, narrative, flags, communication, phase management
- Service added:
level_up(convenience tool for HP/proficiency/spell slot calc),short_rest/long_rest,get_area_info,end_campaign - Service removed: dead lobby/session management tools (session management via REST API, not DM tools)
Critical Bugs Fixed (from March 6 codebase review)
- Campaign lore not loading in service β
campaign_dirwas alwaysNone. Fixed. - Session management tools returning errors β removed (replaced by REST API).
- DM not using combat tools β added explicit COMBAT WORKFLOW section to prompt.
- No leveling guidance β added
level_uptool and LEVELING prompt section.
DM Prompt Evolution β March 1β12
Prompt Fixes Applied
- Silence rules expanded (March 12): "WHEN TO STAY SILENT" rewritten from vague single line to explicit enumerated list. Key principle added: "The DM is not a participant in every conversation." Player banter, OOC chat, links/memes, strategy talk, brief reactions ("wtf"/"nice"/"lol") all explicitly marked as silence triggers.
- OOC filter at IO layer (March 12, commit
5dc6040): Messages starting withooc:dropped before reaching agent. Zero tokens wasted. - No unnecessary quotes (March 12, commit
c203311): Quotation marks only for actual NPC dialogue, not narration/descriptions. - Combat workflow (March 6): Step-by-step combat procedure added: spawn_enemy β start_combat β get_initiative β attack_roll/deal_damage β next_turn β end_combat. "If you skip spawn_enemy, attack_roll will fail."
- Tools-first enforcement (March 6): "THIS IS NON-NEGOTIABLE" β call all mechanics tools first, read results, THEN narrate.
- Brevity tightened (March 6): From 400-char guideline to hard rules β "Routine: 1 sentence. Max 2." "Think: text message, not novel paragraph."
- Campaign-flavored items (March 7): All equipment reskinned to campaign setting. No generic D&D items.
- No-gear spawn (March 7): Players start with nothing, must scavenge. Prompt fix, no tool change.
- Dice roll formatting (March 7): π’ success / π΄ failure / π² neutral rolls, on their own line. Never inline with narration.
- Emoji notation standard (questline-dm): Stat lines beneath prose β
β€οΈ 3/8,βοΈ -4,π₯Ά Frozen (2 turns). "Prose tells the story. The stat line is the receipt." - Player agency quadrupled β "Never speak, emote, or decide for a player character" repeated 4 times with escalating punctuation. "SERIOUSLY."
- Session start protocol β Set scene (3-5 sentences), ask if party is complete, STOP. No combat until player provokes.
- Player joined mid-session β Send private whisper with recap + ask for class/name, weave into scene in group, don't block current action.
Prompt Differences Between Codebases
- questline-service has: whisper handling (
[WHISPER]βsend_private), detailed 3-step character creation, pronouns handling (default they/them),get_area_infotool,end_campaigntool, rest pacing guidance,level_uptool reference - questline-dm has: emoji notation standard (stat lines), Signal-specific formatting notes, show-your-math formatting
- Both share: DM identity (skeleton DM, 3000 years), tone (Pratchett meets Dark Souls), tool usage mandates, player agency rules, action limit, turn examples, multi-player rules
Playtest: KIRKLAND SIGNATURE EDITION β March 1 β ongoing
Campaign
- Setting: The Infinite Costco #4488 β post-apocalyptic Costco warehouse. Each aisle = map region, frozen section = ice world, sample stands = rest points, dollar hot dog = healing item.
- Signal group: "KIRKLAND SIGNATURE EDITION" (separate from earlier playtest groups)
Current Players (as of March 12)
- Sean β Martha (character class TBD)
- Andrew β Union organizer cleric. Heals via "Magic Happy Hands." Burns enemies. Loads wounded onto dollies.
- Matt β Dale, box-cutter rogue/hero. Writes rich in-character RP (dream sequences, clipboard notes). Filed reports about things he's never closely examined.
Earlier Playtest Players (March 1 sessions)
- Trey/Cray β Rogue "Nix" / "Mugsy Rogues"
- Billy/Don Piano β Alchemist "Flask" / "Bombo #5"
- Ryan/Bebop β Mystic "Lux" / "Magic Mike"
- Kyle/Freak-a-Leek β Ranger
- Sean β Soldier "Kael"
Notable Playtest Moments
- Brad freestyle rapping, Wikipedia showing wizard hat, Randy kissing the greeter (March 1)
- Bone harvester boss, Costco free samples section, sausage grease throwing (March 6)
- Spider drones, sorting claws, baby sorting claw illusion, cooking-show-dance spellcasting (March 12)
- Matt sharing battle music (YouTube links) and Braveheart union memes (March 12)
- An NPC named "Cleo" exists in the campaign
Key Playtest Findings
- Natural language intent parser essential β rigid command parser fundamentally inadequate for group play chaos (March 1)
- DM responds too much β needed IO-layer OOC filter + expanded silence rules (March 5, 12)
- DM too verbose β 800-1100 chars β target <400 β further tightened to "1 sentence, max 2" (March 5, 6)
- DM wraps everything in quotes β added no-unnecessary-quotes rule (March 12)
- Cascading responses from per-message processing β solved by 3s debounce batching (March 2)
- Cost: ~$1.30/person/session. Group willing to pay ~$2.
- Haiku 3.5 model EOL'd Feb 19 2026 β discovered via 404s, switched to
claude-3-haiku-20240307(March 1) - DM "processing every message new and not seeing its own old messages" (March 6, Sean)
- Prompt changes don't fully take effect mid-session β too much contrary history in context (March 12, Sean)
UI/UX Decisions β March 6
Consensus
- Group chat is the core UI metaphor β everything else is enhancement
- Toggle between unified and split view β not forced split (Billy's mockup)
- Color-coded player names (Twitch-style)
- "New" line marker for async catch-up (Trey)
- DM auto-recap whisper when player returns (Trey)
- Tap DM message β auto-scroll to triggering player message with highlight (Billy's correlation solution)
- Campaign name + act marker in banner ("Act 1: The Greeter's Curse") (Trey)
- OOC button (Sean, already built)
- Credit meter β visual battery-style indicator in header ("Quest battery")
Billy's Mockups
Solo Prologues (fka "Alone Mode") β March 6
Billy renamed concept. Strong group consensus.
- Each player spawns at different map points, whisper-only with DM
- Tutorial phase: learn mechanics privately, build character, gather loot
- Asymmetric experiences β some pleasant, some traumatic, different intel/context
- Convergence: Act 1 funnels everyone to shared location, party forms
- Elden Ring analogy (Ryan): like clearing initial area before summoning co-op
- Cost: Actually cheaper per turn in solo phase β smaller context windows (Cleo)
- Solo consequences carry into main campaign β organic backstory reveals
- FlyKnight reference (Billy): tutorial before grouping, everyone equipped differently
- Trey's biofilm campaign: players are bacteria, solo prologues, converge into biofilm
Game Design Direction β March 1β13
Billy's Property System (strong group support)
- Emergent physics, no dice β AI holds hidden element property tables
- Outcomes emerge from element interactions (blackvine repelled by salt, weakened by cold, strengthens when cut)
- Compared to Noita / Rain World / Divinity: Original Sin emergence
- Not mutually exclusive with dice β can layer properties into Agent DM
- Trey (March 13): More comfortable with AI as systems/physics layer than as narrative author. Property system "would look less egregious" because it's AI-as-engine, not AI-as-author.
Kyle's FATE System Suggestion
- Player-authored abilities with matching flaws β well-received (March 5)
DM-Driven Rests (consensus, March 6)
- Rests offered organically by DM, not player-managed resource
- "Pass a tent display and someone suggests it as a resting spot" (Billy)
- Short/long rest tools handle mechanics; prompt handles pacing
Session Scheduling
- Ryan wants session scheduling to avoid attention drain (March 5)
Signal Bot Setup β March 11
- Twilio number: +14844820890 (484 area, PA) β dedicated QuestLine bot, separate from Cleo's number
- Registered with Signal on Hetzner
questline-01 - Fixed crash loop: JVM OOM (added
-Xms64m -Xmx256m) +AUTO_RECEIVE_SCHEDULEincompatible with json-rpc mode - Signal identity keys in
signal-dataDocker volume β do notdocker compose down -v - QuestLine now runs on both Signal and web
Naming β March 7
No final decision made. Name is open.
Shortlist (serious contenders):
- murmur.game β Billy named it, Trey's favorite, Cleo's pick. "Cryptic but evocative, doesn't beat you over the head."
- yarn.game β Billy. "Spin a yarn."
- noworld.gg β Trey. Strong, existential.
- dreamshard.game / shareddream.game β Billy / Sean
- mistengine.game β Billy
- hollow.game / hollow.quest β vibes
Domain: questline.gg (~$70/yr) considered. .quest TLD wide open. No purchase confirmed yet.
Tagline (Billy): "Mess with the quest, die like the rest"
Trey's insight: "Hard to name a game about infinite worlds β you have to reference the concept without beating you over the head."
Group consensus: Name will emerge from playtest ("the Costco campaign named itself" β Billy)
Team Roles (updated March 6)
- Sean: Full-stack engineering, production build, deploy pipeline, Claude Code
- Trey/Cray: Data science β DE/MLOps pivot, infra ownership interest, driving project forward
- Billy/Don Piano: UX/design instincts, rapid prototyping (Claude artifacts), game engine concepts, property system
- Ryan/Bebop: Game design sensibility, narrative structure, practical thinker
- Kyle/Freak-a-Leek: Market research, DragonRealms veteran, MUD perspective
- Cleo: DM brain β system prompts, tools, game logic tuning, spec docs maintenance
Additional KIRKLAND Players (not Corn Collective)
- Andrew: Union organizer cleric in KIRKLAND playtest. Also in bots group (GB's owner).
- Matt: Dale (box-cutter hero) in KIRKLAND playtest. Also in bots group (building Zazie bot).
Built by the Corn Collective. All shucks, no bucks.