feat: Implement Phase 5 Quest System (100% complete)

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>
This commit is contained in:
2025-11-29 15:42:55 -06:00
parent e7e329e6ed
commit df26abd207
42 changed files with 8421 additions and 2227 deletions

View File

@@ -66,6 +66,8 @@ class Character:
# Quests and exploration
active_quests: List[str] = field(default_factory=list)
completed_quests: List[str] = field(default_factory=list)
quest_states: Dict[str, Dict] = field(default_factory=dict) # quest_id -> CharacterQuestState.to_dict()
discovered_locations: List[str] = field(default_factory=list)
current_location: Optional[str] = None # Set to origin starting location on creation
@@ -378,6 +380,8 @@ class Character:
"equipped": {slot: item.to_dict() for slot, item in self.equipped.items()},
"gold": self.gold,
"active_quests": self.active_quests,
"completed_quests": self.completed_quests,
"quest_states": self.quest_states,
"discovered_locations": self.discovered_locations,
"current_location": self.current_location,
"npc_interactions": self.npc_interactions,
@@ -467,6 +471,8 @@ class Character:
equipped=equipped,
gold=data.get("gold", 0),
active_quests=data.get("active_quests", []),
completed_quests=data.get("completed_quests", []),
quest_states=data.get("quest_states", {}),
discovered_locations=data.get("discovered_locations", []),
current_location=data.get("current_location"),
npc_interactions=data.get("npc_interactions", {}),