# AI 原生游戏任务系统 PRD 更新时间:`2026-04-02` ## 0. 设计目标 这份方案针对当前仓库,回答的是: **如果要把现有“接受任务 -> 推进 -> 完成 -> 交付”的轻量任务链路,升级成真正的 AI 原生任务系统,应该怎样设计,才能既让任务更像从当前剧情里长出来,又不把规则、奖励和平衡交给模型失控决定?** 这里的“AI 原生”不是指: - 让模型随时随地自由生成一个任务标题和奖励 - 让模型直接修改任务状态、数值或掉落 - 让任务系统变成纯文案系统 这里的“AI 原生”指的是: - AI 负责理解当前故事局面,生成任务语义、动机、话术、阶段转折和关系变化 - 本地规则负责验证任务是否合法、如何推进、何时完成、奖励如何结算、存档如何兼容 - 任务系统不再只是“静态模板挂在 NPC 身上”,而是“从当前局面推导出来的可控任务合约” 一句话总结: **AI 决定这份任务在叙事上是什么,本地规则决定它在系统上如何成立。** ## 1. 当前系统现状 从当前仓库实现看,任务系统已经有一个可工作的最小闭环: - `src/data/questFlow.ts` - 负责构造任务、接受任务、推进任务、完成任务、交付任务 - `src/hooks/story/npcEncounterActions.ts` - 负责 NPC 交互里的 `quest_accept` / `quest_turn_in` - `src/hooks/useStoryGeneration.ts` - 负责在战斗、宝藏、NPC 交互后更新 quest progress - `src/types/story.ts` - 当前 `QuestLogEntry` 是运行时任务主结构 - `src/components/AdventurePanel.tsx` - 负责任务 UI 展示与奖励领取 当前系统已经支持: 1. NPC 提供任务 2. 玩家接受任务 3. 击败怪物 / 调查宝藏 / 与 NPC 切磋 三类目标推进 4. 任务完成后领取奖励 5. 奖励影响货币、背包和 NPC affinity 这说明基础闭环是成立的,问题不在“有没有任务系统”,而在于: - 当前任务更像“局部规则脚手架”,还不是“AI 原生任务系统” - AI 目前主要参与任务文案氛围和选项重写,没有真正参与任务语义生成 - 任务结构太扁平,无法承载阶段变化、关系转折、后续分支和任务记忆 ## 2. 当前系统的核心限制 ## 2.1 任务来源仍然偏静态 当前 `buildQuestForEncounter(...)` 的生成逻辑,本质还是: - 看当前 scene 有没有 hostile npc - 没有就看 monsterIds - 再没有就看 treasureHints - 最后 fallback 到 spar 这套逻辑稳定,但仍然是: **本地 if/else 在选任务类型,AI 只是在外围写故事。** 结果是: - 任务叙事贴合度有限 - 任务动机比较像通用模板 - 很难让任务明显体现“为什么偏偏是这个 NPC、这个时刻、这个场景、这个玩家” ## 2.2 任务结构只有“单目标单阶段” 当前 `QuestLogEntry.objective` 只有: - `kind` - `targetMonsterId` - `targetNpcId` - `targetSceneId` - `requiredCount` 它适合最小任务闭环,但不适合承载: - 多阶段任务 - 前置调查 -> 中段确认 -> 最终结算 - NPC 关系驱动的任务升级 - 同一任务在不同世界/场景下的变体 - 任务完成方式差异带来的后续影响 ## 2.3 任务状态过粗 当前状态只有: - `active` - `completed` - `turned_in` 这会导致任务系统无法表达: - 已发现但未正式接取 - 已接受但未激活下一阶段 - 已满足隐藏条件但未显式揭示 - 已失败 / 已过期 / 已被替代 - 已分支到不同结局 ## 2.4 奖励是固定规则,不随任务语义演化 当前奖励主要由 `buildQuestReward(worldType, roleText)` 生成。 优点: - 稳定 - 易控 - 好测试 问题: - 奖励和任务语义绑定弱 - 很难体现“这个 NPC 因为什么给你这份奖励” - 不能承载 AI 原生任务中更重要的“关系、线索、世界信息、后续机会” ## 2.5 AI 没有任务层专属 contract 当前 `StoryGenerationContext` 很强,但任务相关信息还没有独立建模。于是: - prompt 里只能把任务作为周边信息描述 - AI 无法明确返回“任务意图” - 本地也无法验证 AI 给出的任务建议是否合法 这意味着任务系统还没有形成: **专门面向任务设计的 AI <-> Rule contract** ## 3. 设计原则 ## 3.1 AI 负责叙事,本地负责规则 这是本项目已经验证有效的核心边界,这次任务系统继续沿用。 AI 负责: - 为什么现在出现这份任务 - 任务在关系和剧情上的意义 - 任务目标的话术表达 - 阶段推进时的语义转折 - 奖励在叙事上的来源解释 本地负责: - 任务是否能生成 - 任务目标类型是否合法 - 可推进事件有哪些 - 任务进度如何累计 - 奖励数值、掉落、affinity、货币如何结算 - 存档结构与兼容 ## 3.2 任务必须是“当前局面的产物” AI 原生任务不应是抽象模板,而应明确绑定: 1. 当前 scene / landmark / threat 2. 当前 NPC 的身份、态度、关系阶段 3. 最近几条 story history 4. 玩家当前状态、build 缺口、队伍关系 5. 当前世界观与 custom world profile 如果一份任务脱离这些上下文也成立,那它就还不是“AI 原生任务”。 ## 3.3 任务应优先表达“意图”,再编译成“合约” 不要让 AI 直接返回最终 `QuestLogEntry`。 更稳的方式是: 1. AI 先返回任务意图 `QuestIntent` 2. 本地把它编译成可执行的 `QuestContract` 3. 再由运行时把 `QuestContract` 映射成 UI 所需的 `QuestLogEntry` 这样能保证: - AI 足够自由地表达语义 - 本地仍然保留最终裁决权 - 系统容易测试、回放和做 fallback ## 3.4 任务系统必须兼容“AI 不可用” 这个项目所有关键玩法都应该支持 fallback。 所以 AI 原生任务系统必须允许: - AI 在线时,任务更贴剧情、更像当前局面的自然产物 - AI 离线时,任务仍可退回 deterministic builder 也就是说: **AI 提升任务质量,但不成为任务闭环的单点故障。** ## 4. 建议的系统分层 建议把新任务系统拆成 5 层。 ## 4.1 任务上下文采样层 先从当前运行时抽取一个统一的任务上下文: ```ts type QuestGenerationContext = { worldType: WorldType | null; customWorldProfile?: CustomWorldProfile | null; currentSceneId?: string | null; currentSceneName?: string | null; currentSceneDescription?: string | null; issuerNpcId?: string | null; issuerNpcName?: string | null; issuerNpcContext?: string | null; issuerAffinity?: number | null; issuerDisclosureStage?: NpcDisclosureStage | null; issuerWarmthStage?: NpcWarmthStage | null; encounterKind?: "npc" | "monster" | "treasure" | "none"; recentStoryMoments: StoryMoment[]; playerCharacter: Character; playerHp: number; playerMaxHp: number; playerMana: number; playerMaxMana: number; playerInventory: InventoryItem[]; playerEquipment: EquipmentLoadout; activeCompanions: CompanionState[]; rosterCompanions: CompanionState[]; currentQuestSummary: Array<{ id: string; title: string; status: QuestStatus; issuerNpcId: string; }>; }; ``` 这一层的目标不是直接生成任务,而是先回答: **这次任务生成到底发生在什么局面里?** ## 4.2 AI 任务意图层 让 AI 只返回“任务意图”,而不是最终任务实例: ```ts type QuestIntent = { narrativeType: "bounty" | "escort" | "investigation" | "retrieval" | "relationship" | "trial"; dramaticNeed: string; issuerGoal: string; playerHook: string; worldReason: string; recommendedObjectiveKinds: Array< "defeat_monster" | "inspect_treasure" | "spar_with_npc" | "deliver_item" | "reach_scene" | "talk_to_npc" >; urgency: "low" | "medium" | "high"; intimacy: "transactional" | "cooperative" | "trust_based"; rewardTheme: "currency" | "resource" | "relationship" | "intel" | "rare_item"; followupHooks: string[]; }; ``` 重点是: - AI 告诉系统这份任务“像什么” - 不直接决定最终字段值 - 不直接操作运行时状态 ## 4.3 本地任务编译层 本地根据 `QuestIntent + QuestGenerationContext` 编译出真正可执行的任务合约: ```ts type QuestContract = { id: string; issuerNpcId: string; questArchetype: QuestIntent["narrativeType"]; title: string; description: string; summary: string; steps: QuestStep[]; rewards: QuestRewardPackage; narrativeBindings: QuestNarrativeBinding; failPolicy: "never" | "leave_scene" | "issuer_hostile" | "time_window"; }; type QuestStep = { id: string; kind: | "defeat_monster" | "inspect_treasure" | "spar_with_npc" | "deliver_item" | "reach_scene" | "talk_to_npc"; targetSceneId?: string; targetNpcId?: string; targetMonsterId?: string; targetItemId?: string; requiredCount: number; progress: number; revealText: string; completeText: string; }; ``` 这层的职责是: - 将 AI 的语义建议裁剪到系统允许的任务范式内 - 确保每一个 step 都能被现有事件流推进 - 给每一个任务生成稳定 id、稳定状态和可存档结构 ## 4.4 任务运行时推进层 运行时只认本地任务合约和事件。 建议新增统一的任务推进事件: ```ts type QuestProgressSignal = | { kind: "monster_defeated"; sceneId?: string | null; monsterId: string } | { kind: "treasure_inspected"; sceneId?: string | null } | { kind: "npc_spar_completed"; npcId: string } | { kind: "npc_talk_completed"; npcId: string } | { kind: "scene_reached"; sceneId: string } | { kind: "item_delivered"; npcId: string; itemId: string; quantity: number }; ``` 然后统一走: - `applyQuestProgressSignal(contract, signal)` 而不是继续把推进逻辑分散到多处手写 helper。 这样做的价值是: - 后续加新任务种类时,只需扩展 signal 与 compiler - `useStoryGeneration` 只负责发 signal,不负责理解具体任务细节 - 测试可以直接覆盖“某信号输入 -> 某任务状态输出” ## 4.5 任务叙事回写层 AI 原生任务真正有价值的一层,不只是“生成任务”,而是“在任务推进时改写故事”。 建议在以下节点允许 AI 回写叙事: 1. 任务生成时 2. 新阶段解锁时 3. 任务完成但未交付时 4. 交付奖励时 5. 完成方式影响关系时 这层应该只接收: - 已经确定的任务 contract - 已经发生的规则结果 而不是允许 AI 反向篡改规则结果。 ## 5. 建议的数据结构升级 建议不要直接推翻当前 `QuestLogEntry`,而是在现有结构上新增一层 metadata。 ## 5.1 新增任务元数据 ```ts type QuestNarrativeBinding = { origin: "fallback_builder" | "ai_compiled"; narrativeType: "bounty" | "escort" | "investigation" | "retrieval" | "relationship" | "trial"; dramaticNeed: string; issuerGoal: string; playerHook: string; worldReason: string; followupHooks: string[]; }; type QuestRewardPackage = { currency: number; affinityBonus: number; items: InventoryItem[]; intel?: { codexEntry?: string; rumorText?: string; unlockedSceneId?: string; }; }; ``` ## 5.2 扩展现有 QuestLogEntry ```ts interface QuestLogEntry { id: string; issuerNpcId: string; issuerNpcName: string; sceneId: string | null; title: string; description: string; summary: string; objective: LegacyQuestObjective; progress: number; status: QuestStatus; completionNotified?: boolean; reward: QuestReward; rewardText: string; narrativeBinding?: QuestNarrativeBinding; steps?: QuestStep[]; activeStepId?: string | null; visibleStage?: number; hiddenFlags?: string[]; } ``` 这样做的原因是: - UI 可以先继续读旧字段 - 新逻辑逐步切到 `steps` - 旧存档仍然能兼容 ## 5.3 扩展任务状态 建议未来把任务状态扩展为: ```ts type QuestStatus = | "discovered" | "active" | "ready_to_turn_in" | "completed" | "turned_in" | "failed" | "expired"; ``` MVP 阶段不一定要一次性全上,但至少建议引入: - `discovered` - `ready_to_turn_in` 因为 AI 原生任务里,“被感知到”与“正式接取”往往不是同一刻。 ## 6. AI 任务 contract 设计 ## 6.1 新增专用 prompt contract 建议新增专用任务生成接口,而不是继续把任务生成混在通用 story completion 里。 建议新增: - `src/services/questDirector.ts` - `src/services/questPrompt.ts` - `src/services/questTypes.ts` AI 返回格式建议如下: ```json { "intent": { "narrativeType": "investigation", "dramaticNeed": "NPC 怀疑附近遗迹并不安全,但不敢直接深入", "issuerGoal": "确认遗迹是否值得继续接近", "playerHook": "玩家当前正好在此地,并且具备应对未知风险的能力", "worldReason": "最近场景和对话都指向此处存在被掩盖的旧痕迹", "recommendedObjectiveKinds": ["inspect_treasure", "talk_to_npc"], "urgency": "medium", "intimacy": "cooperative", "rewardTheme": "intel", "followupHooks": ["遗迹背后的旧势力", "NPC 曾经来过这里"] } } ``` 重点规则: - 只允许输出意图,不允许直接输出奖励数值 - 只允许使用本地支持的 objective kinds - 只描述建议,不越权改状态 ## 6.2 AI 负责的字段 AI 可以负责: - `title` 的语义方向 - `description` 的叙事质感 - `summary` 的自然语言表达 - `dramaticNeed` - `issuerGoal` - `playerHook` - `worldReason` - `followupHooks` AI 不负责: - `id` - `requiredCount` - `status` - `progress` - `currency` - `affinityBonus` - 直接生成超出规则支持范围的 objective ## 6.3 本地编译时的裁决逻辑 本地应当做如下校验: 1. objective kind 是否在 allowlist 内 2. 当前 scene / npc / monster / treasure 是否真的存在 3. 当前 NPC 是否已存在未完成任务 4. 当前任务是否会与现有任务重复或冲突 5. 奖励是否符合 rarity / economy / relationship budget 如果 AI 返回不合法: - 降级到 deterministic builder - 但仍可保留 AI 提供的部分叙事字段作为文案参考 ## 7. 任务生成时机设计 建议不是每次点 NPC 都无条件生成任务,而是让系统先判断“是否值得生成任务机会”。 ## 7.1 建议的触发点 适合生成任务机会的节点: 1. 初次与某 NPC 深入互动 2. 某 NPC affinity 达到新阶段 3. 某场景首次发现异常实体或藏宝线索 4. 某条最近剧情暗示了未解决的局面 5. 玩家在当前区域停留较久且缺少明确目标 ## 7.2 不建议触发的节点 以下节点不建议频繁生成任务: - 每次普通聊天都生成任务 - 每次旅行都自动冒出新任务 - 当前已有多个未完成任务时继续塞新任务 - AI 仅凭最近一句话就突然变出高强度委托 ## 7.3 任务机会判断器 建议先做本地 `questOpportunityEvaluator`: ```ts type QuestOpportunity = { shouldOffer: boolean; reason: string; suggestedIssuerNpcId?: string; suggestedThreatType?: "monster" | "treasure" | "relationship" | "travel"; }; ``` 这层先判断“该不该生成”,再决定“交给 AI 生成什么”。 这样能避免模型过度产出任务。 ## 8. 任务推进设计 ## 8.1 从“单字段进度”升级到“步骤机” 当前任务推进是: - 一个 objective - 一个 progress 建议升级为: - 多 step - 每个 step 自己推进 - active step 决定当前 UI 展示 例如: ```ts [ { id: "step_investigate_ruins", kind: "inspect_treasure", targetSceneId: "ruins_gate", requiredCount: 1 }, { id: "step_report_back", kind: "talk_to_npc", targetNpcId: "npc_scholar_lin", requiredCount: 1 } ] ``` 这样任务就能表达: - 先调查 - 再回报 - 再领取奖励 ## 8.2 允许“隐式推进,显式揭示” AI 原生任务最有意思的一点,是任务可以先发生推进,再在叙事上被揭示。 例如: - 玩家在探索时先完成了调查 - 回去交谈时 NPC 才明确说出“你已经替我确认了那里的情况” 这意味着系统上应允许: - step 已完成 - 但 `visibleStage` 仍未切换到下一步,直到触发 reveal 这样任务会更像故事,而不是机械 checklist。 ## 9. 奖励设计 ## 9.1 奖励不只是一包货币和道具 AI 原生任务里,奖励至少应拆成 4 类: 1. 经济奖励 - currency - item bundles 2. 关系奖励 - affinity - disclosure stage / warmth stage 解锁 3. 信息奖励 - rumor - codex entry - 场景/势力线索 4. 机会奖励 - 解锁新 scene - 解锁新 NPC 交互 - 解锁后续任务机会 ## 9.2 AI 负责解释奖励来源,不负责定奖励数值 建议奖励设计继续遵守: - AI 解释“为什么这个 NPC 给这些” - 本地决定“究竟给多少” 例如: - AI 可说:这是 NPC 私藏的旧护符、只愿交给值得信任的人 - 本地则决定:这是 `rare relic + affinityBonus 12 + currency 72` ## 10. UI 表达建议 当前 `AdventurePanel` 已经有不错的任务面板基础,AI 原生任务系统建议补的不是“更多卡片”,而是“更多阶段感”。 建议新增以下 UI 信息: 1. 任务来源语义 - 谁委托 - 为什么此刻委托 2. 当前阶段标题 - 当前不是只看进度条,还要看“现在在做哪一步” 3. 任务关系状态 - 交易型 / 协作型 / 信任型 4. 任务后续钩子 - 这件事可能会牵出什么 UI 上不建议直接暴露给玩家的内部字段: - `dramaticNeed` - `followupHooks` 原始数组 - 所有 hidden flags 这些字段应该被整理成更自然的面板文案。 ## 11. 与当前仓库的接入点建议 ## 11.1 第一批建议改动的文件 建议先从以下文件接入: - `src/types/story.ts` - 扩展 `QuestLogEntry` - `src/services/aiTypes.ts` - 增加任务生成上下文 - `src/data/questFlow.ts` - 增加 contract compiler 和 step progression - `src/hooks/story/npcEncounterActions.ts` - 将 `quest_accept` 改为“机会判断 -> AI 意图 -> 本地编译” - `src/services/prompt.ts` - 不直接负责任务生成,拆出 `questPrompt.ts` ## 11.2 第一批不建议碰的区域 这轮不建议一开始就深入改: - `AdventurePanel` 的整体结构 - `useStoryGeneration` 的全部 orchestrator - 所有现存 AI story prompt 原因是任务系统已经是主链路的一部分,第一步应该先把 contract 立住,而不是把整个 story 系统一起重写。 ## 12. MVP 落地顺序 ## 阶段 A:先做任务 contract,不改全部表现 新增: - `src/services/questTypes.ts` - `src/services/questDirector.ts` - `src/services/questPrompt.ts` 目标: - AI 能返回 `QuestIntent` - 本地能编译成 `QuestContract` - 旧 UI 仍然照常显示 ## 阶段 B:把 NPC 接任务改成 AI 原生生成 先只改: - `quest_accept` 此时: - 仍沿用现有三种基础 objective kind - 但 title / description / rewardText / followupHooks 开始变成上下文生成 这是最稳的切入点,因为: - 影响面小 - 可回退 - 容易观察质量提升 ## 阶段 C:把任务推进改成 step + signal 重点改: - `applyQuestProgressFromMonsterVictory` - `applyQuestProgressFromTreasure` - `applyQuestProgressFromSpar` 把它们收口到统一 signal reducer。 ## 阶段 D:把交付奖励与后续机会联动起来 让 `quest_turn_in` 不再只是: - 发货币 - 发道具 - 加 affinity 而是还能: - 写入 rumor / intel - 解锁后续任务机会 - 改变 NPC 对话阶段 ## 13. 为什么这套方案适合当前仓库 这套方案不是重做一套新玩法,而是顺着仓库已经验证过的边界继续深化: 1. 仓库已经验证“AI 负责叙事,本地负责规则”是正确方向 2. 仓库已经有现成的 quest UI、quest status、quest reward、npc affinity 链路 3. 当前 `useStoryGeneration` 已经在汇总 story/combat/treasure/npc 事件,天然适合继续发 quest signal 4. 当前 `StoryGenerationContext` 已经足够强,只是还缺一个任务专用 contract 所以这次真正缺的不是“再加一个任务面板”,而是: **把任务从‘规则附属物’升级成‘叙事与规则之间的正式中介层’。** ## 14. 最后结论 对这个项目来说,理想的 AI 原生任务系统,不应该做成“AI 随机发委托”,而应该做成: 1. 系统先判断当前局面是否值得生成任务机会 2. AI 根据世界、场景、NPC、最近剧情和玩家状态,生成任务意图 3. 本地将任务意图编译成稳定、可测试、可持久化的任务合约 4. 运行时通过统一 signal 推进任务步骤 5. AI 在任务生成、阶段切换、完成交付时回写叙事质感 6. 奖励既包括资源,也包括关系、情报和后续机会 这样生成出来的任务,才会同时满足三件事: - **像从当前剧情里自然长出来的** - **像系统里可验证、可推进、可存档的** - **像 AI 原生游戏真正该有的任务结构**