# OpenSpec Change: enterprise-gaming-quest - **Change ID**: enterprise-gaming-quest - **Package**: `@suaveplan/quest` - **Category**: gaming/narrative - **Target path**: `gaming/narrative/quest` - **Status**: PROPOSED - **Date**: 2026-04-24 - **Reference spec**: `/mnt/s/web/suaveplan/enterprise/quest.md` --- ## Summary Deliver `@suaveplan/quest` on the genesis branch from scratch at enterprise quality. The package provides a quest/mission system with multi-objective tracking, quest chains, rewards, and event-driven triggers. A `QuestDefinition` describes objectives (kill, collect, reach, talk, craft), prerequisites, and rewards; a `QuestLog` per player tracks active/completed quests with objective progress; a `QuestEventHandler` listens for game events and advances objectives automatically. Genesis adds Zod definition schemas, structured errors, OTel quest-completion counter, injectable clock, and 100% coverage. --- ## Current-state audit (genesis) Package does not exist on genesis yet — fresh build. --- ## Available workspace deps on genesis | Package | Role | |---|---| | `@suaveplan/error` (`workspace:^`) | `QuestError`; `QUEST.*` codes | | `@suaveplan/types` (`workspace:^`) | `Clock`, `IdGenerator` | | `@suaveplan/events` (`workspace:^`) | Quest lifecycle events + game-event listener | | `zod` (`catalog:forms`) | `QuestDefinition` schema | | `@opentelemetry/api` (`catalog:observability`) | Quest completion counter | --- ## Public API surface ```ts type ObjectiveType = 'kill' | 'collect' | 'reach' | 'talk' | 'craft' | 'custom' interface ObjectiveDefinition { id: string type: ObjectiveType description: string targetId?: string // NPC/item/location id required: number // quantity or count optional?: boolean } interface RewardDefinition { xp?: number gold?: number items?: { itemId: string; quantity: number }[] unlocksQuestId?: string } interface QuestDefinition { id: string title: string description: string objectives: ObjectiveDefinition[] rewards: RewardDefinition prerequisites?: string[] // quest IDs that must be completed chainNextId?: string // auto-starts after completion timeLimit?: number // seconds; undefined = no limit } function createQuestRegistry(): QuestRegistry interface QuestRegistry { register(def: QuestDefinition): void get(id: string): QuestDefinition | undefined } function createQuestLog(playerId: string, registry: QuestRegistry, options?: QuestLogOptions): QuestLog interface QuestLog { startQuest(questId: string): void abandonQuest(questId: string): void advanceObjective(questId: string, objectiveId: string, amount?: number): void isComplete(questId: string): boolean isAvailable(questId: string): boolean getActive(): QuestInstance[] getCompleted(): QuestInstance[] tick(dt: number): void // for time-limit tracking } interface QuestInstance { readonly questId: string readonly progress: Map readonly startedAt: number readonly isComplete: boolean readonly isFailed: boolean } // Event-driven advancement function createQuestEventHandler(log: QuestLog, mapping: QuestEventMapping): QuestEventHandler type QuestEventMapping = Map interface QuestEventHandler { onEvent(eventName: string, payload?: unknown): void } ``` ### Error codes ```ts type QuestErrorCode = | 'QUEST_NOT_FOUND' | 'QUEST_ALREADY_ACTIVE' | 'QUEST_PREREQUISITES_NOT_MET' | 'QUEST_OBJECTIVE_NOT_FOUND' | 'QUEST_ALREADY_COMPLETED' | 'QUEST_TIMED_OUT' ``` --- ## New additions for genesis 1. **Prerequisite chain** — `isAvailable()` checks full prerequisite DAG using DFS. 2. **Auto-chain** — on completion, if `chainNextId` is set and prerequisites met, quest log auto-starts next quest. 3. **Time limit** — `tick()` checks elapsed time; exceeds limit → marks quest failed, fires `quest:failed`. 4. **OTel** — `quest.completions_total` counter; `quest.active_count` gauge. --- ## File layout ```text gaming/narrative/quest/ package.json tsconfig.json vitest.config.ts src/ index.ts error-codes.ts constants/index.ts types/common.ts types/common.md core/ quest-registry/ quest-registry.ts quest-registry.md quest-registry.test.ts index.ts quest-log/ quest-log.ts quest-log.md quest-log.types.ts quest-log.test.ts index.ts event-handler/ event-handler.ts event-handler.md event-handler.types.ts event-handler.test.ts index.ts tests/ integration.test.ts ``` --- ## Impact **Downstream**: `@suaveplan/progression` listens for `quest:completed` events to award XP. Prerequisites: `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/events`.