An AI Narrator powered by coordinated Claude agents, so everyone gets to play.
SideQuest runs a council of specialized AI agents — narrator, combat, NPC, and world state — that collectively act as your Narrator. You type actions; the system routes them to the right agent and returns narration. Swap in a genre pack to change the entire tone, rules, and setting.
# Install
pip install .
# Play (launches the terminal UI)
sidequest
# Play with a specific genre pack
sidequest --genre low_fantasy
# Play via Discord
sidequest-discordRequires Python 3.11+ and a working Claude CLI installation.
graph TD
Player -->|action| Orchestrator
GenrePack -->|tone, rules, lore| PromptComposer
SOUL[SOUL.md] -->|guiding principles| PromptComposer
PromptComposer -->|system prompts| Orchestrator
Orchestrator -->|route by intent| IntentRouter
IntentRouter --> Narrator
IntentRouter --> Combat
IntentRouter --> NPC
Narrator -->|narrative text| SceneInterpreter
Combat -->|narrative text| SceneInterpreter
NPC -->|narrative text| SceneInterpreter
SceneInterpreter -->|stage cues| Renderer
Renderer --> TUI[Terminal UI]
Renderer --> ImageGen[Image Generation]
Renderer --> Audio[Audio / Music]
Renderer --> Voice[Voice / TTS]
Narrator -->|state patch| WorldState
Combat -->|state patch| WorldState
NPC -->|state patch| WorldState
WorldState -->|GameState| Orchestrator
The Orchestrator receives player input and uses the Intent Router to dispatch it to the right agent. Each agent runs as an interactive Claude session with a system prompt assembled by the Prompt Composer — which layers genre pack rules, SOUL.md principles, and world state into a structured, attention-aware prompt.
After each action, the World State agent produces a JSON patch to keep the shared GameState consistent. The Scene Interpreter extracts structured stage cues from narrative text, which the Renderer distributes to the UI, image generation, audio, and voice pipelines.
| Agent | Handles |
|---|---|
| Narrator | Exploration, description, story progression |
| Combat | Attacks, spells, tactical decisions |
| NPC | Dialogue, persuasion, social interaction |
| World State | State tracking, consistency enforcement |
| Intent Router | Classifies player input and selects the right agent |
| Music Director | Selects background music based on scene mood |
Genre packs are YAML directories that configure tone, rules, NPCs, character creation, audio, and visuals. The default pack is low_fantasy — a gritty, low-magic world where steel matters more than spells.
genre_packs/low_fantasy/
├── pack.yaml # Name, version, description
├── archetypes.yaml # Character archetypes and classes
├── char_creation.yaml # Scene-driven character creation
├── lore.yaml # World lore, history, factions
├── rules.yaml # Game mechanics and stat generation
├── prompts.yaml # Agent prompt extensions
├── theme.yaml # Color schemes and UI styling
├── inventory.yaml # Item tables and equipment
├── progression.yaml # Leveling and advancement
├── audio.yaml # Music and sound configuration
├── visual_style.yaml # Image generation style directives
└── voice_presets.yaml # TTS voice configuration per archetype
To create a new genre, add a directory under genre_packs/ following the same structure. See docs/genre-packs.md for the full format and a step-by-step creation guide.
SideQuest includes a Textual-based TUI with dedicated panels:
- Narrative panel — scrolling story output with Rich markup
- Party status — live HP bars and character stats
- Quest log — reactive quest tracking
- Combat mode — action bar and initiative/turn order tracker
- Image panel — inline scene art
- Character sheet — detailed overlay on
/partycommand - Audio status — now-playing indicator for background music
The layout adapts to terminal size, collapsing panels gracefully on smaller screens.
SideQuest can run as a Discord bot for multiplayer sessions. Players interact via Discord channels while the AI agents manage the shared game world.
sidequest-discordSee the Discord setup in sidequest/discord/ for configuration details.
sidequest/
├── agents/ # AI agents (narrator, combat, npc, world_state, intent_router, music_director)
├── audio/ # Audio pipeline (music generation, mixing, queue, loudness normalization)
├── comms/ # Inter-agent communication (channel, Discord voice)
├── discord/ # Discord bot, commands, session recovery, perception
├── game/ # Game logic — character, state, session, persistence, inventory, progression
├── genre/ # Genre pack loader, Pydantic models, lore system
├── media/ # Image generation (SDXL, Flux workers, caching, subject extraction)
├── ml/ # ML utilities (memory management)
├── renderer/ # Render pipeline — stage cues, display, beat filtering
├── slash_commands/ # In-game slash command router
├── ui/ # Textual app, widgets, CSS, responsive layout
├── voice/ # Voice/TTS pipeline (Piper, XTTS, effects, streaming)
├── main.py # CLI entry point
├── orchestrator.py # Agent coordination and game loop
├── prompt_composer.py # Three-tier prompt assembly with genre/SOUL integration
├── scene_interpreter.py # Narrative-to-stage-cue extraction
├── soul.py # SOUL.md parser for guiding principles
└── logging_config.py # Logging setup
| Doc | Audience | Description |
|---|---|---|
| How to Play | Players | Getting started, the world contract, commands, genre showcase |
| Features | Players / Prospective users | Full feature overview |
| Architecture | Developers | System design, component diagrams, data flow |
| Genre Packs | Creators / Developers | Genre pack format and creation guide |
| Genre Pack Audio | Creators | Audio configuration for genre packs |
python -m pytest # Run tests
python -m pytest -k "pattern" # Run specific tests
ruff check . # Lint
python -m build # Build packageMIT