This plan translates system_design_en.md into concrete development phases and tasks for engineers. It assumes a Python + LangChain implementation.
-
Repository & Packaging
- Initialize Python project structure as described in
system_design_en.md(autowerewolf/package +docs/). - Add
pyproject.tomlorrequirements.txtwith minimal dependencies:langchain-core,langchain-community,langchain-ollamapydantic,typer(for CLI),rich(optional for pretty logs)pytest(for tests)
- Configure basic tooling:
.gitignore, formatting (e.g.,black/ruffoptional), CI placeholder.
- Initialize Python project structure as described in
-
Baseline README & Docs Hook
- Update
README.mdwith a short project description and link to:docs/werewolf_rules_en.mddocs/system_design_en.mddocs/development_plan_en.md(this file).
- Update
Deliverable: Empty but compilable package with installable dependencies and passing pytest (no tests yet).
Goal: Implement and fully test the pure game logic before integrating LLMs.
-
Domain Models (
engine/state.py,engine/roles.py)- Implement enums and data models:
Role,Alignment,Phase,WinningTeam.Player,GameConfig,RuleVariants,GameState.Eventbase class + concrete event types (NightKill,SeerCheck,WitchSave,VoteCast,SheriffElection,HunterShot,VillageIdiotReveal, etc.).Actionbase class + concrete action types.
- Use
pydanticmodels for validation and serialization.
- Implement enums and data models:
-
Rules Engine (
engine/rules.py)- Implement functions for:
- Role assignment and validation (ensuring correct 12-player compositions for role set A/B).
- Night resolution:
- Input:
GameState+ list of nightActions. - Output: new
GameState+Events, applying rules in correct order.
- Input:
- Day resolution:
- Speech tracking (events only, no logic).
- Vote tallying including sheriff 1.5x votes and tie-breaking.
- Lynch resolution, last words eligibility, and role-triggered effects (Hunter, Village Idiot).
- Win condition checks (Side-Elimination by default, configurable to City-Elimination).
- Encode rule variants from
RuleVariants.
- Implement functions for:
-
Unit Tests (Rules Only)
- Create
tests/test_engine_rules.pywith coverage for:- Night kill + witch save + guard interactions, including
same_guard_same_save_killsbehavior. - Seer checks and their results storage in state.
- Sheriff election, badge pass/tear, and vote weights.
- Hunter shot logic and edge cases (poisoned, killed at night, etc.).
- Village Idiot lynch + reveal behavior.
- Win condition evaluation for all relevant end states.
- Night kill + witch save + guard interactions, including
- Create
Deliverable: Deterministic rules engine with high unit test coverage, no LLMs involved.
Goal: Provide a unified way to obtain LangChain ChatModel instances for different backends.
-
Config Models (
config/models.py)- Implement
ModelConfig,AgentModelConfig, and defaults. - Include validation (e.g.,
api_keyrequired whenbackend == "api").
- Implement
-
Backend Adapter (
agents/backend.py)- Implement
get_chat_model(config: ModelConfig) -> BaseChatModel:backend == "api": useChatOpenAI-style model with customizableapi_base,model_name,api_key.backend == "ollama": useChatOllamawith givenmodel_name.
- Add small integration tests with mocked environment variables or dummy keys to ensure correct instantiation.
- Implement
-
Configuration Loading
- Define a simple YAML/JSON format for
AgentModelConfig. - Implement loader utilities in
config/models.pyorio/persistence.py.
- Define a simple YAML/JSON format for
Deliverable: One function call to obtain appropriate LangChain models for any agent role, with config-driven backend selection.
Goal: Define a unified way to build and execute LLM-powered agents for players and moderator.
-
BasePlayerAgent (
agents/player_base.py)- Define an abstract class or protocol with methods:
decide_night_action(game_view) -> Actiondecide_day_speech(game_view) -> SpeechActiondecide_vote(game_view) -> VoteAction- Optional:
decide_sheriff_run(game_view),decide_badge_pass(game_view).
- Implement constructor taking:
BaseChatModel(from backend adapter).- Role metadata and prompt templates.
- LangChain memory object per agent (see section 5 below).
- Define an abstract class or protocol with methods:
-
Prompt and Output Schema Design
- Define Pydantic models for structured outputs:
SpeechOutput,VoteOutput,NightActionOutput(union of role-specific fields).
- Implement LangChain parsers or
with_structured_outputusage.
- Define Pydantic models for structured outputs:
-
ModeratorChain (
agents/moderator.py)- Implement a chain that receives
GameState+Events +audienceand returns narration. - Ensure prompts enforce no leakage of hidden information.
- Implement a chain that receives
-
Minimal Integration Test
- Implement a dummy
GameStateand use a mock or very small model (can be a fakeLLMimplementation) to ensure chains run end-to-end and return valid structured outputs.
- Implement a dummy
-
LangChain Memory Implementation (
agents/memory.py)- Create a new module
agents/memory.pyto centralize memory management. - Implement memory types for agents:
- Use
ConversationBufferMemoryfor short-term conversational context (recent speeches, votes). - Use
ConversationSummaryMemoryfor longer games to compress older history. - Implement
GameFactMemory(custom class) to store structured facts:- Player claims (e.g., "Player 3 claimed Seer on Day 1").
- Seer check results (private to Seer agent).
- Suspicious behaviors observed.
- Voting patterns and speech summaries.
- Use
- Integrate memory into chain construction:
- Modify
_build_night_chain(),_build_speech_chain(),_build_vote_chain()to include memory context. - Use
RunnableWithMessageHistoryor manual injection of memory into prompts.
- Modify
- Implement memory update hooks:
update_memory_after_speech(player_id, speech_content).update_memory_after_vote(player_id, vote_target).update_memory_after_night(player_id, night_events).
- Ensure memory is scoped per agent (no cross-agent memory leakage).
- Create a new module
Deliverable: Reusable agent base classes and schemas with integrated LangChain Memory, ready for concrete role-specific behavior.
Goal: Implement concrete LangChain agents for each role using the base abstractions.
-
Werewolf Agent (
agents/roles/werewolf.py)- Night: choose
kill_target_id(or special actions: self-explode/self-knife if enabled). - Day: speeches and votes informed by alignment and private knowledge.
- Werewolf Camp Coordination Mechanism (see section 10 below for details).
- Night: choose
-
Villager Agent (
agents/roles/villager.py)- No night action.
- Day: generate suspicion reasoning and votes based on public history.
-
Seer Agent (
agents/roles/seer.py)- Night: select check target, store check result in private memory.
- Day: decide whether to reveal information and how to speak/vote.
-
Witch Agent (
agents/roles/witch.py)- Night: consume info about attack target and remaining potions.
- Choose cure/poison actions under rules constraints.
-
Hunter Agent (
agents/roles/hunter.py)- Day: normal speeches and votes.
- On death: choose a target to shoot, respecting poison restrictions.
-
Guard Agent (
agents/roles/guard.py) (role set A)- Night: choose guard target with engine preventing illegal repeats.
-
Village Idiot Agent (
agents/roles/village_idiot.py) (role set B)- Day: speeches and votes as normal villager.
- When lynched: decide reveal behavior if not automatic by rules.
-
Role-Specific Prompt Tuning
- For each role, design:
- System prompt (role goal, constraints, alignment).
- Few-shot examples if needed (short, to control output schema).
- For each role, design:
-
Tests with Mock LLMs
- Use deterministic fake LLM responses to verify each role agent:
- Accepts a constrained
game_viewinput. - Produces valid structured outputs.
- Respects obvious constraints (e.g., no self-vote when disallowed).
- Accepts a constrained
- Use deterministic fake LLM responses to verify each role agent:
-
Werewolf Camp Internal Coordination Mechanism
- Implement werewolf-only communication during night phase:
- Option A: Shared Memory Approach
- Create
WerewolfCampMemoryclass that is shared among all werewolf agents. - Store werewolf-only facts: confirmed villager roles, coordination strategies, kill history.
- Each werewolf can read/write to this shared memory during night actions.
- Create
- Option B: Multi-Agent Discussion Chain
- Implement
WerewolfDiscussionChainthat simulates werewolf night discussion. - Input: game state visible to werewolves (all werewolf identities known to each other).
- Process: Each werewolf agent proposes a target with reasoning (1-2 rounds).
- Output: Consensus
kill_target_idagreed upon by the pack.
- Implement
- Implementation Details:
- Add
werewolf_coordination_mode: Literal["shared_memory", "discussion_chain", "none"]toRuleVariants. - In
GameOrchestrator, during night phase:- Gather all alive werewolf agents.
- If
discussion_chainmode: runWerewolfDiscussionChainto get consensus target. - If
shared_memorymode: each werewolf decides independently but with shared context. - If
none: first werewolf's decision is used (simple mode).
- Ensure coordination happens BEFORE other night actions (Seer, Witch, Guard).
- Add
- Werewolf Private View:
- Werewolves see each other's identities in their
game_view.private_info. - Include
fellow_werewolves: list[str]in werewolf's private information.
- Werewolves see each other's identities in their
- Option A: Shared Memory Approach
- Implement werewolf-only communication during night phase:
Deliverable: All role agents implemented and testable in isolation with mock or stub LLMs, including werewolf coordination mechanism.
Goal: Wire rules engine and agents together into a full game loop.
-
Orchestrator Core (
orchestrator/game_orchestrator.py)- Implement
GameOrchestratorwith methods:__init__(config: GameConfig, agent_models: AgentModelConfig).run_game() -> GameResult.
- Responsibilities:
- Initialize
GameStateand assign roles. - Construct all
PlayerAgentandModeratorChaininstances usingget_chat_model. - Initialize Memory for each agent (see section 6 below).
- Manage the main loop:
- Night: call role-appropriate
decide_night_action(); pass actions to engine; update state. - Day: sheriff election (Day 1), speeches, votes, lynch resolution.
- After each phase: call ModeratorChain to produce narration and record logs.
- Update agent memories after each phase with relevant events.
- Night: call role-appropriate
- Initialize
- Implement
-
Game View Construction
- Implement functions to derive per-player
game_viewfromGameState+history, ensuring:- Only public information + player's own private info is included.
- No leakage of hidden roles or night actions.
- For werewolves: include
fellow_werewolvesin private info.
- Implement functions to derive per-player
-
Error Handling and Fallbacks
- In orchestrator, wrap all agent calls with:
- Timeout handling.
- JSON/output validation (re-prompt once, then random legal choice on failure).
- In orchestrator, wrap all agent calls with:
-
Basic CLI Integration (
cli/main.py)- CLI options:
--configpath to game config file.--backend(api/ollama override).--model-nameoverride.--seedfor determinism.
- Commands:
run-game: run a single game and print summary.- Optional:
simulate Ngames.
- CLI options:
-
Integration Test (End-to-End, Mocked Models)
- Use deterministic fake LLM models returning simple but valid actions.
- Run full game loop until win condition.
- Assert no crashes and correct state transitions.
-
Memory Initialization and Management in Orchestrator
- In
_create_agents():- Create a
ConversationBufferMemoryorConversationSummaryMemoryinstance for each agent. - Create a
GameFactMemoryinstance for each agent to store structured facts. - For werewolf agents: create or reference shared
WerewolfCampMemory. - Pass memory objects to
create_player_agent().
- Create a
- Implement memory update cycle:
- After night phase: update each agent's memory with visible night results.
- After each speech: update all agents' memories with the speech content.
- After voting: update all agents' memories with voting results.
- Add
memory_type: Literal["buffer", "summary"]toGameConfigfor configurability.
- In
-
Werewolf Coordination Integration
- During night phase, before collecting individual night actions:
- If
werewolf_coordination_mode == "discussion_chain":- Instantiate
WerewolfDiscussionChainwith all alive werewolf agents. - Run discussion chain to determine consensus kill target.
- Use consensus target for all werewolf agents.
- Instantiate
- If
werewolf_coordination_mode == "shared_memory":- Ensure all werewolves share the same
WerewolfCampMemory. - Each werewolf decides independently but sees shared strategic context.
- Ensure all werewolves share the same
- If
- During night phase, before collecting individual night actions:
Deliverable: A runnable game loop that can execute a full Werewolf game with stub or simple models, with proper memory management and werewolf coordination.
Goal: Make games inspectable and debuggable.
-
Logging Utilities (
io/logging.py)- Implement structured logging for:
- Config used for each run.
- Per-turn
Events and important state changes. - Prompts and model responses (with PII/secret redaction where needed).
- Consider using
loggingmodule with JSON formatter orrichfor CLI display.
- Implement structured logging for:
-
Persistence Layer (
io/persistence.py)- Define
GameLogschema. - Implement
save_game_log(path, game_log)andload_game_log(path). - Support at least JSON storage; SQLite optional.
- Define
-
Replay/Analysis Hooks
- Provide utilities to:
- Load a game log and print a human-readable summary.
- Extract key statistics (e.g., win rate of wolves, potion usage, etc.).
- Provide utilities to:
Deliverable: All games produce persistent logs and can be replayed/analyzed offline.
Goal: Make the system practical for multi-game simulations.
-
Prompt Optimization
- Shorten prompts and outputs while keeping role behavior stable.
- Add configuration for verbosity levels (e.g.,
minimal_logsvsfull_narration).
-
Model Profiles
- Define preset
AgentModelConfigs for:fast_local: Ollama small model, low temperature.cloud_strong: API model with higher reasoning quality.
- Define preset
-
Batching Opportunities
- Where supported by LangChain models, batch requests (e.g., all day speeches or votes) to reduce latency.
Deliverable: Configurable performance profiles and reduced cost/latency per game.
These are optional but recommended for a more complete product.
-
Human Player Support
- Allow 1+ human players; treat humans as special agents prompting via CLI or UI.
-
Simple Web UI
- Add a lightweight web server (e.g., FastAPI) to visualize game progress.
-
Advanced Analytics
- Aggregate statistics across many games to evaluate strategies, role balance, and model behavior.
- Prioritize Phase 1–5 to get a fully automated, end-to-end playable system with stub or simple models.
- Keep rules engine pure and fully tested before relying on LLM logic.
- Ensure configuration and backend selection (API vs Ollama) remain data-driven and do not require code changes.
- Use incremental PRs aligned with phases to keep the codebase stable and reviewable.