# 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:** ```yaml 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` - Added `active_quests`, `completed_quests` fields - ✅ `/api/app/api/npcs.py` - Integrated quest eligibility into `talk_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 - [x] Quest loading from YAML - [x] Quest serialization (to_dict/from_dict) - [x] QuestEligibilityService filtering - [x] Probability roll logic - [x] Quest.is_complete() logic - [x] Quest.update_progress() logic ### Integration Tests - [x] Quest offer during NPC talk - [x] Accept quest (add to active_quests) - [x] Decline quest (set refused flag) - [x] Quest limit enforced (max 2 active) - [x] Quest progress updates during combat - [x] Complete quest and receive rewards - [x] Level up from quest XP - [x] 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 - [x] Quest data models implemented and tested - [x] QuestService loads quests from YAML files (5 quests created) - [x] Quest offering integrated into NPC conversations - [x] Context-aware quest selection working (eligibility + probability) - [x] Max 2 active quests enforced - [x] LoreService stub ready for Phase 6 integration - [x] AI naturally weaves quest offers into dialogue - [x] Quest offer parsing extracts `[QUEST_OFFER:id]` correctly - [x] Accept/decline endpoints working - [x] Quest progress updates automatically (combat kill tracking) - [x] Quest completion grants rewards correctly - [x] 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_ids` field - 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 `MockLoreService` with `WeaviateLoreService` - Quest's embedded `lore_context` will be supplemented with vector DB queries - NPC dialogue template already has lore context section