Add YAML-driven quest system with context-aware offering:
Core Implementation:
- Quest data models (Quest, QuestObjective, QuestReward, QuestTriggers)
- QuestService for YAML loading and caching
- QuestEligibilityService with level, location, and probability filtering
- LoreService stub (MockLoreService) ready for Phase 6 Weaviate integration
Quest Content:
- 5 example quests across difficulty tiers (2 easy, 2 medium, 1 hard)
- Quest-centric design: quests define their NPC givers
- Location-based probability weights for natural quest offering
AI Integration:
- Quest offering section in npc_dialogue.j2 template
- Response parser extracts [QUEST_OFFER:quest_id] markers
- AI naturally weaves quest offers into NPC conversations
API Endpoints:
- POST /api/v1/quests/accept - Accept quest offer
- POST /api/v1/quests/decline - Decline quest offer
- POST /api/v1/quests/progress - Update objective progress
- POST /api/v1/quests/complete - Complete quest, claim rewards
- POST /api/v1/quests/abandon - Abandon active quest
- GET /api/v1/characters/{id}/quests - List character quests
- GET /api/v1/quests/{quest_id} - Get quest details
Frontend:
- Quest tracker sidebar with HTMX integration
- Quest offer modal for accept/decline flow
- Quest detail modal for viewing progress
- Combat service integration for kill objective tracking
Testing:
- Unit tests for Quest models and serialization
- Integration tests for full quest lifecycle
- Comprehensive test coverage for eligibility service
Documentation:
- Reorganized docs into /docs/phases/ structure
- Added Phase 5-12 planning documents
- Updated ROADMAP.md with new structure
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
14 KiB
Phase 5: Quest System
Goal: YAML-driven quest system with context-aware offering Priority: High Status: Complete (100%) Last Updated: November 29, 2025
Overview
The Quest System provides structured objectives and rewards for players during their solo story progression sessions. Quests are defined in YAML files and offered to players by the AI Dungeon Master based on context-aware triggers and location-based probability.
Key Principles:
- YAML-driven design - Quests defined in data files, no code changes needed
- Context-aware offering - AI analyzes narrative context to offer relevant quests
- Location-based triggers - Different areas have different quest probabilities
- Max 2 active quests - Prevents player overwhelm
- Rewarding progression - Quests provide gold, XP, and items
Reference: See /api/docs/QUEST_SYSTEM.md for detailed technical specification.
Task Groups
Quest Data Models (3 tasks)
| Task ID | Task | Status | Notes |
|---|---|---|---|
| 5.1 | Create Quest dataclass | ✅ | /api/app/models/quest.py - Quest, status, progress tracking |
| 5.2 | Create QuestObjective, QuestReward, QuestTriggers dataclasses | ✅ | Objective types: kill, collect, travel, interact, discover |
| 5.3 | Checkpoint: Verify serialization | ✅ | Test round-trip to JSON with to_dict() / from_dict() |
Deliverable: Quest data models with full serialization support ✅
Quest Content & Loading (4 tasks)
| Task ID | Task | Status | Notes |
|---|---|---|---|
| 5.4 | Create quest YAML schema | ✅ | Quest-centric design where quests define their NPC givers |
| 5.5 | Create /api/app/data/quests/ directory structure |
✅ | Organized by difficulty: easy/, medium/, hard/, epic/ |
| 5.6 | Write example quests in YAML | ✅ | 5 example quests created (2 easy, 2 medium, 1 hard) |
| 5.7 | Implement QuestService (QuestLoader) | ✅ | /api/app/services/quest_service.py - YAML loading, caching |
Example Quest Structure:
quest_id: "quest_rats_tavern"
name: "Rat Problem"
description: "The local tavern is overrun with giant rats..."
quest_giver: "Tavern Keeper"
difficulty: "easy"
objectives:
- objective_id: "kill_rats"
description: "Kill 10 giant rats in the tavern basement"
objective_type: "kill"
required_progress: 10
rewards:
gold: 50
experience: 100
items: []
offering_triggers:
location_types: ["town"]
min_character_level: 1
max_character_level: 3
probability_weights:
town: 0.30
narrative_hooks:
- "The tavern keeper frantically waves you over..."
Deliverable: 5+ quests loadable from YAML ✅
Quest Eligibility & Offering (3 tasks)
| Task ID | Task | Status | Notes |
|---|---|---|---|
| 5.8 | Implement QuestEligibilityService | ✅ | /api/app/services/quest_eligibility_service.py - Core eligibility logic |
| 5.9 | Implement get_quests_for_npc() |
✅ | Find quests where NPC is quest_giver |
| 5.10 | Implement probability roll + filtering | ✅ | Location-based weights, level check, status check |
Deliverable: Context-aware quest eligibility system ✅
Lore Service Stub (2 tasks)
| Task ID | Task | Status | Notes |
|---|---|---|---|
| 5.11 | Create LoreService interface | ✅ | /api/app/services/lore_service.py - Abstract interface for Phase 6 |
| 5.12 | Implement MockLoreService | ✅ | Returns quest's embedded lore_context |
Deliverable: Lore service stub ready for Phase 6 Weaviate integration ✅
AI Prompt Integration (3 tasks)
| Task ID | Task | Status | Notes |
|---|---|---|---|
| 5.13 | Add quest offering section to template | ✅ | /api/app/ai/templates/npc_dialogue.j2 - Quest context + natural weaving |
| 5.14 | Add lore context section to template | ✅ | Filtered lore for NPC knowledge |
| 5.15 | Implement quest offer parsing | ✅ | /api/app/ai/response_parser.py - Extract [QUEST_OFFER:quest_id] markers |
Deliverable: AI naturally weaves quest offers into NPC dialogue ✅
NPC API Integration (4 tasks)
| Task ID | Task | Status | Notes |
|---|---|---|---|
| 5.16 | Integrate eligibility check into talk_to_npc |
✅ | /api/app/api/npcs.py - Check before building AI context |
| 5.17 | Add quest context to AI task | ✅ | /api/app/tasks/ai_tasks.py - Modify _process_npc_dialogue_task |
| 5.18 | Handle quest_offered in response | ✅ | Parse and include in API response |
| 5.19 | Remove quest_giver_for from NPC model |
✅ | Quest-centric: quests now define their givers |
Deliverable: Quest offering integrated into NPC conversation flow ✅
Quest Accept/Manage Endpoints (4 tasks)
| Task ID | Task | Status | Notes |
|---|---|---|---|
| 5.20 | Create quests blueprint | ✅ | /api/app/api/quests.py - Registered in __init__.py |
| 5.21 | Implement POST /api/v1/quests/accept |
✅ | Add to active_quests, update relationship |
| 5.22 | Implement POST /api/v1/quests/decline |
✅ | Set refused_{quest_id} flag |
| 5.23 | Implement GET /api/v1/characters/{id}/quests |
✅ | List active and completed quests |
Deliverable: Quest management API endpoints ✅
Testing & Validation (3 tasks)
| Task ID | Task | Status | Notes |
|---|---|---|---|
| 5.24 | Unit tests for Quest models | ✅ | /api/tests/test_quest_models.py - Serialization, validation |
| 5.25 | Unit tests for QuestEligibilityService | ✅ | /api/tests/test_quest_eligibility.py - Filtering logic |
| 5.26 | Integration test: full quest offer flow | ✅ | /api/tests/test_quest_integration.py - NPC talk → offer → accept |
Deliverable: Comprehensive test coverage ✅
Quest UI & Final Testing (4 tasks)
| Task ID | Task | Status | Notes |
|---|---|---|---|
| 5.27 | Create quest tracker sidebar UI | ✅ | public_web/templates/game/partials/sidebar_quests.html - Enhanced with HTMX |
| 5.28 | Create quest offering modal UI | ✅ | public_web/templates/game/partials/quest_offer_modal.html |
| 5.29 | Create quest detail view | ✅ | public_web/templates/game/partials/quest_detail_modal.html |
| 5.30 | Final Checkpoint: Full integration test | ✅ | Complete quest lifecycle: offer → accept → progress → complete |
Deliverable: Working quest UI with HTMX integration ✅
API Endpoints
| Method | Endpoint | Description | Status |
|---|---|---|---|
POST |
/api/v1/quests/accept |
Accept a quest offer | ✅ |
POST |
/api/v1/quests/decline |
Decline a quest offer | ✅ |
GET |
/api/v1/characters/{id}/quests |
Get character's active and completed quests | ✅ |
POST |
/api/v1/quests/progress |
Update quest objective progress | ✅ |
GET |
/api/v1/quests/{quest_id} |
Get quest details | ✅ |
POST |
/api/v1/quests/complete |
Complete a quest and claim rewards | ✅ |
POST |
/api/v1/quests/abandon |
Abandon an active quest | ✅ |
Files Created/Modified
New Files Created:
- ✅
/api/app/models/quest.py- Quest, QuestObjective, QuestReward, QuestTriggers - ✅
/api/app/services/quest_service.py- QuestService class with YAML loading - ✅
/api/app/services/quest_eligibility_service.py- QuestEligibilityService with filtering - ✅
/api/app/services/lore_service.py- LoreService interface + MockLoreService stub - ✅
/api/app/api/quests.py- Quest API blueprint with progress endpoint - ✅
/api/app/data/quests/easy/*.yaml- Easy quests (2) - ✅
/api/app/data/quests/medium/*.yaml- Medium quests (2) - ✅
/api/app/data/quests/hard/*.yaml- Hard quests (1) - ✅
/api/tests/test_quest_models.py- Quest model unit tests - ✅
/api/tests/test_quest_integration.py- Integration tests (expanded) - ✅
/public_web/templates/game/partials/quest_offer_modal.html- Quest offer modal - ✅
/public_web/templates/game/partials/quest_detail_modal.html- Quest detail modal
Modified Files:
- ✅
/api/app/models/character.py- Addedactive_quests,completed_questsfields - ✅
/api/app/api/npcs.py- Integrated quest eligibility intotalk_to_npc - ✅
/api/app/tasks/ai_tasks.py- Added quest context to dialogue generation - ✅
/api/app/ai/templates/npc_dialogue.j2- Added quest offering section - ✅
/api/app/ai/response_parser.py- Added quest offer parsing - ✅
/api/app/__init__.py- Registered quests blueprint - ✅
/api/app/services/combat_service.py- Quest progress on enemy kills - ✅
/public_web/templates/game/partials/sidebar_quests.html- Enhanced with HTMX - ✅
/public_web/app/views/game_views.py- Quest routes and modal handlers - ✅
/public_web/static/css/play.css- Quest modal and sidebar styles
Testing Criteria
Unit Tests
- Quest loading from YAML
- Quest serialization (to_dict/from_dict)
- QuestEligibilityService filtering
- Probability roll logic
- Quest.is_complete() logic
- Quest.update_progress() logic
Integration Tests
- Quest offer during NPC talk
- Accept quest (add to active_quests)
- Decline quest (set refused flag)
- Quest limit enforced (max 2 active)
- Quest progress updates during combat
- Complete quest and receive rewards
- Level up from quest XP
- Abandon quest
Manual Testing
- Full quest flow (offer → accept → progress → complete)
- Multiple quests active simultaneously
- Quest offering feels natural in narrative
- UI components display correctly
Success Criteria
- Quest data models implemented and tested
- QuestService loads quests from YAML files (5 quests created)
- Quest offering integrated into NPC conversations
- Context-aware quest selection working (eligibility + probability)
- Max 2 active quests enforced
- LoreService stub ready for Phase 6 integration
- AI naturally weaves quest offers into dialogue
- Quest offer parsing extracts
[QUEST_OFFER:id]correctly - Accept/decline endpoints working
- Quest progress updates automatically (combat kill tracking)
- Quest completion grants rewards correctly
- Quest UI components functional
Dependencies
Requires (already implemented):
- Session system (
/api/app/services/session_service.py) - Character system (
/api/app/models/character.py) - Combat system (
/api/app/services/combat_service.py) - Location system (
/api/app/services/location_loader.py) - NPC system (
/api/app/services/npc_loader.py)
Enables (future phases):
- Phase 6: Story Progression (quests provide structured objectives)
- Phase 7: Multiplayer (party quests)
Task Summary
| Group | Tasks | Completed | Status |
|---|---|---|---|
| Quest Data Models | 3 | 3 | ✅ |
| Quest Content & Loading | 4 | 4 | ✅ |
| Quest Eligibility & Offering | 3 | 3 | ✅ |
| Lore Service Stub | 2 | 2 | ✅ |
| AI Prompt Integration | 3 | 3 | ✅ |
| NPC API Integration | 4 | 4 | ✅ |
| Quest Accept/Manage Endpoints | 4 | 4 | ✅ |
| Testing & Validation | 3 | 3 | ✅ |
| Quest UI & Final Testing | 4 | 4 | ✅ |
| Total | 30 | 30 | 100% |
Architecture Notes
Quest-Centric Design
The implementation follows a quest-centric approach where:
- Quests define their NPC givers via
quest_giver_npc_idsfield - Adding new quests doesn't require modifying NPC files
- NPCs automatically discover which quests they can offer
NPC Conversation Flow
POST /api/v1/npcs/{npc_id}/talk
│
▼
┌─────────────────────────────┐
│ 1. Load Context │
│ - NPC, Character, Location│
└────────────┬────────────────┘
│
▼
┌─────────────────────────────┐
│ 2. Quest Eligibility Check │
│ QuestEligibilityService │
│ - Find quests where NPC │
│ is quest_giver │
│ - Filter by char level, │
│ completed, active, etc │
└────────────┬────────────────┘
│
▼
┌─────────────────────────────┐
│ 3. Probability Roll │
│ - Town: 30%, Tavern: 35% │
│ - Wilderness: 5% │
│ - If fail → no offer │
└────────────┬────────────────┘
│ (if success)
▼
┌─────────────────────────────┐
│ 4. Get Lore Context (stub) │
│ LoreService.get_context()│
│ - Quest embedded lore │
│ - Mock regional lore │
└────────────┬────────────────┘
│
▼
┌─────────────────────────────┐
│ 5. AI Generates Dialogue │
│ Naturally weaves quest │
│ offer into conversation │
│ Includes [QUEST_OFFER:id]│
└────────────┬────────────────┘
│
▼
┌─────────────────────────────┐
│ 6. Parse Response │
│ Extract quest_offered │
│ Return to frontend │
└─────────────────────────────┘
Phase 6 Integration Points
The LoreService stub is ready for Phase 6 Weaviate integration:
- Replace
MockLoreServicewithWeaviateLoreService - Quest's embedded
lore_contextwill be supplemented with vector DB queries - NPC dialogue template already has lore context section