Freytag Forge is a story-first detective RPG in your terminal/browser: you type what you do, the world reacts, and the narrative stays coherent across turns with deterministic state tracking under the hood.
Outside The Mansion
Broad stone steps rise to a carved oak door framed by weathered columns.
A torn ledger page lies half-caught in a crack between the stones near the bottom step.
Daria Stone is nearby, watching your next move.
>PICK UP THE LEDGER PAGE
Clue noted: Half-burned ledger page with initials that match the victim's diary.
>DARIA, WHAT DO YOU MAKE OF THIS?
Daria says: "The initials aren't random. Start with whoever had access to the archives tonight."
- Python 3.12+
- uv
make installOpenAI:
export OPENAI_API_KEY="your_api_key"
export OPENAI_MODEL="gpt-4o-mini" # optionalOllama:
ollama serve
ollama pull llama3.2
export OLLAMA_MODEL="llama3.2" # optional
export OLLAMA_BASE_URL="http://localhost:11434/api/chat" # optionalmake runThen open http://127.0.0.1:8000.
Core gameplay commands:
look,go <direction>,take <item>,talk <npc>,use <item> on <target>,inventory
Meta commands:
save <slot>,load <slot>,quit
Replay + transcript:
uv run python -m storygame --seed 123 --replay runs/commands.txt --transcript runs/session.txtRun tests:
make test- Planner-first turn routing: player input is interpreted through the LLM/freeform action planner first.
- Deterministic simulation boundary: world facts, inventory/location state, events, beat progression, and persistence remain deterministic.
- Coherence gate on narration: narrator output is evaluated by deterministic validators + multi-critic judge loop before final player-facing output.
- Story-agent opening pipeline: architect -> character -> plot, then narrator opening + room presentation cache.
- Canonical persistence: SQLite save snapshots plus
StoryState.json/STORY.mdartifact history with trace linkage.
For full architecture and design details, see docs/PRD.md.