Rework story engine flow and reorganize project docs
Some checks failed
CI / verify (push) Has been cancelled
Some checks failed
CI / verify (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,699 @@
|
||||
# AI 原生自定义世界生成流程优化 PRD
|
||||
|
||||
更新时间:`2026-04-06`
|
||||
|
||||
## 0. 文档目的
|
||||
|
||||
这份 PRD 用于基于 [CUSTOM_WORLD_CREATOR_INPUT_AND_AI_BOUNDARY_DESIGN_2026-04-06.md](../design/CUSTOM_WORLD_CREATOR_INPUT_AND_AI_BOUNDARY_DESIGN_2026-04-06.md) 的分工结论,系统优化当前自定义世界生成流程。
|
||||
|
||||
目标不是推翻当前已经存在的多阶段生成链,而是解决下面这个核心错位:
|
||||
|
||||
**当前仓库已经开始把世界生成拆成 `framework -> themePack -> storyGraph -> role outline -> dossier -> narrativeProfile` 的分阶段 AI 编译流程,但创作者入口仍然是“一段大文本”,结果页又把大量低杠杆字段重新扔回给创作者人工兜底。**
|
||||
|
||||
一句话定义本次优化:
|
||||
|
||||
**让创作者先定义世界灵魂锚点,再让 AI / 系统围绕锚点分层生成、分层展开、分层可控地完成长尾内容。**
|
||||
|
||||
## 1. 当前流程现状
|
||||
|
||||
## 1.1 当前用户流程
|
||||
|
||||
当前自定义世界的实际产品链路大致是:
|
||||
|
||||
1. 世界选择页点击“创建自定义世界”
|
||||
2. 弹出创建弹窗,只输入一段 `世界设定文本`
|
||||
3. 调用 `generateCustomWorldProfile(...)`
|
||||
4. 进入分阶段生成页,依次跑:
|
||||
- 世界框架
|
||||
- 题材适配层
|
||||
- 世界线程图谱
|
||||
- 可扮演角色骨架
|
||||
- 场景角色骨架
|
||||
- 场景骨架
|
||||
- 场景连接
|
||||
- 角色叙事补全
|
||||
- 角色档案补全
|
||||
- 角色叙事档案补全
|
||||
- 最终归档
|
||||
5. 生成完成后进入结果页
|
||||
6. 在结果页里按 `世界 / 可扮演角色 / 场景角色 / 场景` 四个页签逐项编辑
|
||||
7. 保存并进入世界
|
||||
|
||||
对应当前仓库的主要模块:
|
||||
|
||||
- 输入入口:`src/components/SelectionCustomizationModals.tsx`
|
||||
- 预开局流程:`src/components/game-shell/PreGameSelectionFlow.tsx`
|
||||
- 分阶段生成:`src/services/ai.ts`
|
||||
- prompt 与结构归一:`src/services/customWorld.ts`
|
||||
- 扩展与编译:`src/services/customWorldBuilder.ts`
|
||||
- 结果页:`src/components/CustomWorldResultView.tsx`
|
||||
- 结果目录:`src/components/CustomWorldEntityCatalog.tsx`
|
||||
- 实体编辑器:`src/components/CustomWorldEntityEditorModal.tsx`
|
||||
|
||||
## 1.2 当前流程已经做对了什么
|
||||
|
||||
当前流程并不是“完全错误”,它已经有几个很值得保留的基础:
|
||||
|
||||
1. 生成链已经不是单次大 JSON 直出,而是分阶段生成。
|
||||
2. 已经存在 `themePack / storyGraph / narrativeProfile / knowledgeFacts / threadContracts` 这类更接近 AI 原生剧情引擎的结构。
|
||||
3. 已经有阶段进度反馈,而不是黑盒等待。
|
||||
4. 已经有结果页与人工编辑能力,可以作为后续工作台的基础。
|
||||
5. 已经有 normalize / fallback / repair prompt 机制,说明链路具备继续工程化的基础。
|
||||
|
||||
本次优化应尽量复用这些已有能力,而不是回到“单次 prompt 直接生世界”的旧思路。
|
||||
|
||||
## 1.3 当前流程的核心问题
|
||||
|
||||
## 1.3.1 创作者入口过于粗糙
|
||||
|
||||
当前创建入口只有一块大文本输入框。
|
||||
|
||||
这会直接导致:
|
||||
|
||||
1. 不会写长描述的用户很难开局。
|
||||
2. 愿意精细创作的用户没有结构化落点。
|
||||
3. 系统无法明确分辨“哪些是创作者真正想锁定的锚点,哪些只是随口补充的描述”。
|
||||
|
||||
结果就是:
|
||||
|
||||
**输入端自由,但信息信号不稳定;AI 虽然能生成很多内容,却不一定生成的是创作者真正关心的内容。**
|
||||
|
||||
## 1.3.2 创作者与 AI 的职责发生倒置
|
||||
|
||||
当前流程实际上是:
|
||||
|
||||
- 创作者先写一段泛化设定
|
||||
- AI 再把整个世界铺满
|
||||
- 创作者最后回到结果页,人工修改大量角色、章节、技能、初始物品、场景连接等细节
|
||||
|
||||
这与“低创作门槛、高创作自由度”的目标相反。
|
||||
|
||||
因为真正应该由创作者控制的,是:
|
||||
|
||||
- 世界核心命题
|
||||
- 主题与气质
|
||||
- 玩家视角
|
||||
- 核心冲突
|
||||
- 关键角色
|
||||
- 关键地点
|
||||
- 标志性物件 / 怪物 / 禁忌
|
||||
|
||||
而不是让创作者在结果页里逐个补:
|
||||
|
||||
- `backstoryReveal.chapters`
|
||||
- `skills`
|
||||
- `initialItems`
|
||||
- `sceneNpcIds`
|
||||
- `connections`
|
||||
- 各类长尾角色与场景的细枝末节
|
||||
|
||||
## 1.3.3 关键内容与长尾内容没有分层
|
||||
|
||||
当前流程会稳定生成:
|
||||
|
||||
- `5` 个可扮演角色
|
||||
- `25+` 个场景角色
|
||||
- `10+` 个场景
|
||||
|
||||
问题不在数量本身,而在于系统并没有明确区分:
|
||||
|
||||
1. 哪些是创作者应重点塑造的关键对象
|
||||
2. 哪些只是 AI 应自动展开的长尾铺量
|
||||
|
||||
这会导致两个问题:
|
||||
|
||||
1. AI 在早期就花大量成本生成长尾内容,等待时间长。
|
||||
2. 创作者在结果页里面对的是一整套“全部都生成了”的世界,而不是“先抓关键锚点,再决定是否继续铺开”。
|
||||
|
||||
## 1.3.4 当前结果页暴露了过多低杠杆字段
|
||||
|
||||
当前结果页和实体编辑器允许编辑的字段过多,而且很多是低创作价值、系统结构化字段:
|
||||
|
||||
- 背景章节的标题、阈值、teaser、content、contextSnippet
|
||||
- 角色技能与初始物品
|
||||
- 场景 NPC 分配
|
||||
- 场景连接网络
|
||||
|
||||
这对“专业创作者”当然有帮助,但对目标用户来说,容易把工具变成:
|
||||
|
||||
**看起来自由度很高,实际上需要承担很多系统编辑工作。**
|
||||
|
||||
## 1.3.5 当前重新生成是“整世界覆盖式”的
|
||||
|
||||
当前结果页的“重新生成”会清空并重做当前世界的所有信息。
|
||||
|
||||
这意味着:
|
||||
|
||||
1. 创作者一旦修改过内容,就会担心被覆盖。
|
||||
2. 没有“锁定关键内容,只重生成长尾部分”的机制。
|
||||
3. AI 无法真正成为创作搭档,只像一次性大批量生成器。
|
||||
|
||||
## 1.3.6 当前生成阶段是“模型视角”,不是“创作者视角”
|
||||
|
||||
当前生成页展示的是系统批次和阶段进度,这很好,但它主要回答的是:
|
||||
|
||||
- 现在模型在跑哪一步
|
||||
|
||||
没有回答的是:
|
||||
|
||||
- 创作者最关心的关键角色是否已经成型
|
||||
- 世界冲突是否已经稳定
|
||||
- 当前这轮已经锁定了哪些核心创意
|
||||
- 接下来生成的是关键锚点,还是长尾内容
|
||||
|
||||
也就是说:
|
||||
|
||||
**当前链路的进度可见了,但创作过程仍然没有真正可见。**
|
||||
|
||||
## 2. 本次优化的设计目标
|
||||
|
||||
这次优化要同时满足 6 个目标:
|
||||
|
||||
1. 降低输入门槛
|
||||
- 不要求创作者一上来写长文,不要求理解系统字段。
|
||||
|
||||
2. 提高高杠杆创作自由度
|
||||
- 让创作者直接控制世界灵魂锚点,而不是低价值细节。
|
||||
|
||||
3. 明确创作者与 AI 的职责边界
|
||||
- 创作者负责“决定什么值得创作”,AI 负责“把它展开并跑起来”。
|
||||
|
||||
4. 保留现有分阶段生成骨架
|
||||
- 不推翻 `framework -> themePack -> storyGraph -> role/landmark` 的已有结构。
|
||||
|
||||
5. 引入锁定与局部重生成
|
||||
- 让创作者能保住自己在乎的内容,只重做其余部分。
|
||||
|
||||
6. 把结果页从“数据总表”升级成“创作工作台”
|
||||
- 让编辑界面按创作价值组织,而不是按底层对象堆字段。
|
||||
|
||||
## 3. 核心产品结论
|
||||
|
||||
优化后的自定义世界流程应该改为:
|
||||
|
||||
```text
|
||||
创作者输入世界锚点
|
||||
-> AI 编译创作者意图摘要
|
||||
-> 创作者确认 / 锁定关键锚点
|
||||
-> AI 先生成关键角色与关键地点
|
||||
-> 创作者可局部修改 / 局部重生成
|
||||
-> AI 再展开长尾 NPC、长尾场景与运行时编译结构
|
||||
-> 结果页以“锚点 / 关键对象 / 扩展内容 / 运行时摘要”方式组织
|
||||
-> 保存并进入世界
|
||||
```
|
||||
|
||||
一句话:
|
||||
|
||||
**先做创作决策,再做内容展开;先做关键对象,再做长尾铺量;先让创作者锁定灵魂,再让 AI 扩散世界。**
|
||||
|
||||
## 4. 输入层优化方案
|
||||
|
||||
## 4.1 把“单一大文本”升级为“创作卡片”
|
||||
|
||||
新的输入层不应只有一块大 textarea,而应拆成卡片式输入。
|
||||
|
||||
建议至少包含 9 张卡:
|
||||
|
||||
1. 世界一句话
|
||||
2. 主题与气质
|
||||
3. 玩家是谁
|
||||
4. 核心冲突
|
||||
5. 关键势力
|
||||
6. 关键角色
|
||||
7. 关键地点
|
||||
8. 标志性要素
|
||||
9. 禁止事项
|
||||
|
||||
每张卡都支持:
|
||||
|
||||
1. 一句话输入
|
||||
2. 标签 / 选项辅助
|
||||
3. 高级补充展开
|
||||
|
||||
这样做的目的不是让用户填更多,而是让:
|
||||
|
||||
- 不会写长文的人,也能靠卡片完成创作输入
|
||||
- 愿意深挖的人,也有明确位置继续提升质量
|
||||
|
||||
## 4.2 保留“自由输入模式”,但不再只靠它
|
||||
|
||||
当前的 `settingText` 不应被废弃,而应保留为:
|
||||
|
||||
1. 快速模式
|
||||
2. 导入模式
|
||||
3. 兜底模式
|
||||
|
||||
系统应支持两种输入入口:
|
||||
|
||||
1. 快速文本模式
|
||||
- 用户只写一段设定,系统自动拆分成创作卡片建议
|
||||
|
||||
2. 卡片模式
|
||||
- 用户直接按结构化方式输入世界锚点
|
||||
|
||||
两种模式最终都编译成统一的创作者意图对象。
|
||||
|
||||
## 4.3 必填与选填要分开
|
||||
|
||||
不应要求用户每一张卡都填完。
|
||||
|
||||
建议:
|
||||
|
||||
- 必填:
|
||||
- 世界一句话
|
||||
- 主题与气质
|
||||
- 玩家是谁
|
||||
- 核心冲突
|
||||
|
||||
- 选填:
|
||||
- 关键势力
|
||||
- 关键角色
|
||||
- 关键地点
|
||||
- 标志性要素
|
||||
- 禁止事项
|
||||
|
||||
这样既能保证世界最小成型,又不会把创作者门槛抬高。
|
||||
|
||||
## 4.4 明确支持“锁定”
|
||||
|
||||
每张卡片、每个关键角色、每个关键地点都应支持锁定。
|
||||
|
||||
锁定后:
|
||||
|
||||
1. AI 不得在重生成时覆盖该内容
|
||||
2. 长尾内容只能围绕它展开
|
||||
3. 结果页里应明确显示其为“创作者锚点”
|
||||
|
||||
## 5. 生成链路优化方案
|
||||
|
||||
## 5.1 新增“创作者意图编译层”
|
||||
|
||||
在真正开始世界生成前,先新增一个轻量阶段:
|
||||
|
||||
**Creator Intent Compile**
|
||||
|
||||
输入:
|
||||
|
||||
- 文本模式输入
|
||||
- 或卡片模式输入
|
||||
|
||||
输出:
|
||||
|
||||
- 创作者意图摘要
|
||||
- 世界锚点摘要
|
||||
- 系统识别出的关键角色 / 冲突 / 地点 / 禁忌
|
||||
|
||||
这一步的作用不是生成世界,而是先回答:
|
||||
|
||||
1. 系统理解到的世界核心是什么
|
||||
2. 哪些内容将被视为创作者强锚点
|
||||
3. 哪些内容将交给 AI 扩展
|
||||
|
||||
## 5.2 把当前生成链改成“关键先行、长尾后补”
|
||||
|
||||
当前 `generateCustomWorldProfile(...)` 的分阶段结构可以保留,但生成顺序需要更创作者化。
|
||||
|
||||
建议改成 5 层:
|
||||
|
||||
### 第一层:世界锚点层
|
||||
|
||||
先生成:
|
||||
|
||||
- 世界框架
|
||||
- ThemePack
|
||||
- StoryGraph 的基础版
|
||||
- 创作者锚点摘要
|
||||
|
||||
这一层完成后,系统应能让创作者看到:
|
||||
|
||||
- 世界现在到底被理解成了什么
|
||||
- 哪些冲突 / 势力 / 意象被识别出来了
|
||||
|
||||
### 第二层:关键对象层
|
||||
|
||||
优先生成:
|
||||
|
||||
- 关键可扮演角色
|
||||
- 关键场景角色
|
||||
- 关键地点
|
||||
|
||||
这一层优先围绕创作者明确输入的角色和地点,而不是先铺满全部数量。
|
||||
|
||||
### 第三层:创作者校对层
|
||||
|
||||
在继续展开长尾内容前,应允许创作者做一次轻量校对:
|
||||
|
||||
- 确认关键角色是否对
|
||||
- 确认关键地点是否对
|
||||
- 锁定已经满意的内容
|
||||
- 对不满意的关键对象做局部重生成
|
||||
|
||||
### 第四层:长尾展开层
|
||||
|
||||
在关键层稳定后,再生成:
|
||||
|
||||
- 普通场景角色
|
||||
- 路人 / 杂兵 / 补位 NPC
|
||||
- 次级地点
|
||||
- 扩展连接关系
|
||||
- 长尾命名和描述
|
||||
|
||||
### 第五层:运行时编译层
|
||||
|
||||
最后再编译:
|
||||
|
||||
- `themePack`
|
||||
- `storyGraph`
|
||||
- `knowledgeFacts`
|
||||
- `threadContracts`
|
||||
- `narrativeProfile`
|
||||
- 各类运行时支持结构
|
||||
|
||||
## 5.3 支持“快速开局生成”和“完整展开生成”
|
||||
|
||||
建议提供两种生成策略:
|
||||
|
||||
1. 快速开局
|
||||
- 先完成世界锚点 + 关键对象 + 最小可玩档案
|
||||
- 用户可以更快看到世界雏形
|
||||
|
||||
2. 完整展开
|
||||
- 一次性继续补齐长尾场景角色、地标和完整世界网络
|
||||
|
||||
这样做的价值很高:
|
||||
|
||||
1. 降低首次等待焦虑
|
||||
2. 让创作者更早介入关键对象校正
|
||||
3. 避免系统在创作方向还没稳定前,先铺满大量长尾内容
|
||||
|
||||
## 5.4 角色与场景生成要改成“锚点优先 + 长尾补位”
|
||||
|
||||
当前角色与场景的生成方式更像“按配额批量产出”。
|
||||
|
||||
优化后应改为:
|
||||
|
||||
1. 先生成创作者明确指定的关键角色 / 地点
|
||||
2. 再根据世界冲突自动补位缺失的角色原型和场景功能位
|
||||
3. 最后再铺长尾
|
||||
|
||||
这样生成出来的世界会更像“围绕创作者意图长出来”,而不是“先生成了一个完整世界,再让创作者去认领”
|
||||
|
||||
## 6. 结果页与编辑工作台优化方案
|
||||
|
||||
## 6.1 结果页不应再按“底层对象目录”组织为主
|
||||
|
||||
当前结果页主要按:
|
||||
|
||||
- 世界
|
||||
- 可扮演角色
|
||||
- 场景角色
|
||||
- 场景
|
||||
|
||||
来组织。
|
||||
|
||||
优化后建议改成 4 层工作台:
|
||||
|
||||
1. 创作锚点
|
||||
- 展示创作者输入和锁定内容
|
||||
|
||||
2. 关键对象
|
||||
- 关键角色、关键地点、关键冲突对象
|
||||
|
||||
3. 扩展内容
|
||||
- AI 自动展开的长尾角色、长尾地点、补位内容
|
||||
|
||||
4. 世界编译摘要
|
||||
- 展示世界线程、题材包、运行时摘要,但默认不要求创作者编辑
|
||||
|
||||
## 6.2 编辑界面应遵守“高价值字段前置,低价值字段折叠”
|
||||
|
||||
对创作者默认暴露的应是:
|
||||
|
||||
- 角色一句话定位
|
||||
- 角色表面面貌
|
||||
- 角色真正想要什么
|
||||
- 角色与谁有关
|
||||
- 地点为什么重要
|
||||
- 地点承载什么冲突
|
||||
- 世界哪些规则不能动
|
||||
|
||||
不应默认把下面这些字段摆在第一屏:
|
||||
|
||||
- `backstoryReveal.chapters`
|
||||
- `skills`
|
||||
- `initialItems`
|
||||
- `contextSnippet`
|
||||
- `sceneNpcIds`
|
||||
- `connections`
|
||||
|
||||
这些应被系统下沉到:
|
||||
|
||||
- 自动生成
|
||||
- 高级模式
|
||||
- 或局部展开区域
|
||||
|
||||
## 6.3 新增局部重生成
|
||||
|
||||
结果页必须支持至少 4 种局部重生成:
|
||||
|
||||
1. 仅重生成某个关键角色
|
||||
2. 仅重生成某个关键地点
|
||||
3. 仅重生成长尾场景角色
|
||||
4. 仅重生成场景网络 / 长尾连接
|
||||
|
||||
并且所有局部重生成都必须:
|
||||
|
||||
- 尊重锁定内容
|
||||
- 显示影响范围
|
||||
- 避免全局覆盖
|
||||
|
||||
## 6.4 新增“AI 建议修订”而非“只允许手改”
|
||||
|
||||
结果页不应只提供人工编辑,还应提供:
|
||||
|
||||
- 让 AI 重写一句话定位
|
||||
- 让 AI 补强冲突张力
|
||||
- 让 AI 改得更克制 / 更黑暗 / 更传奇 / 更现实
|
||||
- 让 AI 只围绕已锁定内容变体
|
||||
|
||||
这样才能真正体现“AI 是创作辅助,而不是一次性生成器”。
|
||||
|
||||
## 7. 数据结构建议
|
||||
|
||||
## 7.1 新增 `CustomWorldCreatorIntent`
|
||||
|
||||
建议新增创作者输入的统一结构:
|
||||
|
||||
```ts
|
||||
interface CustomWorldCreatorIntent {
|
||||
sourceMode: 'freeform' | 'card';
|
||||
rawSettingText: string;
|
||||
worldHook: string;
|
||||
themeKeywords: string[];
|
||||
toneDirectives: string[];
|
||||
playerPremise: string;
|
||||
openingSituation: string;
|
||||
coreConflicts: string[];
|
||||
keyFactions: CreatorFactionSeed[];
|
||||
keyCharacters: CreatorCharacterSeed[];
|
||||
keyLandmarks: CreatorLandmarkSeed[];
|
||||
iconicElements: string[];
|
||||
forbiddenDirectives: string[];
|
||||
}
|
||||
```
|
||||
|
||||
作用:
|
||||
|
||||
- 把“创作者真正输入了什么”从最终 `CustomWorldProfile` 中分离出来
|
||||
|
||||
## 7.2 新增 `CustomWorldAnchorPack`
|
||||
|
||||
建议新增系统编译后的锚点包:
|
||||
|
||||
```ts
|
||||
interface CustomWorldAnchorPack {
|
||||
worldSummary: string;
|
||||
creatorIntentSummary: string;
|
||||
lockedAnchorIds: string[];
|
||||
keyConflictSummaries: string[];
|
||||
keyFactionSummaries: string[];
|
||||
keyCharacterAnchors: ActorAnchor[];
|
||||
keyLandmarkAnchors: LandmarkAnchor[];
|
||||
motifDirectives: string[];
|
||||
}
|
||||
```
|
||||
|
||||
作用:
|
||||
|
||||
- 让后续长尾扩展、局部重生成、结果页工作台都围绕同一套“创作锚点”工作
|
||||
|
||||
## 7.3 新增 `CustomWorldLockState`
|
||||
|
||||
```ts
|
||||
interface CustomWorldLockState {
|
||||
worldLockedFields: string[];
|
||||
lockedCharacterIds: string[];
|
||||
lockedLandmarkIds: string[];
|
||||
lockedConflictIds: string[];
|
||||
lockedFactionIds: string[];
|
||||
}
|
||||
```
|
||||
|
||||
作用:
|
||||
|
||||
- 明确哪些内容 AI 不能重写
|
||||
|
||||
## 7.4 新增 `CustomWorldGenerationDraft`
|
||||
|
||||
```ts
|
||||
interface CustomWorldGenerationDraft {
|
||||
creatorIntent: CustomWorldCreatorIntent;
|
||||
anchorPack: CustomWorldAnchorPack | null;
|
||||
profile: CustomWorldProfile | null;
|
||||
lockState: CustomWorldLockState;
|
||||
generationMode: 'fast' | 'full';
|
||||
generationStatus: 'idle' | 'compiling' | 'generating_key' | 'generating_long_tail' | 'ready';
|
||||
}
|
||||
```
|
||||
|
||||
作用:
|
||||
|
||||
- 让“创作者输入、AI 编译、结果编辑”成为连续工作流,而不是只有最终成品对象
|
||||
|
||||
## 8. 与当前仓库的接入建议
|
||||
|
||||
## 8.1 输入层
|
||||
|
||||
优先改:
|
||||
|
||||
- `src/components/SelectionCustomizationModals.tsx`
|
||||
- `src/components/game-shell/PreGameSelectionFlow.tsx`
|
||||
|
||||
目标:
|
||||
|
||||
- 把单 textarea 升级为“快速模式 + 卡片模式”
|
||||
- 新增创作者意图状态
|
||||
- 新增锁定和局部重生成入口
|
||||
|
||||
## 8.2 prompt 与生成服务层
|
||||
|
||||
优先改:
|
||||
|
||||
- `src/services/customWorld.ts`
|
||||
- `src/services/ai.ts`
|
||||
|
||||
目标:
|
||||
|
||||
- 新增 Creator Intent Compile prompt
|
||||
- 新增 Anchor Pack compile prompt
|
||||
- 新增局部重生成 prompt
|
||||
- 保留现有 `framework / themePack / storyGraph / role / landmark` 生成骨架
|
||||
|
||||
## 8.3 Builder 与结构层
|
||||
|
||||
优先改:
|
||||
|
||||
- `src/services/customWorldBuilder.ts`
|
||||
- `src/types/customWorld.ts`
|
||||
|
||||
目标:
|
||||
|
||||
- 为 `CustomWorldProfile` 增加创作者意图与锚点相关扩展字段
|
||||
- 保持旧档兼容
|
||||
- 让现有 builder 能同时消费 `creatorIntent + anchorPack + profile seed`
|
||||
|
||||
## 8.4 结果页与编辑器层
|
||||
|
||||
优先改:
|
||||
|
||||
- `src/components/CustomWorldResultView.tsx`
|
||||
- `src/components/CustomWorldEntityCatalog.tsx`
|
||||
- `src/components/CustomWorldEntityEditorModal.tsx`
|
||||
|
||||
目标:
|
||||
|
||||
- 结果页由“数据目录”转为“创作工作台”
|
||||
- 支持局部重生成
|
||||
- 高价值字段前置,低价值字段折叠
|
||||
- 允许 AI 辅助改写,而不只是手工编辑
|
||||
|
||||
## 9. 明确不做什么
|
||||
|
||||
本次优化不做以下事情:
|
||||
|
||||
1. 不推翻当前自定义世界最终输出仍是 `CustomWorldProfile` 的兼容目标
|
||||
2. 不把所有运行时结构都暴露给创作者直接编辑
|
||||
3. 不要求创作者理解 `themePack / storyGraph / knowledgeFacts / threadContracts` 等系统结构
|
||||
4. 不把复杂数值平衡、掉落预算、build 预算转移给创作者
|
||||
5. 不把“高自由度”理解成“所有字段都手工可改”
|
||||
|
||||
## 10. 验收标准
|
||||
|
||||
做到以下几点,才算这次优化真正成立:
|
||||
|
||||
1. 创作者可以不用写长文,只靠卡片输入也能完成自定义世界创建。
|
||||
2. 系统会明确区分“创作者锚点”和“AI 自动展开内容”。
|
||||
3. 创作者不再需要默认手改大量 `skills / initialItems / backstoryReveal / scene connections` 才能得到可用世界。
|
||||
4. 结果页支持锁定关键角色、关键地点、关键冲突,并支持局部重生成。
|
||||
5. 重新生成不再默认覆盖整个世界。
|
||||
6. 当前 `framework -> themePack -> storyGraph -> role/landmark` 生成主链可以继续复用,而不是被废弃。
|
||||
7. 结果页默认展示的是高创作价值对象,而不是系统级低层字段。
|
||||
8. 长尾内容生成明显后置于关键对象生成,创作者能更早看到并修正关键对象。
|
||||
9. 旧的自由文本输入模式仍然可用,但不再是唯一入口。
|
||||
|
||||
## 11. 推荐落地顺序
|
||||
|
||||
## 阶段 A:先加创作者意图层
|
||||
|
||||
先做:
|
||||
|
||||
- `CustomWorldCreatorIntent`
|
||||
- 输入卡片 UI
|
||||
- 快速文本 -> 卡片建议编译
|
||||
|
||||
目标:
|
||||
|
||||
- 先把创作者输入从“单一大文本”升级成“可识别的创作锚点”
|
||||
|
||||
## 阶段 B:再加锚点包与锁定能力
|
||||
|
||||
先做:
|
||||
|
||||
- `CustomWorldAnchorPack`
|
||||
- `CustomWorldLockState`
|
||||
- 锁定 UI
|
||||
|
||||
目标:
|
||||
|
||||
- 让后续生成真正知道“哪些不能动”
|
||||
|
||||
## 阶段 C:再改生成顺序
|
||||
|
||||
先做:
|
||||
|
||||
- 关键对象优先
|
||||
- 长尾内容后置
|
||||
- 快速开局模式
|
||||
|
||||
目标:
|
||||
|
||||
- 缩短“看到关键结果”的等待时间
|
||||
|
||||
## 阶段 D:最后重做结果页工作台
|
||||
|
||||
先做:
|
||||
|
||||
- 锚点页
|
||||
- 关键对象页
|
||||
- 扩展内容页
|
||||
- 局部重生成
|
||||
|
||||
目标:
|
||||
|
||||
- 让结果页真正成为创作工具,而不是人工补表页面
|
||||
|
||||
## 12. 一句话结论
|
||||
|
||||
当前自定义世界流程最需要优化的,不是“让 AI 再多生成一点内容”,而是:
|
||||
|
||||
**把创作者从低价值字段编辑里解放出来,让创作者负责世界灵魂锚点,让 AI 负责围绕这些锚点分层生成、分层展开、分层可控地把世界长出来。**
|
||||
@@ -0,0 +1,869 @@
|
||||
# AI 原生剧情引擎第一阶段技术落地方案
|
||||
|
||||
更新时间:`2026-04-06`
|
||||
|
||||
## 0. 文档目的
|
||||
|
||||
这份方案用于把以下三份 PRD 收束成当前仓库可直接开工的第一阶段技术实现方案:
|
||||
|
||||
- `docs/prd/AI_NATIVE_CROSS_GENRE_STORY_ENGINE_PRD_2026-04-06.md`
|
||||
- `docs/prd/AI_NATIVE_NARRATIVE_THREAD_ITEM_AND_WORLD_NPC_PRD_2026-04-06.md`
|
||||
- `docs/prd/AI_NATIVE_CLASSIC_RPG_EXPERIENCE_BENCHMARK_PRD_2026-04-06.md`
|
||||
|
||||
目标不是一次把“经典 RPG 体验”全部做完,而是在当前项目框架内先做出一个最小但完整的剧情引擎闭环,让后续可以继续往《仙剑》《轩辕剑》《古剑》《黑神话》《博德之门》所代表的体验能力上叠。
|
||||
|
||||
这份方案必须满足两个约束:
|
||||
|
||||
1. 不推翻当前仓库已有的 `customWorld / prompt / npcInteractions / questDirector / runtimeItem` 主链。
|
||||
2. 第一阶段做完后,玩家能立刻感知到内容质量提升,而不是只有内部结构更“先进”。
|
||||
|
||||
## 1. 第一阶段目标
|
||||
|
||||
第一阶段只做 4 件必须一起成立的事:
|
||||
|
||||
1. 给自定义世界补 `题材适配层 + 世界线程图谱 + 角色叙事档案`
|
||||
2. 给运行时 prompt 补 `信息可见性裁剪 + 情境导演最小指令`
|
||||
3. 给重点 NPC 补 `低好感也有戏` 的首遇表达与最小关系立场矩阵
|
||||
4. 给重点运行时物件补 `叙事指纹`,让名称、描述、来源真正开始承载故事
|
||||
|
||||
一句话定义第一阶段:
|
||||
|
||||
**先把“世界会说话、角色会藏话、物件会带话、prompt 不再全知”这四个基础能力接起来。**
|
||||
|
||||
## 2. 第一阶段完成定义
|
||||
|
||||
第一阶段完成后,必须同时满足下面这些结果:
|
||||
|
||||
1. 新生成的自定义世界,结构里会稳定带上 `ThemePack`、`WorldStoryGraph` 和 `ActorNarrativeProfile`。
|
||||
2. 自定义世界 NPC 在首遇或低披露阶段,不再把完整 `backstory` 与所有未解锁章节直接注入 prompt。
|
||||
3. 低初始好感 NPC 的首轮文本,会出现“当前压力 + 错位说辞 + 暗线钩子”,而不只是更冷淡。
|
||||
4. 稀有以上或重点奖励物件,会带 `storyFingerprint`,名称与描述不再只是 build 方向模板句。
|
||||
5. 旧存档和旧自定义世界数据仍能平滑读取,缺失字段有 fallback。
|
||||
6. 至少一条主链已经把“世界线程 -> 角色档案 -> 可见信息 -> 文本生成 -> 记忆回写”跑通。
|
||||
|
||||
## 3. 范围控制
|
||||
|
||||
## 3.1 第一阶段纳入范围
|
||||
|
||||
纳入范围的模块:
|
||||
|
||||
- `src/services/customWorld.ts`
|
||||
- `src/services/prompt.ts`
|
||||
- `src/data/npcInteractions.ts`
|
||||
- `src/hooks/useStoryGeneration.ts`
|
||||
- `src/services/questDirector.ts`
|
||||
- `src/services/runtimeItemAiPrompt.ts`
|
||||
- `src/data/runtimeItemNarrative.ts`
|
||||
- `src/types/customWorld.ts`
|
||||
- `src/types/game.ts`
|
||||
- `src/types/scene.ts`
|
||||
- `src/types/runtimeItem.ts`
|
||||
- `src/services/aiTypes.ts`
|
||||
|
||||
新增模块:
|
||||
|
||||
- `src/types/storyEngine.ts`
|
||||
- `src/services/storyEngine/themePack.ts`
|
||||
- `src/services/storyEngine/worldStoryGraph.ts`
|
||||
- `src/services/storyEngine/actorNarrativeProfile.ts`
|
||||
- `src/services/storyEngine/visibilityEngine.ts`
|
||||
- `src/services/storyEngine/sceneNarrativeDirector.ts`
|
||||
- `src/services/storyEngine/carrierNarrativeCompiler.ts`
|
||||
|
||||
## 3.2 第一阶段明确不做
|
||||
|
||||
以下内容留到第二阶段及以后,不放进本阶段:
|
||||
|
||||
1. 全量营地事件系统
|
||||
2. 队友 approval / disapproval 的完整 UI 面板
|
||||
3. 复杂多结局主线编排器
|
||||
4. 全题材内容包与人工词典大规模沉淀
|
||||
5. 所有叙事载体类型一次性接入
|
||||
6. 全支线线程化改造
|
||||
7. 复杂 scene residue 地图化编辑器
|
||||
|
||||
原因很简单:
|
||||
|
||||
**第一阶段的目标是把底层语法和最小闭环接通,而不是把所有经典 RPG 能力一次铺满。**
|
||||
|
||||
## 4. 第一阶段最小闭环
|
||||
|
||||
建议把第一阶段的最小闭环定义为:
|
||||
|
||||
```text
|
||||
自定义世界生成
|
||||
-> 题材适配层
|
||||
-> 世界线程图谱
|
||||
-> 角色叙事档案
|
||||
-> 遭遇时构造可见性切片
|
||||
-> 构造场景导演指令
|
||||
-> 生成首遇 / 对话 / 任务 / 物件叙事
|
||||
-> 回写最小剧情记忆
|
||||
```
|
||||
|
||||
这个闭环里,先只强接两个高价值落点:
|
||||
|
||||
1. 大世界 NPC 遭遇
|
||||
2. 运行时重点物件
|
||||
|
||||
原因:
|
||||
|
||||
- 这两条链最容易让玩家立刻感到“内容变得像经典 RPG 了”
|
||||
- 也最符合当前仓库已经有的主链结构
|
||||
|
||||
## 5. 数据结构落地方案
|
||||
|
||||
## 5.1 新增 `src/types/storyEngine.ts`
|
||||
|
||||
建议把第一阶段的引擎基础类型集中到一个新文件,避免继续把新语义散进已有 `story.ts`。
|
||||
|
||||
建议包含这些结构:
|
||||
|
||||
```ts
|
||||
export interface ThemePack {
|
||||
id: string;
|
||||
displayName: string;
|
||||
toneRange: string[];
|
||||
institutionLexicon: string[];
|
||||
tabooLexicon: string[];
|
||||
artifactClasses: string[];
|
||||
actorArchetypes: string[];
|
||||
conflictForms: string[];
|
||||
clueForms: string[];
|
||||
namingPatterns: string[];
|
||||
revealStyles: string[];
|
||||
}
|
||||
|
||||
export interface StoryThread {
|
||||
id: string;
|
||||
title: string;
|
||||
visibility: 'visible' | 'hidden';
|
||||
summary: string;
|
||||
conflictType: string;
|
||||
stakes: string;
|
||||
involvedFactionIds: string[];
|
||||
involvedActorIds: string[];
|
||||
relatedLocationIds: string[];
|
||||
}
|
||||
|
||||
export interface StoryScar {
|
||||
id: string;
|
||||
title: string;
|
||||
pastEvent: string;
|
||||
publicResidue: string;
|
||||
hiddenTruth: string;
|
||||
relatedActorIds: string[];
|
||||
relatedLocationIds: string[];
|
||||
}
|
||||
|
||||
export interface StoryMotif {
|
||||
id: string;
|
||||
label: string;
|
||||
semanticRole: string;
|
||||
lexicalHints: string[];
|
||||
}
|
||||
|
||||
export interface WorldStoryGraph {
|
||||
visibleThreads: StoryThread[];
|
||||
hiddenThreads: StoryThread[];
|
||||
scars: StoryScar[];
|
||||
motifs: StoryMotif[];
|
||||
}
|
||||
|
||||
export interface ActorNarrativeProfile {
|
||||
publicMask: string;
|
||||
firstContactMask: string;
|
||||
visibleLine: string;
|
||||
hiddenLine: string;
|
||||
contradiction: string;
|
||||
debtOrBurden: string;
|
||||
taboo: string;
|
||||
immediatePressure: string;
|
||||
relatedThreadIds: string[];
|
||||
relatedScarIds: string[];
|
||||
reactionHooks: string[];
|
||||
}
|
||||
|
||||
export interface VisibilitySlice {
|
||||
factIds: string[];
|
||||
sayableFactIds: string[];
|
||||
inferredFactIds: string[];
|
||||
forbiddenFactIds: string[];
|
||||
misdirectionHints: string[];
|
||||
}
|
||||
|
||||
export interface SceneNarrativeDirective {
|
||||
primaryPressure: string;
|
||||
activeThreadIds: string[];
|
||||
foregroundActorIds: string[];
|
||||
foregroundCarrierIds: string[];
|
||||
revealBudget: 'low' | 'medium' | 'high';
|
||||
emotionalCadence: 'tense' | 'curious' | 'hostile' | 'intimate' | 'tragic' | 'mysterious';
|
||||
}
|
||||
|
||||
export interface CarrierStoryFingerprint {
|
||||
visibleClue: string;
|
||||
witnessMark: string;
|
||||
unresolvedQuestion: string;
|
||||
currentAppearanceReason: string;
|
||||
relatedThreadIds: string[];
|
||||
relatedScarIds: string[];
|
||||
reactionHooks: string[];
|
||||
}
|
||||
|
||||
export interface CompanionStanceProfile {
|
||||
trust: number;
|
||||
warmth: number;
|
||||
ideologicalFit: number;
|
||||
fearOrGuard: number;
|
||||
loyalty: number;
|
||||
currentConflictTag?: string | null;
|
||||
recentApprovals: string[];
|
||||
recentDisapprovals: string[];
|
||||
}
|
||||
|
||||
export interface StoryEngineMemoryState {
|
||||
discoveredFactIds: string[];
|
||||
activeThreadIds: string[];
|
||||
resolvedScarIds: string[];
|
||||
recentCarrierIds: string[];
|
||||
}
|
||||
```
|
||||
|
||||
同时更新:
|
||||
|
||||
- `src/types.ts`
|
||||
|
||||
把 `storyEngine.ts` 导出。
|
||||
|
||||
## 5.2 扩展 `src/types/customWorld.ts`
|
||||
|
||||
扩展:
|
||||
|
||||
```ts
|
||||
interface CustomWorldRoleProfile {
|
||||
narrativeProfile?: ActorNarrativeProfile;
|
||||
}
|
||||
|
||||
interface CustomWorldProfile {
|
||||
themePack?: ThemePack | null;
|
||||
storyGraph?: WorldStoryGraph | null;
|
||||
}
|
||||
```
|
||||
|
||||
注意:
|
||||
|
||||
1. 这两个字段都要允许 `null` / 缺失
|
||||
2. `normalizeCustomWorldProfile(...)` 必须能从旧档案平滑补 fallback
|
||||
|
||||
## 5.3 扩展 `src/types/runtimeItem.ts`
|
||||
|
||||
扩展:
|
||||
|
||||
```ts
|
||||
interface RuntimeItemMetadata {
|
||||
storyFingerprint?: CarrierStoryFingerprint;
|
||||
}
|
||||
```
|
||||
|
||||
同时扩展 AI 意图:
|
||||
|
||||
```ts
|
||||
interface RuntimeItemAiIntent {
|
||||
visibleClue?: string;
|
||||
witnessMark?: string;
|
||||
unfinishedBusiness?: string;
|
||||
hiddenHook?: string;
|
||||
reactionHooks?: string[];
|
||||
namingPattern?: string;
|
||||
}
|
||||
```
|
||||
|
||||
## 5.4 扩展 `src/types/game.ts`
|
||||
|
||||
扩展:
|
||||
|
||||
```ts
|
||||
interface GameState {
|
||||
storyEngineMemory?: StoryEngineMemoryState;
|
||||
}
|
||||
```
|
||||
|
||||
用途:
|
||||
|
||||
1. 记录已发现事实
|
||||
2. 记录当前激活线程
|
||||
3. 记录已经回响过的旧伤
|
||||
4. 记录最近拿到的重点叙事载体
|
||||
|
||||
## 5.5 扩展 `src/types/scene.ts`
|
||||
|
||||
扩展:
|
||||
|
||||
```ts
|
||||
interface NpcPersistentState {
|
||||
stanceProfile?: CompanionStanceProfile;
|
||||
}
|
||||
|
||||
interface Encounter {
|
||||
narrativeProfile?: ActorNarrativeProfile;
|
||||
}
|
||||
|
||||
interface SceneNpc {
|
||||
narrativeProfile?: ActorNarrativeProfile;
|
||||
}
|
||||
```
|
||||
|
||||
注意:
|
||||
|
||||
- 这里的 `stanceProfile` 不只给已入队同伴使用,重点 NPC 也可以先共享这套结构
|
||||
|
||||
## 5.6 扩展 `src/services/aiTypes.ts`
|
||||
|
||||
给 `StoryGenerationContext` 增加:
|
||||
|
||||
```ts
|
||||
visibilitySlice?: VisibilitySlice | null;
|
||||
sceneNarrativeDirective?: SceneNarrativeDirective | null;
|
||||
encounterNarrativeProfile?: ActorNarrativeProfile | null;
|
||||
activeThreadIds?: string[] | null;
|
||||
```
|
||||
|
||||
给 `QuestGenerationContext` 增加:
|
||||
|
||||
```ts
|
||||
activeThreadIds?: string[] | null;
|
||||
issuerNarrativeProfile?: ActorNarrativeProfile | null;
|
||||
```
|
||||
|
||||
## 6. 模块实现方案
|
||||
|
||||
## 6.1 `src/services/storyEngine/themePack.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 根据 `customWorldProfile.templateWorldType`、`summary`、`tone` 生成题材适配层
|
||||
2. 如果是预设世界,也能提供内置默认 `ThemePack`
|
||||
3. 给后续命名、术语、禁忌词、物件类别提供统一词汇入口
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildThemePackFromWorldProfile(profile)
|
||||
resolveFallbackThemePack(worldType)
|
||||
```
|
||||
|
||||
本阶段要求:
|
||||
|
||||
- 先做 deterministic builder,不强依赖额外 LLM 调用
|
||||
|
||||
## 6.2 `src/services/storyEngine/worldStoryGraph.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 根据 `CustomWorldProfile` 现有字段生成或补全 `WorldStoryGraph`
|
||||
2. 先从 `majorFactions / coreConflicts / landmarks / storyNpcs` 抽图谱
|
||||
3. 缺失时允许走 LLM 辅助生成,但要有 deterministic fallback
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildFallbackWorldStoryGraph(profile, themePack)
|
||||
generateWorldStoryGraphWithAi(profile, themePack)
|
||||
normalizeWorldStoryGraph(value, fallback)
|
||||
```
|
||||
|
||||
本阶段要求:
|
||||
|
||||
- 默认必须可离线 fallback
|
||||
- 图谱生成失败不能阻塞整个自定义世界生成
|
||||
|
||||
## 6.3 `src/services/storyEngine/actorNarrativeProfile.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 从角色的 `description / backstory / motivation / relationshipHooks / tags / backstoryReveal`
|
||||
编译 `ActorNarrativeProfile`
|
||||
2. 缺失时给出 fallback
|
||||
3. 为 prompt 提供稳定的“首遇面具、当前压力、暗线钩子”
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildFallbackActorNarrativeProfile(role, graph)
|
||||
generateActorNarrativeProfileWithAi(role, graph, themePack)
|
||||
normalizeActorNarrativeProfile(value, fallback)
|
||||
```
|
||||
|
||||
## 6.4 `src/services/storyEngine/visibilityEngine.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 根据当前遭遇、好感、首遇状态、已解锁章节、故事记忆构造 `VisibilitySlice`
|
||||
2. 明确哪些事实:
|
||||
- 可以进入 prompt
|
||||
- 只能作为推测
|
||||
- 绝对不能进入本轮上下文
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildEncounterVisibilitySlice(params)
|
||||
buildQuestVisibilitySlice(params)
|
||||
buildCarrierVisibilitySlice(params)
|
||||
```
|
||||
|
||||
本阶段关键约束:
|
||||
|
||||
1. 自定义世界 NPC 首遇时禁止注入完整 `backstory`
|
||||
2. 未解锁章节禁止注入 `content`
|
||||
3. 低披露阶段允许注入:
|
||||
- `publicMask`
|
||||
- `firstContactMask`
|
||||
- `visibleLine`
|
||||
- `immediatePressure`
|
||||
- 已解锁章节的 `contextSnippet`
|
||||
|
||||
## 6.5 `src/services/storyEngine/sceneNarrativeDirector.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 用当前场景、遭遇、最近行动、激活线程构造 `SceneNarrativeDirective`
|
||||
2. 告诉 prompt 本轮更应该强调:
|
||||
- 紧张
|
||||
- 试探
|
||||
- 情感深化
|
||||
- 揭示
|
||||
- 悬念
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildSceneNarrativeDirective(params)
|
||||
```
|
||||
|
||||
本阶段先做 local director,不新增额外 LLM 调用。
|
||||
|
||||
## 6.6 `src/services/storyEngine/carrierNarrativeCompiler.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 根据 `WorldStoryGraph + relationAnchor + scene + actorNarrativeProfile`
|
||||
编译 `CarrierStoryFingerprint`
|
||||
2. 给运行时重点物件提供:
|
||||
- 可见线索
|
||||
- 见证痕
|
||||
- 未完成问题
|
||||
- 当前出现理由
|
||||
- 后续反应钩子
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildRuntimeItemStoryFingerprint(params)
|
||||
buildCarrierNarrativeName(params)
|
||||
buildCarrierNarrativeDescription(params)
|
||||
```
|
||||
|
||||
## 7. 现有文件改造方案
|
||||
|
||||
## 7.1 `src/services/customWorld.ts`
|
||||
|
||||
当前问题:
|
||||
|
||||
1. 角色生成偏设定卡
|
||||
2. 没有先产题材适配层与世界线程图谱
|
||||
3. 角色背景和章节没有统一挂到世界线程上
|
||||
|
||||
改造方案:
|
||||
|
||||
1. 保留现有多阶段生成结构
|
||||
2. 插入两个新阶段:
|
||||
- `theme_pack_and_story_graph`
|
||||
- `actor_narrative_profile`
|
||||
3. 最终输出时把:
|
||||
- `themePack`
|
||||
- `storyGraph`
|
||||
- 每个 NPC 的 `narrativeProfile`
|
||||
写回 `CustomWorldProfile`
|
||||
|
||||
建议新的顺序:
|
||||
|
||||
1. 世界基础框架
|
||||
2. ThemePack
|
||||
3. WorldStoryGraph
|
||||
4. 角色基础字段
|
||||
5. ActorNarrativeProfile
|
||||
6. backstoryReveal / skills / initialItems
|
||||
|
||||
## 7.2 `src/services/prompt.ts`
|
||||
|
||||
这是第一阶段必须重点改的文件。
|
||||
|
||||
当前问题已经确认:
|
||||
|
||||
1. 自定义世界 NPC 遭遇会直接注入完整 `backstory`
|
||||
2. 会直接注入所有章节摘要
|
||||
3. `describeCustomWorldSection(...)` 会整体塞入太多 NPC 全量信息
|
||||
|
||||
改造方案:
|
||||
|
||||
1. 所有自定义世界 NPC prompt 统一先经过 `buildEncounterVisibilitySlice(...)`
|
||||
2. 只允许读取 `visibilitySlice` 输出的事实
|
||||
3. `describeCustomWorldSection(...)` 改成只注入:
|
||||
- 世界摘要
|
||||
- ThemePack 摘要
|
||||
- StoryGraph 激活线程摘要
|
||||
- 当前相关 NPC 的公开面与线程索引
|
||||
|
||||
禁止继续注入:
|
||||
|
||||
1. 完整 `backstory`
|
||||
2. 未解锁 `backstoryReveal.content`
|
||||
3. 多角色全量技能、初始物品、完整背景
|
||||
|
||||
## 7.3 `src/data/npcInteractions.ts`
|
||||
|
||||
改造目标:
|
||||
|
||||
1. 低好感角色从“更冷”改成“更有压力和错位”
|
||||
2. 接入最小 `stanceProfile`
|
||||
|
||||
建议新增:
|
||||
|
||||
```ts
|
||||
buildInitialStanceProfile(...)
|
||||
applyStoryChoiceToStanceProfile(...)
|
||||
describeNpcNarrativePressure(...)
|
||||
```
|
||||
|
||||
本阶段只接这些行为的 stance 更新:
|
||||
|
||||
1. `npc_chat`
|
||||
2. `npc_help`
|
||||
3. `npc_gift`
|
||||
4. `npc_recruit`
|
||||
5. `npc_quest_accept`
|
||||
|
||||
先不做完整 approval UI,只做:
|
||||
|
||||
- 内部状态更新
|
||||
- prompt 注入差异
|
||||
- 文本反应差异
|
||||
|
||||
## 7.4 `src/hooks/useStoryGeneration.ts`
|
||||
|
||||
当前不要再往里塞更多内容逻辑,而是让它接新引擎组件。
|
||||
|
||||
改造方式:
|
||||
|
||||
1. 构造 `visibilitySlice`
|
||||
2. 构造 `sceneNarrativeDirective`
|
||||
3. 把这两者透传给 `generateInitialStory / generateNextStep`
|
||||
4. 在回合结束时回写:
|
||||
- `storyEngineMemory`
|
||||
- `revealedFactIds`
|
||||
- 最近激活线程
|
||||
|
||||
它在第一阶段里只做 orchestration,不承担新的叙事规则实现。
|
||||
|
||||
## 7.5 `src/services/questDirector.ts`
|
||||
|
||||
当前它已经有:
|
||||
|
||||
- AI intent
|
||||
- fallback builder
|
||||
- compile to quest
|
||||
|
||||
第一阶段只补最小 thread awareness,不把整个任务系统完全重做。
|
||||
|
||||
改造方式:
|
||||
|
||||
1. `QuestGenerationContext` 增加:
|
||||
- `activeThreadIds`
|
||||
- `issuerNarrativeProfile`
|
||||
2. `buildQuestIntentPrompt(...)` 增加:
|
||||
- 当前激活线程
|
||||
- NPC 当前压力
|
||||
- 可披露线索
|
||||
|
||||
本阶段不改:
|
||||
|
||||
- `QuestLogEntry` 主结构
|
||||
- `questFlow.ts` 主编译方式
|
||||
|
||||
## 7.6 `src/services/runtimeItemAiPrompt.ts`
|
||||
|
||||
扩展当前物品意图 contract,但不让它直接生成成品。
|
||||
|
||||
新增字段:
|
||||
|
||||
1. `visibleClue`
|
||||
2. `witnessMark`
|
||||
3. `unfinishedBusiness`
|
||||
4. `hiddenHook`
|
||||
5. `reactionHooks`
|
||||
6. `namingPattern`
|
||||
|
||||
要求模型回答:
|
||||
|
||||
1. 这件物到底见证过什么
|
||||
2. 它为什么现在出现
|
||||
3. 谁以后会对它起反应
|
||||
|
||||
## 7.7 `src/data/runtimeItemNarrative.ts`
|
||||
|
||||
这是第一阶段另一个必须重点改的文件。
|
||||
|
||||
当前问题:
|
||||
|
||||
1. 名称偏词块拼接
|
||||
2. 描述偏单模板句
|
||||
|
||||
改造方案:
|
||||
|
||||
1. 先从 `CarrierStoryFingerprint` 编译名称
|
||||
2. 描述固定升级成三层式:
|
||||
- 表面痕迹
|
||||
- 旧事牵连
|
||||
- 当前局势意义
|
||||
3. `sourceReason` 继续保留,但不再是描述的全部中心
|
||||
|
||||
## 8. Prompt Contract 方案
|
||||
|
||||
## 8.1 自定义世界生成新增 contract
|
||||
|
||||
### 1. ThemePack Contract
|
||||
|
||||
输入:
|
||||
|
||||
- 世界 summary
|
||||
- tone
|
||||
- templateWorldType
|
||||
- factions
|
||||
- coreConflicts
|
||||
|
||||
输出:
|
||||
|
||||
- 题材词汇
|
||||
- 冲突形式
|
||||
- 载体种类
|
||||
- 命名范式
|
||||
|
||||
### 2. WorldStoryGraph Contract
|
||||
|
||||
输入:
|
||||
|
||||
- 世界摘要
|
||||
- major factions
|
||||
- core conflicts
|
||||
- landmarks
|
||||
- story NPC 简要清单
|
||||
|
||||
输出:
|
||||
|
||||
- `visibleThreads`
|
||||
- `hiddenThreads`
|
||||
- `scars`
|
||||
- `motifs`
|
||||
|
||||
### 3. ActorNarrativeProfile Contract
|
||||
|
||||
输入:
|
||||
|
||||
- 角色基础字段
|
||||
- 角色 `backstoryReveal`
|
||||
- 所属世界线程摘要
|
||||
|
||||
输出:
|
||||
|
||||
- `publicMask`
|
||||
- `firstContactMask`
|
||||
- `visibleLine`
|
||||
- `hiddenLine`
|
||||
- `contradiction`
|
||||
- `debtOrBurden`
|
||||
- `taboo`
|
||||
- `immediatePressure`
|
||||
- `reactionHooks`
|
||||
|
||||
## 8.2 运行时剧情生成 contract
|
||||
|
||||
运行时主 prompt 不再直接吃全量世界设定,而是吃:
|
||||
|
||||
1. `SceneNarrativeDirective`
|
||||
2. `VisibilitySlice`
|
||||
3. 当前遭遇公开信息
|
||||
4. 已解锁章节摘要
|
||||
5. 当前激活线程
|
||||
|
||||
## 8.3 运行时物件 contract
|
||||
|
||||
输入:
|
||||
|
||||
- 生成渠道
|
||||
- 关系锚点
|
||||
- 当前场景
|
||||
- 当前激活线程
|
||||
- 相关角色公开面与当前压力
|
||||
|
||||
输出:
|
||||
|
||||
- 物件叙事指纹字段
|
||||
- 命名范式建议
|
||||
- build 倾向字段
|
||||
|
||||
## 9. 迁移与兼容方案
|
||||
|
||||
## 9.1 旧自定义世界兼容
|
||||
|
||||
旧数据可能没有:
|
||||
|
||||
- `themePack`
|
||||
- `storyGraph`
|
||||
- `narrativeProfile`
|
||||
|
||||
策略:
|
||||
|
||||
1. 读取时用 `normalizeCustomWorldProfile(...)` 自动补 fallback
|
||||
2. fallback 不阻塞运行时
|
||||
3. 下次保存时按新结构写回
|
||||
|
||||
## 9.2 旧存档兼容
|
||||
|
||||
旧存档可能没有:
|
||||
|
||||
- `storyEngineMemory`
|
||||
- `stanceProfile`
|
||||
- `storyFingerprint`
|
||||
|
||||
策略:
|
||||
|
||||
1. `GameState` 初始化时补空结构
|
||||
2. `NpcPersistentState` 初始化时补最小 stance
|
||||
3. 旧物品没有 `storyFingerprint` 时,不报错,走旧描述逻辑 fallback
|
||||
|
||||
## 10. 测试方案
|
||||
|
||||
## 10.1 单元测试
|
||||
|
||||
建议新增:
|
||||
|
||||
1. `visibilityEngine.test.ts`
|
||||
- 验证首遇和低披露阶段不会泄露完整背景
|
||||
|
||||
2. `worldStoryGraph.test.ts`
|
||||
- 验证 fallback 图谱最少字段齐全
|
||||
|
||||
3. `actorNarrativeProfile.test.ts`
|
||||
- 验证 fallback profile 至少包含压力、错位、钩子
|
||||
|
||||
4. `carrierNarrativeCompiler.test.ts`
|
||||
- 验证重点物件能稳定产出指纹、名称和三层描述
|
||||
|
||||
## 10.2 集成测试
|
||||
|
||||
建议补这些集成检查:
|
||||
|
||||
1. 自定义世界生成后,`CustomWorldProfile.storyGraph` 与 `narrativeProfile` 存在
|
||||
2. `prompt.ts` 在首遇自定义世界 NPC 时不含完整 `backstory`
|
||||
3. `runtimeItemNarrative.ts` 重点物件输出包含故事指纹与升级描述
|
||||
4. `questDirector.ts` 任务上下文已经能读取线程与角色叙事档案
|
||||
|
||||
## 10.3 手工验证场景
|
||||
|
||||
至少做这 4 条人工回归:
|
||||
|
||||
1. 初见低好感 NPC
|
||||
2. 初见中高好感 NPC
|
||||
3. 拿到 rare 级重点物件
|
||||
4. 从某 NPC 处接到调查或关系类任务
|
||||
|
||||
## 11. 交付顺序
|
||||
|
||||
建议按下面顺序做,避免返工:
|
||||
|
||||
1. 类型与 fallback
|
||||
- `storyEngine.ts`
|
||||
- 现有类型扩展
|
||||
- 旧档兼容
|
||||
|
||||
2. 自定义世界生成链
|
||||
- `themePack`
|
||||
- `worldStoryGraph`
|
||||
- `actorNarrativeProfile`
|
||||
|
||||
3. prompt 可见性层
|
||||
- `visibilityEngine`
|
||||
- `prompt.ts` 裁剪
|
||||
- `useStoryGeneration.ts` 接线
|
||||
|
||||
4. NPC 首遇和 stance 最小链
|
||||
- `npcInteractions.ts`
|
||||
- `StoryGenerationContext` 注入
|
||||
|
||||
5. 重点物件叙事链
|
||||
- `runtimeItemAiPrompt.ts`
|
||||
- `carrierNarrativeCompiler.ts`
|
||||
- `runtimeItemNarrative.ts`
|
||||
|
||||
6. 任务线程感知最小接入
|
||||
- `questDirector.ts`
|
||||
|
||||
7. 测试与内容回归
|
||||
|
||||
## 12. 风险与处理
|
||||
|
||||
## 风险 1:阶段过大
|
||||
|
||||
处理:
|
||||
|
||||
- 第一阶段只强接 NPC 与重点物件两条链
|
||||
- 营地事件、全支线线程化后置
|
||||
|
||||
## 风险 2:prompt 体积继续膨胀
|
||||
|
||||
处理:
|
||||
|
||||
- 先做 `VisibilitySlice`
|
||||
- 严禁继续直接注入全量背景
|
||||
|
||||
## 风险 3:旧档与旧内容不兼容
|
||||
|
||||
处理:
|
||||
|
||||
- 所有新增字段必须有 normalize fallback
|
||||
- 第一阶段不删除旧字段
|
||||
|
||||
## 风险 4:AI 输出不稳定
|
||||
|
||||
处理:
|
||||
|
||||
- 所有新 contract 都必须配 deterministic fallback builder
|
||||
- AI 只产意图,不直接产运行时成品
|
||||
|
||||
## 13. 第一阶段验收清单
|
||||
|
||||
做到以下几点,才算第一阶段可收口:
|
||||
|
||||
1. 新生成自定义世界可稳定带出 `ThemePack + WorldStoryGraph + ActorNarrativeProfile`
|
||||
2. 首遇自定义世界 NPC 时,prompt 中不再包含完整 `backstory`
|
||||
3. 低好感 NPC 首轮文本能显著表现“压力、错位、钩子”
|
||||
4. 稀有以上重点物件会稳定带出 `storyFingerprint`
|
||||
5. 重点物件名称与描述不再只依赖固定模板句
|
||||
6. 任务生成至少能读取激活线程和 NPC 当前叙事压力
|
||||
7. 旧档读取正常
|
||||
8. `lint / 相关测试 / check:encoding` 通过
|
||||
|
||||
## 14. 一句话结论
|
||||
|
||||
第一阶段不要追求“立刻做出所有经典 RPG 体验”,而要先把:
|
||||
|
||||
- 世界线程
|
||||
- 角色叙事档案
|
||||
- 信息可见性
|
||||
- 重点物件叙事指纹
|
||||
|
||||
这四个底座接进当前仓库主链。
|
||||
|
||||
只要这一步做稳,后面无论是《仙剑》式角色关系、《轩辕剑》式历史神话、《古剑》式世界厚度、《黑神话》式空间残痕,还是《博德之门》式队友反应,都会开始有一个真正可持续生长的引擎底盘。
|
||||
@@ -0,0 +1,644 @@
|
||||
# AI 原生剧情引擎第二阶段技术落地方案
|
||||
|
||||
更新时间:`2026-04-06`
|
||||
|
||||
## 0. 文档目的
|
||||
|
||||
这份方案建立在当前仓库已经基本完成的第一阶段能力之上,面向第二阶段的真实技术推进。
|
||||
|
||||
第一阶段已经把这些底座接进主链:
|
||||
|
||||
1. `ThemePack`
|
||||
2. `WorldStoryGraph`
|
||||
3. `ActorNarrativeProfile`
|
||||
4. `VisibilitySlice`
|
||||
5. `SceneNarrativeDirective`
|
||||
6. `CarrierStoryFingerprint`
|
||||
7. `storyEngineMemory`
|
||||
|
||||
同时也已经把这些链打通了:
|
||||
|
||||
1. 自定义世界扩展构建链
|
||||
2. 自定义世界 NPC 首遇 prompt 裁剪
|
||||
3. 运行时重点物件叙事编译
|
||||
4. 任务 prompt 的最小线程感知
|
||||
5. NPC 最小 stance 更新
|
||||
|
||||
第二阶段不再解决“底座有没有”,而是解决:
|
||||
|
||||
**这些底座如何从“静态骨架 + deterministic fallback”升级成“真正能持续驱动经典 RPG 体验的动态剧情引擎”。**
|
||||
|
||||
## 1. 第一阶段审计结论
|
||||
|
||||
先明确当前真实状态,再定义第二阶段范围。
|
||||
|
||||
## 1.1 已经落地的部分
|
||||
|
||||
按代码审计结果,以下内容已经可以判定为“已落地”:
|
||||
|
||||
1. 类型层已接入
|
||||
- `src/types/storyEngine.ts`
|
||||
- `src/types/customWorld.ts`
|
||||
- `src/types/game.ts`
|
||||
- `src/types/runtimeItem.ts`
|
||||
- `src/types/scene.ts`
|
||||
- `src/services/aiTypes.ts`
|
||||
|
||||
2. 自定义世界扩展构建已接入
|
||||
- `src/services/customWorldBuilder.ts`
|
||||
- `src/services/customWorld.ts`
|
||||
|
||||
3. Prompt 可见性裁剪已接入主链
|
||||
- `src/services/prompt.ts`
|
||||
- `src/hooks/useStoryGeneration.ts`
|
||||
|
||||
4. 重点物件叙事指纹已接入主链
|
||||
- `src/services/storyEngine/carrierNarrativeCompiler.ts`
|
||||
- `src/data/runtimeItemNarrative.ts`
|
||||
|
||||
5. 最小记忆回写已接入
|
||||
- `src/hooks/story/progressionActions.ts`
|
||||
- `src/services/storyEngine/echoMemory.ts`
|
||||
|
||||
6. 第一阶段关键测试已通过
|
||||
- `prompt.test.ts`
|
||||
- `customWorldBuilder.test.ts`
|
||||
- `visibilityEngine.test.ts`
|
||||
- `carrierNarrativeCompiler.test.ts`
|
||||
- `runtimeItemDirector.test.ts`
|
||||
- `npcInteractions.test.ts`
|
||||
|
||||
7. 工程门禁本轮检查通过
|
||||
- `lint`
|
||||
- `typecheck`
|
||||
- `check:encoding`
|
||||
|
||||
## 1.2 仍然属于“部分落地”的部分
|
||||
|
||||
以下能力虽然已经有骨架,但还没达到第二阶段想要的经典 RPG 体验强度:
|
||||
|
||||
1. `WorldStoryGraph`
|
||||
- 当前主要仍是 fallback 构建,AI 版本还是 stub。
|
||||
|
||||
2. `ActorNarrativeProfile`
|
||||
- 当前主要仍是 fallback 编译,AI 版本还是 stub。
|
||||
|
||||
3. `CompanionStanceProfile`
|
||||
- 当前只覆盖局部 NPC 行为,不覆盖全局选择反馈、队友插话、营地事件。
|
||||
|
||||
4. `storyEngineMemory`
|
||||
- 当前已经回写,但消费端还很弱,回响还没有真正反过来改变世界表达。
|
||||
|
||||
5. `QuestDirector`
|
||||
- 当前已经有线程感知,但任务本体还没有成为“线程合约”的实体。
|
||||
|
||||
6. `CarrierStoryFingerprint`
|
||||
- 当前只强接运行时物件,还没扩到地点残痕、文书、证物、怪物掉落情报、场景调查结果。
|
||||
|
||||
## 1.3 当前进入第二阶段前,最值得注意的两个真实缺口
|
||||
|
||||
### 缺口 A:AI 版世界线程 / 角色档案生成仍未真正接管主链
|
||||
|
||||
当前代码里虽然已经有:
|
||||
|
||||
- `generateWorldStoryGraphWithAi(...)`
|
||||
- `generateActorNarrativeProfileWithAi(...)`
|
||||
|
||||
但它们还只是 fallback 包装,本质上没有真的调用独立 AI contract。
|
||||
|
||||
这意味着:
|
||||
|
||||
- 当前世界线程和角色叙事档案仍偏“本地启发式编译”
|
||||
- 第一阶段解决了“结构没有”的问题
|
||||
- 但还没有真正进入“AI 原生世界叙事图谱”阶段
|
||||
|
||||
### 缺口 B:可见性虽然裁掉了完整背景,但隐式泄露仍未完全收紧
|
||||
|
||||
当前 `prompt.ts` 里,对自定义世界 NPC 的:
|
||||
|
||||
- `relationshipHooks`
|
||||
- `tags`
|
||||
|
||||
仍是无条件注入。
|
||||
|
||||
如果这些字段本身带有暗线名词、组织名、旧案对象名,那么:
|
||||
|
||||
- 首遇阶段仍有隐式越权泄露的风险
|
||||
|
||||
这说明第二阶段必须把“知识图谱”和“可见性切片”的颗粒度继续做细,不能只停留在章节级裁剪。
|
||||
|
||||
## 2. 第二阶段目标
|
||||
|
||||
第二阶段只做 5 件事:
|
||||
|
||||
1. 把世界线程和角色叙事档案从 fallback 编译升级成真正的 AI contract 驱动
|
||||
2. 把 `VisibilitySlice` 升级成可追踪的 `KnowledgeFact` 图谱
|
||||
3. 把 `CompanionStanceProfile` 从局部 NPC 状态升级成队友反应系统
|
||||
4. 把 `QuestDirector` 从“知道线程”升级成“线程合约推进器”
|
||||
5. 把叙事载体从“重点物件”扩展成“物件 + 地点 + 文书 + 调查残痕”
|
||||
|
||||
一句话定义第二阶段:
|
||||
|
||||
**从“会组织故事骨架”升级到“会持续推进、反馈、回响和分化故事”。**
|
||||
|
||||
## 3. 第二阶段完成定义
|
||||
|
||||
第二阶段完成后,必须同时满足:
|
||||
|
||||
1. 自定义世界的 `ThemePack / WorldStoryGraph / ActorNarrativeProfile` 至少核心部分由独立 AI contract 生成,而不再只是 fallback。
|
||||
2. 世界中的“事实”被显式建模成可发现、可说、可误判、可禁止的 `KnowledgeFact`。
|
||||
3. 队友会对关键选择给出稳定的认可 / 反对 / 沉默 / 紧张回避反馈。
|
||||
4. 至少一类任务已经真正挂在 `StoryThread` 上推进,并能根据 `signal` 更新阶段。
|
||||
5. 玩家获得重点物件、调查地点或读取文书后,后续 NPC 和剧情会产生回响。
|
||||
6. “经典 RPG 感”开始明显来自系统联动,而不只是单次文本质量提升。
|
||||
|
||||
## 4. 第二阶段范围
|
||||
|
||||
## 4.1 纳入范围
|
||||
|
||||
- `src/services/customWorld.ts`
|
||||
- `src/services/customWorldBuilder.ts`
|
||||
- `src/services/prompt.ts`
|
||||
- `src/services/questDirector.ts`
|
||||
- `src/services/questPrompt.ts`
|
||||
- `src/data/questFlow.ts`
|
||||
- `src/data/npcInteractions.ts`
|
||||
- `src/hooks/useStoryGeneration.ts`
|
||||
- `src/hooks/story/npcEncounterActions.ts`
|
||||
- `src/hooks/story/npcInteraction.ts`
|
||||
- `src/services/storyEngine/*`
|
||||
- `src/types/storyEngine.ts`
|
||||
- `src/types/story.ts`
|
||||
|
||||
## 4.2 新增模块
|
||||
|
||||
- `src/services/storyEngine/knowledgeGraph.ts`
|
||||
- `src/services/storyEngine/knowledgeContract.ts`
|
||||
- `src/services/storyEngine/companionReactionDirector.ts`
|
||||
- `src/services/storyEngine/threadContract.ts`
|
||||
- `src/services/storyEngine/threadSignalRouter.ts`
|
||||
- `src/services/storyEngine/sceneResidueCompiler.ts`
|
||||
- `src/services/storyEngine/narrativeCarrierCatalog.ts`
|
||||
|
||||
## 4.3 明确不做
|
||||
|
||||
第二阶段仍不做:
|
||||
|
||||
1. 全量结局树编辑器
|
||||
2. 全世界所有对象统一入图谱编辑器
|
||||
3. 多周目专用 meta-story 系统
|
||||
4. 完整 romance / betrayal / leave-party 大型队友事件网
|
||||
5. 全 UI 层 approval feed 面板
|
||||
|
||||
原因:
|
||||
|
||||
第二阶段的核心仍是“让引擎开始动态驱动经典 RPG 体验”,而不是做内容工具大平台。
|
||||
|
||||
## 5. 第二阶段最小闭环
|
||||
|
||||
建议第二阶段最小闭环定义为:
|
||||
|
||||
```text
|
||||
世界图谱 AI 生成
|
||||
-> 角色叙事档案 AI 生成
|
||||
-> KnowledgeFact 图谱
|
||||
-> VisibilitySlice 2.0
|
||||
-> 队友反应导演
|
||||
-> 线程合约生成
|
||||
-> signal 推进
|
||||
-> 地点/文书/物件回响
|
||||
-> 记忆回写
|
||||
```
|
||||
|
||||
本阶段最关键的用户可感知落点有 3 条:
|
||||
|
||||
1. 队友 / 同伴反应链
|
||||
2. 调查 / 任务推进链
|
||||
3. 地点 / 物件 / 文书残痕链
|
||||
|
||||
## 6. 数据结构升级方案
|
||||
|
||||
## 6.1 `src/types/storyEngine.ts`
|
||||
|
||||
第二阶段新增:
|
||||
|
||||
```ts
|
||||
export interface KnowledgeFact {
|
||||
id: string;
|
||||
title: string;
|
||||
content: string;
|
||||
ownerActorIds: string[];
|
||||
relatedThreadIds: string[];
|
||||
relatedScarIds: string[];
|
||||
sourceType: 'actor' | 'item' | 'document' | 'scene' | 'monster' | 'quest';
|
||||
visibility: 'public' | 'discoverable' | 'private' | 'forbidden';
|
||||
sayability: 'direct' | 'indirect' | 'reactive_only';
|
||||
aliases?: string[];
|
||||
}
|
||||
|
||||
export interface ThreadContractStep {
|
||||
id: string;
|
||||
title: string;
|
||||
revealText: string;
|
||||
completionSignalIds: string[];
|
||||
optionalFactIds: string[];
|
||||
}
|
||||
|
||||
export interface ThreadContract {
|
||||
id: string;
|
||||
threadId: string;
|
||||
issuerActorId?: string | null;
|
||||
narrativeType: 'investigation' | 'escort' | 'hunt' | 'relationship' | 'trial' | 'recovery';
|
||||
currentStepId: string | null;
|
||||
visibleStage: number;
|
||||
steps: ThreadContractStep[];
|
||||
followupThreadIds: string[];
|
||||
}
|
||||
|
||||
export interface StorySignal {
|
||||
id: string;
|
||||
signalType:
|
||||
| 'enter_scene'
|
||||
| 'leave_scene'
|
||||
| 'talk_to_actor'
|
||||
| 'obtain_carrier'
|
||||
| 'inspect_scene'
|
||||
| 'win_battle'
|
||||
| 'give_item'
|
||||
| 'accept_contract'
|
||||
| 'resolve_contract_step';
|
||||
actorId?: string | null;
|
||||
sceneId?: string | null;
|
||||
carrierId?: string | null;
|
||||
threadIds?: string[];
|
||||
}
|
||||
|
||||
export interface CompanionReactionRecord {
|
||||
id: string;
|
||||
characterId: string;
|
||||
reactionType: 'approve' | 'disapprove' | 'concern' | 'silence' | 'curious';
|
||||
reason: string;
|
||||
relatedThreadIds: string[];
|
||||
createdAt: string;
|
||||
}
|
||||
```
|
||||
|
||||
并扩展:
|
||||
|
||||
```ts
|
||||
export interface StoryEngineMemoryState {
|
||||
discoveredFactIds: string[];
|
||||
inferredFactIds?: string[];
|
||||
activeThreadIds: string[];
|
||||
resolvedScarIds: string[];
|
||||
recentCarrierIds: string[];
|
||||
recentSignalIds?: string[];
|
||||
recentCompanionReactions?: CompanionReactionRecord[];
|
||||
}
|
||||
```
|
||||
|
||||
## 6.2 `src/types/story.ts`
|
||||
|
||||
第二阶段建议扩展任务结构,而不是直接新起平行系统。
|
||||
|
||||
扩展:
|
||||
|
||||
```ts
|
||||
interface QuestLogEntry {
|
||||
threadId?: string | null;
|
||||
contractId?: string | null;
|
||||
discoveredFactIds?: string[];
|
||||
relatedCarrierIds?: string[];
|
||||
}
|
||||
```
|
||||
|
||||
注意:
|
||||
|
||||
- 第二阶段仍继续复用 `QuestLogEntry`
|
||||
- 不推翻当前任务系统,只增强其线程感知和推进能力
|
||||
|
||||
## 6.3 `src/types/scene.ts`
|
||||
|
||||
扩展:
|
||||
|
||||
```ts
|
||||
interface ScenePresetInfo {
|
||||
narrativeResidues?: SceneNarrativeResidue[];
|
||||
}
|
||||
|
||||
interface SceneNarrativeResidue {
|
||||
id: string;
|
||||
title: string;
|
||||
visibleClue: string;
|
||||
linkedFactIds: string[];
|
||||
linkedThreadIds: string[];
|
||||
}
|
||||
```
|
||||
|
||||
## 7. 模块实现方案
|
||||
|
||||
## 7.1 `knowledgeGraph.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 从 `WorldStoryGraph + ActorNarrativeProfile + backstoryReveal + carriers`
|
||||
编译出全局 `KnowledgeFact[]`
|
||||
2. 统一管理:
|
||||
- 事实 ID
|
||||
- 所属角色
|
||||
- 所属线程
|
||||
- 是否可直说
|
||||
- 是否只能反应式表达
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildKnowledgeGraph(profile)
|
||||
buildActorKnowledgeFacts(role, graph)
|
||||
buildCarrierKnowledgeFacts(carrier, graph)
|
||||
```
|
||||
|
||||
第二阶段关键要求:
|
||||
|
||||
- `VisibilitySlice` 不再只靠字符串标签推断
|
||||
- 必须能落到真实事实节点
|
||||
|
||||
## 7.2 `knowledgeContract.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 用 `KnowledgeFact` 构造 `VisibilitySlice 2.0`
|
||||
2. 支持:
|
||||
- 可直接说的事实
|
||||
- 只能暗示的事实
|
||||
- 只会在反应中暴露的事实
|
||||
- 玩家已经误判但系统不盖章的事实
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildVisibilitySliceFromFacts(params)
|
||||
buildMisdirectionFacts(params)
|
||||
```
|
||||
|
||||
## 7.3 `companionReactionDirector.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 根据玩家选择、活跃线程、事实图谱、队友 stance 生成队友反应
|
||||
2. 把当前只存在于 `stanceProfile` 内的数值,变成:
|
||||
- 明确的认可 / 反对 / 担忧 / 沉默
|
||||
- 可写入聊天、插话、任务后反馈的短反应
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildCompanionReactionBatch(params)
|
||||
applyCompanionReactionToStance(params)
|
||||
```
|
||||
|
||||
第二阶段要求:
|
||||
|
||||
1. 至少支持关键选择后队友短反应
|
||||
2. 至少支持营地或旅途中一次补充评价
|
||||
|
||||
## 7.4 `threadContract.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 把 `StoryThread` 编译成可推进的 `ThreadContract`
|
||||
2. 为调查、关系、试炼、追索等线程提供稳定步骤结构
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildThreadContract(params)
|
||||
compileQuestFromThreadContract(params)
|
||||
```
|
||||
|
||||
第二阶段目标:
|
||||
|
||||
- 不是重做任务系统
|
||||
- 而是让任务成为线程推进器的一种表现
|
||||
|
||||
## 7.5 `threadSignalRouter.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 接收运行时 signal
|
||||
2. 判断哪些线程、哪些合约步骤应该推进
|
||||
3. 触发:
|
||||
- 任务步骤完成
|
||||
- 新事实解锁
|
||||
- 队友反应
|
||||
- 新残痕 / 新物件回响
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
collectStorySignals(params)
|
||||
resolveSignalsToThreadUpdates(params)
|
||||
```
|
||||
|
||||
## 7.6 `sceneResidueCompiler.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 给场景和调查结果补 `narrativeResidues`
|
||||
2. 让场景本身开始承担《黑神话》《古剑》式残痕叙事
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildSceneNarrativeResidues(params)
|
||||
buildResidueInspectResult(params)
|
||||
```
|
||||
|
||||
第二阶段要求:
|
||||
|
||||
1. 至少在自定义世界 landmark 上生成残痕
|
||||
2. 至少能在“观察痕迹 / inspect / observe_signs”时读出来
|
||||
|
||||
## 7.7 `narrativeCarrierCatalog.ts`
|
||||
|
||||
职责:
|
||||
|
||||
把当前只覆盖 `InventoryItem` 的载体,扩成统一的叙事载体目录:
|
||||
|
||||
1. 物件
|
||||
2. 文书
|
||||
3. 场景残痕
|
||||
4. 怪物特殊掉落情报
|
||||
5. 任务证据
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildNarrativeCarrierCatalog(state)
|
||||
resolveCarrierById(id)
|
||||
```
|
||||
|
||||
## 8. 现有文件改造方案
|
||||
|
||||
## 8.1 `src/services/customWorld.ts`
|
||||
|
||||
第二阶段要做的,不是继续堆 fallback,而是把 AI contract 真正接进生成链。
|
||||
|
||||
改造目标:
|
||||
|
||||
1. `ThemePack` 允许 AI 细化词汇与命名模式
|
||||
2. `WorldStoryGraph` 允许 AI 生成更像世界主线 / 暗线的线程图谱
|
||||
3. `ActorNarrativeProfile` 允许 AI 生成更有作者性的角色命题与错位感
|
||||
|
||||
要求:
|
||||
|
||||
- 仍保留 fallback
|
||||
- AI 失败时不阻塞生成
|
||||
- AI 成功时优先写入结构化结果
|
||||
|
||||
## 8.2 `src/services/customWorldBuilder.ts`
|
||||
|
||||
第二阶段不再只是 normalize,而要支持:
|
||||
|
||||
1. 合并 AI 输出与 fallback
|
||||
2. 校验线程、角色、场景之间的 ID 关联
|
||||
3. 把 `KnowledgeFact` 预编译结果一起挂回 profile
|
||||
|
||||
## 8.3 `src/services/prompt.ts`
|
||||
|
||||
这是第二阶段最重要的运行时改造点。
|
||||
|
||||
改造目标:
|
||||
|
||||
1. 彻底移除低披露阶段对 `relationshipHooks` / `tags` 的无条件直出
|
||||
2. `VisibilitySlice` 改为基于 `KnowledgeFact` 组装
|
||||
3. 引入 `recentCompanionReactions`
|
||||
4. 引入 `recentCarrierEchoes`
|
||||
|
||||
第二阶段后,prompt 不应再直接拼太多原始字段,而应该优先拼:
|
||||
|
||||
1. 可见事实
|
||||
2. 可推测事实
|
||||
3. 反应提示
|
||||
4. 线程压力
|
||||
|
||||
## 8.4 `src/data/npcInteractions.ts`
|
||||
|
||||
第二阶段重点:
|
||||
|
||||
1. 把 `stanceProfile` 从局部数值状态,升级成真正会改变文本与反应方向的关系模型
|
||||
2. 增加:
|
||||
- 审慎沉默
|
||||
- 价值观反对
|
||||
- 被触发的 taboo 反应
|
||||
- 队友间互评
|
||||
|
||||
仍不做大 UI,但要开始做:
|
||||
|
||||
- 运行时差异反应文本
|
||||
- 旅途中短插话
|
||||
|
||||
## 8.5 `src/hooks/useStoryGeneration.ts`
|
||||
|
||||
第二阶段继续保持 orchestrator 职责,不吞业务细节。
|
||||
|
||||
新增职责:
|
||||
|
||||
1. 收集 `StorySignal`
|
||||
2. 路由到 `threadSignalRouter`
|
||||
3. 收集队友反应批次
|
||||
4. 把反应和回响写回 story history / memory
|
||||
|
||||
## 8.6 `src/services/questDirector.ts` + `src/data/questFlow.ts`
|
||||
|
||||
第二阶段目标:
|
||||
|
||||
1. 任务不再只是“任务意图 -> 任务”
|
||||
2. 而是:
|
||||
- `StoryThread -> ThreadContract -> Quest manifestation`
|
||||
|
||||
最低要求:
|
||||
|
||||
1. 调查类任务
|
||||
2. 关系类任务
|
||||
|
||||
先完成线程化。
|
||||
|
||||
## 8.7 `src/data/runtimeItemNarrative.ts`
|
||||
|
||||
第二阶段这里不再是主攻点,但仍要扩:
|
||||
|
||||
1. 和 `narrativeCarrierCatalog` 对齐
|
||||
2. 支持非物件类叙事载体复用同一套描述语法
|
||||
3. 支持 NPC 对重点物件产生反应
|
||||
|
||||
## 9. 第二阶段开发顺序
|
||||
|
||||
建议顺序如下:
|
||||
|
||||
1. `KnowledgeFact` 图谱
|
||||
2. `VisibilitySlice 2.0`
|
||||
3. Prompt 泄露收口
|
||||
4. Companion reaction director
|
||||
5. Thread contract / signal router
|
||||
6. Scene residue / narrative carriers
|
||||
7. 自定义世界 AI contract 真接入
|
||||
8. 测试与内容回归
|
||||
|
||||
原因:
|
||||
|
||||
- 不先做知识图谱和可见性,后面所有反应系统都会继续飘
|
||||
- 不先做 signal router,线程化任务和回响都无法稳定推进
|
||||
|
||||
## 10. 测试方案
|
||||
|
||||
## 10.1 新增单元测试
|
||||
|
||||
建议新增:
|
||||
|
||||
1. `knowledgeGraph.test.ts`
|
||||
2. `knowledgeContract.test.ts`
|
||||
3. `companionReactionDirector.test.ts`
|
||||
4. `threadContract.test.ts`
|
||||
5. `threadSignalRouter.test.ts`
|
||||
6. `sceneResidueCompiler.test.ts`
|
||||
|
||||
## 10.2 新增集成测试
|
||||
|
||||
建议补以下集成路径:
|
||||
|
||||
1. 关键选择 -> 队友反应 -> stance 更新
|
||||
2. 获取重点物件 -> memory 回写 -> 后续 NPC 反应
|
||||
3. 调查线索 -> signal -> thread contract step 推进
|
||||
4. 自定义世界 AI 线程图谱 -> prompt 可见性 -> 首遇文本
|
||||
|
||||
## 10.3 第二阶段验收测试场景
|
||||
|
||||
至少人工回归这 5 条:
|
||||
|
||||
1. 队友对玩家价值观选择的分化反应
|
||||
2. 调查类任务拿到线索后任务推进
|
||||
3. 场景残痕被观察后触发新对话变化
|
||||
4. 重点物件被某 NPC 识别并改变口风
|
||||
5. 同一条暗线在人物、任务、地点、物件上多次回响
|
||||
|
||||
## 11. 第二阶段验收标准
|
||||
|
||||
做到以下几点,才算第二阶段收口:
|
||||
|
||||
1. 自定义世界线程图谱和角色叙事档案已真正支持 AI contract 生成
|
||||
2. 首遇和低披露阶段不再通过 `relationshipHooks / tags` 等隐式字段泄露暗线信息
|
||||
3. 队友会对关键选择给出差异化反应,且能写回关系状态
|
||||
4. 至少一类任务已经通过 `ThreadContract + StorySignal` 推进
|
||||
5. 地点调查、物件获取、对话推进之间开始形成回响闭环
|
||||
6. `storyEngineMemory` 中的 `recentCarrierIds / resolvedScarIds / recentCompanionReactions`
|
||||
已被运行时消费,而不只是存着
|
||||
7. 相关测试通过,`lint` / `typecheck` / `check:encoding` 通过
|
||||
|
||||
## 12. 一句话结论
|
||||
|
||||
第一阶段解决的是“剧情引擎的骨架有没有”,第二阶段要解决的是:
|
||||
|
||||
**这些骨架能不能开始真正驱动选择后果、队友反应、调查推进和世界回响。**
|
||||
|
||||
只要第二阶段做稳,当前项目就会从“结构上像 AI 原生剧情引擎”,真正走到“体验上开始像经典单机 RPG”。
|
||||
@@ -0,0 +1,690 @@
|
||||
# AI 原生剧情引擎第三阶段技术落地方案
|
||||
|
||||
更新时间:`2026-04-06`
|
||||
|
||||
## 0. 文档目的
|
||||
|
||||
这份方案建立在当前仓库第二阶段已经基本落地的前提上,面向第三阶段的技术推进。
|
||||
|
||||
按当前代码审计结果,第二阶段这些关键能力已经基本接入:
|
||||
|
||||
1. `KnowledgeFact`
|
||||
2. `VisibilitySlice 2.0`
|
||||
3. `CompanionReactionRecord`
|
||||
4. `ThreadContract`
|
||||
5. `StorySignal`
|
||||
6. `SceneNarrativeResidue`
|
||||
7. `narrativeCarrierCatalog`
|
||||
8. `recentCompanionReactions / recentCarrierEchoes`
|
||||
9. 自定义世界生成链中的 `ThemePack / StoryGraph / ActorNarrativeProfile` AI 生成阶段
|
||||
|
||||
同时,这些链已经形成了真实接线:
|
||||
|
||||
1. `customWorldBuilder` 会生成 `knowledgeFacts / threadContracts / narrativeResidues`
|
||||
2. `useStoryGeneration` 会读取 `knowledgeFacts` 并构造新的可见性切片
|
||||
3. `progressionActions` 会收集 `signals`、更新 `thread`、生成 `companion reactions`
|
||||
4. `questFlow` 已开始挂接 `threadContract`
|
||||
5. `prompt.ts` 已消费最近队友反应与载体回响
|
||||
|
||||
因此第三阶段不再解决:
|
||||
|
||||
- 引擎底层语法有没有
|
||||
- 线程和事实能不能进主链
|
||||
|
||||
第三阶段要解决的是:
|
||||
|
||||
**如何让这些系统进一步长成“章节化、队友线、世界状态变化、旅程高光、长期回顾”这些真正构成经典单机 RPG 体验的中高层叙事能力。**
|
||||
|
||||
## 1. 第二阶段审计结论
|
||||
|
||||
## 1.1 可以判定为“基本落地”的部分
|
||||
|
||||
按代码和测试情况,第二阶段已经基本落地:
|
||||
|
||||
1. 第二阶段新增模块都已存在并有测试:
|
||||
- `knowledgeGraph`
|
||||
- `knowledgeContract`
|
||||
- `companionReactionDirector`
|
||||
- `threadContract`
|
||||
- `threadSignalRouter`
|
||||
- `sceneResidueCompiler`
|
||||
- `echoMemory`
|
||||
|
||||
2. 关键主链已接入:
|
||||
- `customWorldBuilder.ts`
|
||||
- `useStoryGeneration.ts`
|
||||
- `progressionActions.ts`
|
||||
- `questFlow.ts`
|
||||
- `prompt.ts`
|
||||
|
||||
3. 第二阶段相关测试通过:
|
||||
- `knowledgeGraph.test.ts`
|
||||
- `knowledgeContract.test.ts`
|
||||
- `companionReactionDirector.test.ts`
|
||||
- `threadContract.test.ts`
|
||||
- `threadSignalRouter.test.ts`
|
||||
- `sceneResidueCompiler.test.ts`
|
||||
- `echoMemory.test.ts`
|
||||
|
||||
4. 工程门禁通过:
|
||||
- `lint`
|
||||
- `typecheck`
|
||||
- `check:encoding`
|
||||
|
||||
所以,“第二阶段技术落地方案已经基本落地”这个判断是成立的。
|
||||
|
||||
## 1.2 第二阶段仍然留下的真实缺口
|
||||
|
||||
虽然第二阶段已经基本落地,但它目前更像“动态剧情中层骨架”,还没完全进入“经典 RPG 体验高层”。
|
||||
|
||||
当前最关键的 6 个缺口是:
|
||||
|
||||
1. `ThreadContract` 仍偏浅
|
||||
- 目前主要还是两步式 contract,更多是“线程感知任务”,还不是多阶段主线/支线推进器。
|
||||
|
||||
2. `CompanionReactionDirector` 仍偏通用
|
||||
- 现在队友反应能发生,但还主要是通用 approve/disapprove 级别,还没有真正进入角色个人命题、价值观冲突、营地事件、队友互评。
|
||||
|
||||
3. `KnowledgeFact` 虽然存在,但还缺“长期总结层”
|
||||
- 现在事实能进可见性切片,但还缺章节摘要、世界回顾、角色关系归档、游玩 recap。
|
||||
|
||||
4. `SceneNarrativeResidue` 仍偏静态
|
||||
- 场景开始能讲故事了,但场景还不会因为线程推进、事件完成、阵营变化而发生状态变异。
|
||||
|
||||
5. 世界状态变化还很弱
|
||||
- 当前 `signal` 会推进记忆和 quest,可是还不会稳定驱动:
|
||||
- 场景变更
|
||||
- NPC 立场改口
|
||||
- 商店库存风格变化
|
||||
- 场景敌人/残痕刷新
|
||||
|
||||
6. 缺少章节 / 旅程 / 高光导演层
|
||||
- 现在有线程、有事实、有反应,但还没有一个更高层的“章节推进器”来控制:
|
||||
- 主线节奏
|
||||
- 旅程段落
|
||||
- 大事件前后
|
||||
- 营地休整与情感释放
|
||||
- 章节收束与下一章开启
|
||||
|
||||
## 1.3 结论
|
||||
|
||||
第一阶段解决的是“骨架有没有”,第二阶段解决的是“中层动态有没有”,第三阶段要解决的是:
|
||||
|
||||
**这些系统能不能组合出真正像经典单机 RPG 的章节感、队友线、旅程高光和世界变化。**
|
||||
|
||||
## 2. 第三阶段目标
|
||||
|
||||
第三阶段只做 5 件事:
|
||||
|
||||
1. 建立 `章节 / 旅程 / 高光导演层`
|
||||
2. 建立 `队友个人线与营地事件层`
|
||||
3. 建立 `世界状态变化与阵营温度层`
|
||||
4. 建立 `叙事文书 / 档案 / 回顾摘要层`
|
||||
5. 建立 `大事件 / 章节高潮 / Boss 前后叙事编排层`
|
||||
|
||||
一句话定义第三阶段:
|
||||
|
||||
**从“动态剧情系统”升级到“能持续制造章节记忆点和旅程余味的 RPG 叙事框架”。**
|
||||
|
||||
## 3. 第三阶段完成定义
|
||||
|
||||
第三阶段完成后,至少要同时满足:
|
||||
|
||||
1. 游戏运行中能形成 `章节感`
|
||||
- 玩家明确感到自己经历了“第一章、第二章、转折、大事件、余波”。
|
||||
|
||||
2. 队友不再只是对选择做短反应
|
||||
- 而是会有:
|
||||
- 个人线推进
|
||||
- 营地事件
|
||||
- 队友互评
|
||||
- 价值观冲突
|
||||
- 忠诚变化
|
||||
|
||||
3. 世界会因为线程推进发生状态变化
|
||||
- 某些场景描述、残痕、NPC 态度、敌对压力、商店风格、任务机会会改变。
|
||||
|
||||
4. 玩家会得到结构化回顾
|
||||
- 包括:
|
||||
- 当前章节摘要
|
||||
- 已发现关键真相
|
||||
- 队友关系变化
|
||||
- 最近大事件
|
||||
|
||||
5. 至少一条主线或关键线程,已经能从“起线 -> 扩张 -> 转折 -> 高潮 -> 余波”完整走完。
|
||||
|
||||
## 4. 第三阶段范围
|
||||
|
||||
## 4.1 纳入范围
|
||||
|
||||
- `src/services/storyEngine/*`
|
||||
- `src/hooks/useStoryGeneration.ts`
|
||||
- `src/hooks/story/progressionActions.ts`
|
||||
- `src/data/npcInteractions.ts`
|
||||
- `src/data/questFlow.ts`
|
||||
- `src/services/prompt.ts`
|
||||
- `src/components/AdventureEntityModal.tsx`
|
||||
- `src/components/CharacterPanel.tsx`
|
||||
- `src/components/InventoryPanel.tsx`
|
||||
- `src/components/AdventurePanel.tsx`
|
||||
- `src/types/storyEngine.ts`
|
||||
- `src/types/story.ts`
|
||||
- `src/types/game.ts`
|
||||
- `src/types/scene.ts`
|
||||
|
||||
## 4.2 新增模块
|
||||
|
||||
- `src/services/storyEngine/chapterDirector.ts`
|
||||
- `src/services/storyEngine/journeyBeatPlanner.ts`
|
||||
- `src/services/storyEngine/companionArcDirector.ts`
|
||||
- `src/services/storyEngine/campEventDirector.ts`
|
||||
- `src/services/storyEngine/worldMutationRouter.ts`
|
||||
- `src/services/storyEngine/factionTensionState.ts`
|
||||
- `src/services/storyEngine/documentCarrierCompiler.ts`
|
||||
- `src/services/storyEngine/storyChronicle.ts`
|
||||
- `src/services/storyEngine/recapDigest.ts`
|
||||
- `src/services/storyEngine/setpieceDirector.ts`
|
||||
|
||||
## 4.3 第三阶段明确不做
|
||||
|
||||
第三阶段仍不做:
|
||||
|
||||
1. 全流程可视化剧情编辑器
|
||||
2. 通用 mod 工具链
|
||||
3. 全量配音/镜头脚本系统
|
||||
4. 无限复杂分支树编辑器
|
||||
5. 所有支线都拥有章节级演出
|
||||
|
||||
原因:
|
||||
|
||||
第三阶段目标是把当前系统推到“经典 RPG 体验层”,不是同时把制作工具也做到工业级。
|
||||
|
||||
## 5. 第三阶段最小闭环
|
||||
|
||||
建议第三阶段最小闭环为:
|
||||
|
||||
```text
|
||||
ChapterDirector
|
||||
-> JourneyBeatPlanner
|
||||
-> ThreadContract / StorySignal
|
||||
-> CompanionArcDirector
|
||||
-> CampEventDirector
|
||||
-> WorldMutationRouter
|
||||
-> SetpieceDirector
|
||||
-> StoryChronicle / RecapDigest
|
||||
```
|
||||
|
||||
这条闭环对应玩家可感知的体验是:
|
||||
|
||||
1. 章节推进
|
||||
2. 旅程段落变化
|
||||
3. 队友关系与个人线变化
|
||||
4. 场景 / 世界状态变化
|
||||
5. 大事件 / 高潮回合
|
||||
6. 章节后的回顾与余波
|
||||
|
||||
## 6. 数据结构升级方案
|
||||
|
||||
## 6.1 `src/types/storyEngine.ts`
|
||||
|
||||
第三阶段建议新增:
|
||||
|
||||
```ts
|
||||
export interface ChapterState {
|
||||
id: string;
|
||||
title: string;
|
||||
theme: string;
|
||||
primaryThreadIds: string[];
|
||||
stage: 'opening' | 'expansion' | 'turning_point' | 'climax' | 'aftermath';
|
||||
chapterSummary: string;
|
||||
}
|
||||
|
||||
export interface JourneyBeat {
|
||||
id: string;
|
||||
beatType: 'approach' | 'investigation' | 'camp' | 'conflict' | 'boss_prelude' | 'climax' | 'recovery';
|
||||
title: string;
|
||||
triggerThreadIds: string[];
|
||||
recommendedSceneIds: string[];
|
||||
emotionalGoal: string;
|
||||
}
|
||||
|
||||
export interface CompanionArcState {
|
||||
characterId: string;
|
||||
arcTheme: string;
|
||||
currentStage: 'closed' | 'guarded' | 'opening' | 'conflicted' | 'bonded' | 'resolved';
|
||||
activeConflictTags: string[];
|
||||
pendingEventIds: string[];
|
||||
resolvedEventIds: string[];
|
||||
}
|
||||
|
||||
export interface CampEvent {
|
||||
id: string;
|
||||
eventType: 'private_talk' | 'party_banter' | 'conflict' | 'comfort' | 'reveal' | 'decision';
|
||||
title: string;
|
||||
participantCharacterIds: string[];
|
||||
triggerReason: string;
|
||||
relatedThreadIds: string[];
|
||||
}
|
||||
|
||||
export interface WorldMutation {
|
||||
id: string;
|
||||
mutationType: 'scene_text' | 'npc_attitude' | 'shop_style' | 'enemy_pressure' | 'route_lock' | 'route_unlock';
|
||||
targetId: string;
|
||||
reason: string;
|
||||
relatedThreadIds: string[];
|
||||
}
|
||||
|
||||
export interface FactionTensionState {
|
||||
factionId: string;
|
||||
temperature: number;
|
||||
pressureSummary: string;
|
||||
activeConflictThreadIds: string[];
|
||||
}
|
||||
|
||||
export interface ChronicleEntry {
|
||||
id: string;
|
||||
category: 'chapter' | 'thread' | 'companion' | 'carrier' | 'scene' | 'world_event';
|
||||
title: string;
|
||||
summary: string;
|
||||
relatedIds: string[];
|
||||
createdAt: string;
|
||||
}
|
||||
```
|
||||
|
||||
并扩展:
|
||||
|
||||
```ts
|
||||
export interface StoryEngineMemoryState {
|
||||
currentChapter?: ChapterState | null;
|
||||
currentJourneyBeatId?: string | null;
|
||||
companionArcStates?: CompanionArcState[];
|
||||
worldMutations?: WorldMutation[];
|
||||
chronicle?: ChronicleEntry[];
|
||||
}
|
||||
```
|
||||
|
||||
## 6.2 `src/types/game.ts`
|
||||
|
||||
第三阶段建议新增:
|
||||
|
||||
```ts
|
||||
interface GameState {
|
||||
chapterState?: ChapterState | null;
|
||||
}
|
||||
```
|
||||
|
||||
说明:
|
||||
|
||||
- `chapterState` 放在 `GameState` 顶层,便于 UI 和主流程快速读取
|
||||
- 详细历史仍留在 `storyEngineMemory`
|
||||
|
||||
## 6.3 `src/types/scene.ts`
|
||||
|
||||
第三阶段建议扩展:
|
||||
|
||||
```ts
|
||||
interface ScenePresetInfo {
|
||||
mutationStateText?: string | null;
|
||||
currentPressureLevel?: 'low' | 'medium' | 'high' | 'extreme';
|
||||
}
|
||||
```
|
||||
|
||||
用于场景在章节推进后发生显式变化。
|
||||
|
||||
## 7. 模块实现方案
|
||||
|
||||
## 7.1 `chapterDirector.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 根据主活跃线程、最近 signal、世界冲突温度,决定当前章节处于哪个阶段
|
||||
2. 生成:
|
||||
- 章节标题
|
||||
- 当前主题
|
||||
- 当前主线线程
|
||||
- 当前章节摘要
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
resolveCurrentChapterState(params)
|
||||
advanceChapterState(params)
|
||||
```
|
||||
|
||||
第三阶段目标:
|
||||
|
||||
- 让玩家的体验从“连续事件流”变成“章节化旅程”
|
||||
|
||||
## 7.2 `journeyBeatPlanner.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 在章节内部规划短周期旅程段落
|
||||
2. 给当前阶段分配:
|
||||
- 接近
|
||||
- 调查
|
||||
- 休整
|
||||
- 冲突
|
||||
- 高潮前奏
|
||||
- 余波
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildJourneyBeatQueue(params)
|
||||
resolveCurrentJourneyBeat(params)
|
||||
```
|
||||
|
||||
它是第三阶段对标《黑神话》旅程感和《仙剑》节奏起伏的关键模块。
|
||||
|
||||
## 7.3 `companionArcDirector.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 把当前队友的 stance、thread、reaction、facts 组合成真正的个人线状态
|
||||
2. 决定某个队友此刻更接近:
|
||||
- 打开
|
||||
- 回避
|
||||
- 冲突
|
||||
- 信任
|
||||
- 和解
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildCompanionArcState(params)
|
||||
advanceCompanionArc(params)
|
||||
```
|
||||
|
||||
目标:
|
||||
|
||||
- 从“通用反应”进化到“每个队友都有正在发生的个人线”
|
||||
|
||||
## 7.4 `campEventDirector.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 根据 `CompanionArcState + recentCompanionReactions + chapterState`
|
||||
决定是否生成营地/旅途中事件
|
||||
2. 生成:
|
||||
- 私聊事件
|
||||
- 队友互评
|
||||
- 意见冲突
|
||||
- 情绪缓和
|
||||
- 个人秘密推进
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
evaluateCampEventOpportunity(params)
|
||||
buildCampEvent(params)
|
||||
```
|
||||
|
||||
这是第三阶段对标《仙剑》角色羁绊、《博德之门》营地戏的核心模块。
|
||||
|
||||
## 7.5 `worldMutationRouter.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 把 `StorySignal + ThreadContract + ChapterState` 转成世界状态变化
|
||||
2. 更新:
|
||||
- 场景描述
|
||||
- NPC 口风
|
||||
- 商店风格
|
||||
- 敌人压力
|
||||
- 路线开关
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
resolveWorldMutations(params)
|
||||
applyWorldMutationsToGameState(params)
|
||||
```
|
||||
|
||||
第三阶段目标:
|
||||
|
||||
- 世界开始“因为你做过的事而变”
|
||||
|
||||
## 7.6 `factionTensionState.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 给 major factions 维护温度和压力摘要
|
||||
2. 决定某些章节里哪条势力线正在升温
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildFactionTensionState(profile, memory)
|
||||
applySignalToFactionTension(params)
|
||||
```
|
||||
|
||||
它主要对标《轩辕剑》的大时代张力和《古剑》的世界推进感。
|
||||
|
||||
## 7.7 `documentCarrierCompiler.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 把“文书、口供、记录、日志、残页、信件”等正式纳入叙事载体体系
|
||||
2. 和 `narrativeCarrierCatalog` 对齐
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildNarrativeDocument(params)
|
||||
compileDocumentKnowledgeFacts(params)
|
||||
```
|
||||
|
||||
目标:
|
||||
|
||||
- 第三阶段让叙事载体不再只限于物件和场景残痕
|
||||
|
||||
## 7.8 `storyChronicle.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 把当前发生过的大事件、关键事实、角色转折写入 chronicle
|
||||
2. 让玩家和系统都有一个更高层的“已发生过什么”的长期摘要
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
appendChronicleEntry(params)
|
||||
buildChronicleSummary(params)
|
||||
```
|
||||
|
||||
## 7.9 `recapDigest.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 生成章节回顾、阶段摘要、下回合简报
|
||||
2. 给 UI、存档恢复、继续游戏提供更强的 recap 文本
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildChapterRecap(params)
|
||||
buildContinueGameDigest(params)
|
||||
```
|
||||
|
||||
## 7.10 `setpieceDirector.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 决定何时进入大事件、Boss 前奏、对峙、章节高潮
|
||||
2. 给主链输出高光导演指令
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
evaluateSetpieceOpportunity(params)
|
||||
buildSetpieceDirective(params)
|
||||
```
|
||||
|
||||
第三阶段目标:
|
||||
|
||||
- 让剧情不只是“持续往前”,而是有真正高光和收束
|
||||
|
||||
## 8. 现有文件改造方案
|
||||
|
||||
## 8.1 `src/hooks/useStoryGeneration.ts`
|
||||
|
||||
第三阶段这里要继续保持 orchestrator 职责,但增加“高层导演”的接线:
|
||||
|
||||
新增接线:
|
||||
|
||||
1. `chapterDirector`
|
||||
2. `journeyBeatPlanner`
|
||||
3. `setpieceDirector`
|
||||
4. `campEventDirector`
|
||||
|
||||
它要做的事情:
|
||||
|
||||
1. 读取当前章节状态
|
||||
2. 读取当前旅程 beat
|
||||
3. 判断本回合是否应该转入营地 / 高潮 / 余波
|
||||
4. 把这些高层指令压入 prompt
|
||||
|
||||
## 8.2 `src/hooks/story/progressionActions.ts`
|
||||
|
||||
这里是第三阶段最重要的状态推进点。
|
||||
|
||||
新增职责:
|
||||
|
||||
1. 调用 `worldMutationRouter`
|
||||
2. 调用 `companionArcDirector`
|
||||
3. 调用 `storyChronicle`
|
||||
4. 回写:
|
||||
- `chapterState`
|
||||
- `companionArcStates`
|
||||
- `worldMutations`
|
||||
- `chronicle`
|
||||
|
||||
## 8.3 `src/services/prompt.ts`
|
||||
|
||||
第三阶段改造目标:
|
||||
|
||||
1. 加入 `chapterState`
|
||||
2. 加入 `journeyBeat`
|
||||
3. 加入 `recentWorldMutations`
|
||||
4. 加入 `recentChronicleSummary`
|
||||
|
||||
提示词不再只围绕“当前场景 + 当前遭遇 + facts”,还要围绕:
|
||||
|
||||
1. 当前章节主题
|
||||
2. 当前旅程段落
|
||||
3. 最近发生的世界变化
|
||||
4. 队友当前情绪与线索包袱
|
||||
|
||||
## 8.4 `src/data/npcInteractions.ts`
|
||||
|
||||
第三阶段重点:
|
||||
|
||||
1. 支持由 `CompanionArcState` 决定对话气质
|
||||
2. 支持队友互评与冲突事件
|
||||
3. 支持同一选择在不同 arc stage 下触发不同态度
|
||||
|
||||
## 8.5 `src/data/questFlow.ts`
|
||||
|
||||
第三阶段目标:
|
||||
|
||||
1. 任务从“线程 manifest”继续升级为“章节与旅程服务”
|
||||
2. 支持:
|
||||
- 章节中期任务
|
||||
- 高潮前置任务
|
||||
- 余波任务
|
||||
|
||||
## 8.6 `src/components/*`
|
||||
|
||||
第三阶段不主打大 UI 重做,但建议最小补这些表现:
|
||||
|
||||
1. `AdventurePanel`
|
||||
- 当前章节标题 / 当前旅程 beat 轻量显示
|
||||
|
||||
2. `CharacterPanel`
|
||||
- 队友当前个人线阶段
|
||||
|
||||
3. `AdventureEntityModal`
|
||||
- 最近与该角色相关的 chronicle / residue / carrier 片段
|
||||
|
||||
4. `InventoryPanel`
|
||||
- 文书 / 证据 / 特殊载体的独立入口
|
||||
|
||||
## 9. 第三阶段开发顺序
|
||||
|
||||
建议顺序如下:
|
||||
|
||||
1. `chapterDirector`
|
||||
2. `journeyBeatPlanner`
|
||||
3. `companionArcDirector`
|
||||
4. `campEventDirector`
|
||||
5. `worldMutationRouter`
|
||||
6. `documentCarrierCompiler`
|
||||
7. `storyChronicle`
|
||||
8. `recapDigest`
|
||||
9. `setpieceDirector`
|
||||
10. UI 最小接线
|
||||
|
||||
原因:
|
||||
|
||||
- 没有章节和旅程层,后面的营地事件和高潮都无从安放
|
||||
- 没有 world mutation,很多后续内容仍会像“文本在变,世界没变”
|
||||
|
||||
## 10. 测试方案
|
||||
|
||||
## 10.1 新增单元测试
|
||||
|
||||
建议新增:
|
||||
|
||||
1. `chapterDirector.test.ts`
|
||||
2. `journeyBeatPlanner.test.ts`
|
||||
3. `companionArcDirector.test.ts`
|
||||
4. `campEventDirector.test.ts`
|
||||
5. `worldMutationRouter.test.ts`
|
||||
6. `factionTensionState.test.ts`
|
||||
7. `documentCarrierCompiler.test.ts`
|
||||
8. `storyChronicle.test.ts`
|
||||
9. `recapDigest.test.ts`
|
||||
10. `setpieceDirector.test.ts`
|
||||
|
||||
## 10.2 新增集成测试
|
||||
|
||||
建议补这 5 类:
|
||||
|
||||
1. 线程推进到转折点后,章节状态发生变化
|
||||
2. 队友在关键选择后推进个人线阶段
|
||||
3. 获得关键文书后,营地事件或下一轮剧情出现新回响
|
||||
4. 某条主线推进后,场景文本和 NPC 态度发生世界状态变化
|
||||
5. 高潮前后,prompt 中的章节、旅程、世界变化信息都能被正确注入
|
||||
|
||||
## 10.3 人工回归场景
|
||||
|
||||
至少做这 6 条:
|
||||
|
||||
1. 一条调查线程从起线推进到转折
|
||||
2. 一个队友从 guarded 推到 conflicted / bonded
|
||||
3. 一个营地事件被触发并影响后续关系
|
||||
4. 一个重点物件 + 文书 + 场景残痕组成同一条暗线回响
|
||||
5. 一个章节进入高潮前后,场景压力显著变化
|
||||
6. 继续游戏时能看到结构化 recap,而不是只靠最后几条 story history
|
||||
|
||||
## 11. 第三阶段验收标准
|
||||
|
||||
做到以下几点,才算第三阶段可收口:
|
||||
|
||||
1. 系统能稳定给出 `ChapterState`
|
||||
2. 至少一条主线线程可以经历 `opening -> expansion -> turning_point -> climax -> aftermath`
|
||||
3. 队友个人线能有明确阶段推进,并能触发营地或旅途事件
|
||||
4. 世界状态会因为线程推进产生可见变化
|
||||
5. 文书/证据类叙事载体正式进入主链
|
||||
6. 玩家可以在运行时获得章节回顾和近期大事件摘要
|
||||
7. 高潮节点会由 `setpieceDirector` 显式导演,而不是随机撞出来
|
||||
8. 相关测试通过,`lint` / `typecheck` / `check:encoding` 通过
|
||||
|
||||
## 12. 一句话结论
|
||||
|
||||
第一阶段解决“骨架”,第二阶段解决“动态系统”,第三阶段要解决的是:
|
||||
|
||||
**这些动态系统能不能真正长出章节感、队友线、世界变化和章节高光。**
|
||||
|
||||
只有第三阶段做稳,当前项目才会从“已经很像 AI 原生剧情引擎”,真正走向“能稳定制造经典单机 RPG 旅程体验”的层级。
|
||||
@@ -0,0 +1,725 @@
|
||||
# AI 原生剧情引擎第四阶段技术落地方案
|
||||
|
||||
更新时间:`2026-04-06`
|
||||
|
||||
## 0. 文档目的
|
||||
|
||||
这份方案建立在当前仓库第三阶段已经基本落地的前提上,面向第四阶段的技术推进。
|
||||
|
||||
按当前代码审计结果,第三阶段已经基本把这些中高层能力接进了主链:
|
||||
|
||||
1. `ChapterState`
|
||||
2. `JourneyBeat`
|
||||
3. `CompanionArcState`
|
||||
4. `CampEvent`
|
||||
5. `WorldMutation`
|
||||
6. `FactionTensionState`
|
||||
7. `ChronicleEntry`
|
||||
8. `ContinueGameDigest`
|
||||
9. `SetpieceDirective`
|
||||
|
||||
并且这些能力已经开始被:
|
||||
|
||||
- `useStoryGeneration`
|
||||
- `progressionActions`
|
||||
- `prompt.ts`
|
||||
- `AdventurePanel`
|
||||
- `CharacterPanel`
|
||||
- `AdventureEntityModal`
|
||||
- `InventoryPanel`
|
||||
|
||||
实际消费。
|
||||
|
||||
因此第四阶段不再解决:
|
||||
|
||||
- 底层图谱有没有
|
||||
- 动态系统有没有
|
||||
- 章节、旅程和高光导演有没有
|
||||
|
||||
第四阶段要解决的是:
|
||||
|
||||
**如何让当前已经具备的动态叙事系统,真正进入“可持续量产内容、可收束长线剧情、可形成多幕主线与结局体验、可进行作者性控制和质量校验”的阶段。**
|
||||
|
||||
一句话说:
|
||||
|
||||
**前三阶段把引擎“做起来”,第四阶段要把它“做完整、做可控、做可持续量产”。**
|
||||
|
||||
## 1. 第三阶段审计结论
|
||||
|
||||
## 1.1 可以判定为“基本落地”的部分
|
||||
|
||||
按代码和测试情况,第三阶段已经基本落地:
|
||||
|
||||
1. 第三阶段新增模块都已存在并有测试:
|
||||
- `chapterDirector`
|
||||
- `journeyBeatPlanner`
|
||||
- `companionArcDirector`
|
||||
- `campEventDirector`
|
||||
- `worldMutationRouter`
|
||||
- `factionTensionState`
|
||||
- `documentCarrierCompiler`
|
||||
- `storyChronicle`
|
||||
- `recapDigest`
|
||||
- `setpieceDirector`
|
||||
|
||||
2. 关键主链已接入:
|
||||
- `useStoryGeneration.ts`
|
||||
- `progressionActions.ts`
|
||||
- `prompt.ts`
|
||||
- `AdventurePanel.tsx`
|
||||
- `CharacterPanel.tsx`
|
||||
- `AdventureEntityModal.tsx`
|
||||
- `InventoryPanel.tsx`
|
||||
- `GameShell.tsx`
|
||||
|
||||
3. 第三阶段相关测试通过:
|
||||
- `chapterDirector.test.ts`
|
||||
- `journeyBeatPlanner.test.ts`
|
||||
- `companionArcDirector.test.ts`
|
||||
- `campEventDirector.test.ts`
|
||||
- `worldMutationRouter.test.ts`
|
||||
- `factionTensionState.test.ts`
|
||||
- `documentCarrierCompiler.test.ts`
|
||||
- `storyChronicle.test.ts`
|
||||
- `recapDigest.test.ts`
|
||||
- `setpieceDirector.test.ts`
|
||||
|
||||
4. 工程门禁通过:
|
||||
- `lint`
|
||||
- `typecheck`
|
||||
- `check:encoding`
|
||||
|
||||
所以,“第三阶段技术落地方案已经基本落地”这个判断成立。
|
||||
|
||||
## 1.2 第三阶段留下的真实缺口
|
||||
|
||||
虽然第三阶段已经把“章节、旅程、队友线、世界变化、高光导演”这些高层能力接起来了,但它们还更像“运行时中高层系统”,还没有进入真正的“长线 campaign 完整度”和“内容生产可控性”阶段。
|
||||
|
||||
当前最关键的 7 个缺口是:
|
||||
|
||||
1. `ChapterState` 已有,但还缺 `Act / Campaign` 级结构
|
||||
- 目前更像章节段落推进器,还不是完整的多幕主线架构。
|
||||
|
||||
2. 队友个人线已有,但还缺“收束态”
|
||||
- 当前能推进 arc stage,但还没有:
|
||||
- 个人线结局
|
||||
- 决裂 / 离队 / 归队
|
||||
- 忠诚锁定
|
||||
- 决战前站队
|
||||
|
||||
3. 世界变化已有,但还缺“全局后果账本”
|
||||
- 当前能改场景和口风,但还没有统一的:
|
||||
- 关键选择后果台账
|
||||
- 阵营态势累积
|
||||
- 长线不可逆变化
|
||||
|
||||
4. 文书与 chronicle 已有,但还缺“玩家可管理的故事档案”
|
||||
- 现在有内容生成和少量展示,但还缺真正的 codex / archive 层。
|
||||
|
||||
5. `SetpieceDirector` 已有,但还偏事件触发器
|
||||
- 当前能识别高潮和余波,但还没有:
|
||||
- 多阶段高潮编排
|
||||
- 决战前准备段
|
||||
- 决战后结算段
|
||||
|
||||
6. 缺少结局 / 尾声系统
|
||||
- 当前可以推进 journey,但没有明确的:
|
||||
- 线程结局
|
||||
- 角色结局
|
||||
- 世界结局
|
||||
- 尾声摘要
|
||||
|
||||
7. 缺少作者性约束与质量门禁
|
||||
- 当前系统很强,但如果要稳定产出“经典 RPG 级长线内容”,必须补:
|
||||
- branch budget
|
||||
- ending coverage
|
||||
- contradiction checks
|
||||
- pacing checks
|
||||
- narrative QA 报告
|
||||
|
||||
## 1.3 结论
|
||||
|
||||
第一阶段解决“骨架”,第二阶段解决“动态系统”,第三阶段解决“章节和旅程感”,第四阶段要解决的是:
|
||||
|
||||
**这套引擎能不能稳定做出完整 campaign,并且能被持续生产、校验、维护和扩张。**
|
||||
|
||||
## 2. 第四阶段目标
|
||||
|
||||
第四阶段只做 5 件事:
|
||||
|
||||
1. 建立 `Campaign / Act / Ending` 级主线结构
|
||||
2. 建立 `Companion Resolution` 队友线收束系统
|
||||
3. 建立 `Consequence Ledger` 全局后果账本
|
||||
4. 建立 `Narrative Codex / Archive` 故事档案系统
|
||||
5. 建立 `Authorial Constraint + Narrative QA` 内容生产与质量门禁体系
|
||||
|
||||
一句话定义第四阶段:
|
||||
|
||||
**从“能跑出经典 RPG 旅程感”升级到“能稳定完成一整部经典 RPG campaign”。**
|
||||
|
||||
## 3. 第四阶段完成定义
|
||||
|
||||
第四阶段完成后,至少要同时满足:
|
||||
|
||||
1. 系统能够维护多幕结构
|
||||
- `Act I / II / III` 或等价 campaign 分段真正成立。
|
||||
|
||||
2. 至少一条完整主线能走到结局
|
||||
- 并且结局由:
|
||||
- 主线程结果
|
||||
- 队友个人线结果
|
||||
- 阵营态势
|
||||
- 关键后果账本
|
||||
共同决定。
|
||||
|
||||
3. 队友个人线能有明确收束
|
||||
- 包括:
|
||||
- 和解
|
||||
- 坚定追随
|
||||
- 决裂
|
||||
- 离队
|
||||
- 牺牲 / 缺席 / 旁观
|
||||
|
||||
4. 世界后果被系统记录并能影响结局和尾声
|
||||
- 不只是局部场景文字变化。
|
||||
|
||||
5. 玩家可以查看已发生的主线、角色线、文书、关键真相和结局线索。
|
||||
|
||||
6. 生成链具备明确的作者性约束和 QA 报告,不再只靠人工抽样验证。
|
||||
|
||||
## 4. 第四阶段范围
|
||||
|
||||
## 4.1 纳入范围
|
||||
|
||||
- `src/services/storyEngine/*`
|
||||
- `src/hooks/story/progressionActions.ts`
|
||||
- `src/hooks/useStoryGeneration.ts`
|
||||
- `src/services/prompt.ts`
|
||||
- `src/data/questFlow.ts`
|
||||
- `src/data/npcInteractions.ts`
|
||||
- `src/components/AdventurePanel.tsx`
|
||||
- `src/components/CharacterPanel.tsx`
|
||||
- `src/components/InventoryPanel.tsx`
|
||||
- `src/components/AdventureEntityModal.tsx`
|
||||
- `src/components/GameShell.tsx`
|
||||
- `src/types/storyEngine.ts`
|
||||
- `src/types/game.ts`
|
||||
- `src/types/story.ts`
|
||||
|
||||
## 4.2 新增模块
|
||||
|
||||
- `src/services/storyEngine/campaignDirector.ts`
|
||||
- `src/services/storyEngine/actPlanner.ts`
|
||||
- `src/services/storyEngine/endingResolver.ts`
|
||||
- `src/services/storyEngine/epilogueComposer.ts`
|
||||
- `src/services/storyEngine/companionResolutionDirector.ts`
|
||||
- `src/services/storyEngine/consequenceLedger.ts`
|
||||
- `src/services/storyEngine/narrativeCodex.ts`
|
||||
- `src/services/storyEngine/authorialConstraintPack.ts`
|
||||
- `src/services/storyEngine/branchBudgetPlanner.ts`
|
||||
- `src/services/storyEngine/narrativeQaReport.ts`
|
||||
- `src/services/storyEngine/narrativeConsistencyChecks.ts`
|
||||
|
||||
## 4.3 第四阶段明确不做
|
||||
|
||||
第四阶段仍不做:
|
||||
|
||||
1. 完整可视化剧情节点编辑器
|
||||
2. 商业级本地化 pipeline
|
||||
3. 全自动配音 / 镜头脚本工具链
|
||||
4. 全量开放给 mod 作者的内容 DSL
|
||||
5. 无上限多周目 meta-progression
|
||||
|
||||
原因:
|
||||
|
||||
第四阶段的任务是把 campaign 层做完整和可控,不是同时做全生产平台。
|
||||
|
||||
## 5. 第四阶段最小闭环
|
||||
|
||||
建议第四阶段最小闭环为:
|
||||
|
||||
```text
|
||||
CampaignDirector
|
||||
-> ActPlanner
|
||||
-> Chapter / Journey / Thread systems
|
||||
-> ConsequenceLedger
|
||||
-> CompanionResolutionDirector
|
||||
-> EndingResolver
|
||||
-> EpilogueComposer
|
||||
-> NarrativeCodex
|
||||
-> NarrativeQaReport
|
||||
```
|
||||
|
||||
这条闭环对应玩家可感知的体验是:
|
||||
|
||||
1. 这不是无限流局部冒险,而是一段完整 campaign
|
||||
2. 你的选择有长期代价
|
||||
3. 队友线会真正收束
|
||||
4. 结局和尾声会回收之前埋下的线
|
||||
5. 整个过程具有更强作者性和完成度
|
||||
|
||||
## 6. 数据结构升级方案
|
||||
|
||||
## 6.1 `src/types/storyEngine.ts`
|
||||
|
||||
第四阶段建议新增:
|
||||
|
||||
```ts
|
||||
export interface CampaignState {
|
||||
id: string;
|
||||
title: string;
|
||||
currentActId: string | null;
|
||||
currentActIndex: number;
|
||||
resolvedEndingId?: string | null;
|
||||
}
|
||||
|
||||
export interface ActState {
|
||||
id: string;
|
||||
title: string;
|
||||
actIndex: number;
|
||||
theme: string;
|
||||
primaryThreadIds: string[];
|
||||
status: 'opening' | 'midgame' | 'late_game' | 'finale' | 'resolved';
|
||||
}
|
||||
|
||||
export interface ConsequenceRecord {
|
||||
id: string;
|
||||
category: 'thread' | 'companion' | 'faction' | 'world' | 'ending_flag';
|
||||
title: string;
|
||||
summary: string;
|
||||
weight: number;
|
||||
relatedIds: string[];
|
||||
irreversible: boolean;
|
||||
}
|
||||
|
||||
export interface CompanionResolution {
|
||||
characterId: string;
|
||||
resolutionType: 'bonded' | 'reconciled' | 'estranged' | 'departed' | 'sacrificed' | 'neutral';
|
||||
summary: string;
|
||||
relatedThreadIds: string[];
|
||||
}
|
||||
|
||||
export interface EndingState {
|
||||
id: string;
|
||||
title: string;
|
||||
endingType: 'heroic' | 'tragic' | 'bitter_sweet' | 'fractured' | 'ascendant';
|
||||
summary: string;
|
||||
contributingThreadIds: string[];
|
||||
companionResolutions: CompanionResolution[];
|
||||
worldOutcomeSummary: string;
|
||||
}
|
||||
|
||||
export interface AuthorialConstraintPack {
|
||||
toneRules: string[];
|
||||
noGoPatterns: string[];
|
||||
branchBudget: {
|
||||
maxMajorDivergences: number;
|
||||
maxEndingFamilies: number;
|
||||
};
|
||||
mandatoryThemes: string[];
|
||||
requiredPayoffs: string[];
|
||||
}
|
||||
|
||||
export interface NarrativeQaIssue {
|
||||
id: string;
|
||||
severity: 'low' | 'medium' | 'high';
|
||||
category: 'consistency' | 'pacing' | 'payoff' | 'branch_budget' | 'reveal_leak';
|
||||
summary: string;
|
||||
relatedIds: string[];
|
||||
}
|
||||
|
||||
export interface NarrativeQaReport {
|
||||
generatedAt: string;
|
||||
issues: NarrativeQaIssue[];
|
||||
summary: string;
|
||||
}
|
||||
```
|
||||
|
||||
并扩展:
|
||||
|
||||
```ts
|
||||
export interface StoryEngineMemoryState {
|
||||
campaignState?: CampaignState | null;
|
||||
actState?: ActState | null;
|
||||
consequenceLedger?: ConsequenceRecord[];
|
||||
companionResolutions?: CompanionResolution[];
|
||||
endingState?: EndingState | null;
|
||||
authorialConstraintPack?: AuthorialConstraintPack | null;
|
||||
narrativeQaReport?: NarrativeQaReport | null;
|
||||
}
|
||||
```
|
||||
|
||||
## 6.2 `src/types/game.ts`
|
||||
|
||||
扩展:
|
||||
|
||||
```ts
|
||||
interface GameState {
|
||||
campaignState?: CampaignState | null;
|
||||
}
|
||||
```
|
||||
|
||||
## 6.3 `src/types/story.ts`
|
||||
|
||||
扩展:
|
||||
|
||||
```ts
|
||||
interface QuestLogEntry {
|
||||
actId?: string | null;
|
||||
consequenceIds?: string[];
|
||||
}
|
||||
```
|
||||
|
||||
目的:
|
||||
|
||||
- 让任务正式进入 campaign / act 结构
|
||||
|
||||
## 7. 模块实现方案
|
||||
|
||||
## 7.1 `campaignDirector.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 建立整个 campaign 的总状态
|
||||
2. 管理当前 act 与 campaign 收束进度
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
resolveCampaignState(params)
|
||||
advanceCampaignState(params)
|
||||
```
|
||||
|
||||
目标:
|
||||
|
||||
- 从章节推进升级到“整部故事”的推进
|
||||
|
||||
## 7.2 `actPlanner.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 根据主线程、世界 tension、队友线推进情况划分 act
|
||||
2. 决定何时进入:
|
||||
- 第一幕铺陈
|
||||
- 第二幕扩张
|
||||
- 第三幕决战
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildActPlan(params)
|
||||
resolveCurrentActState(params)
|
||||
```
|
||||
|
||||
## 7.3 `consequenceLedger.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 记录关键选择和线程推进的长期后果
|
||||
2. 形成一个统一可回收的“后果账本”
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
appendConsequenceRecord(params)
|
||||
buildConsequenceLedgerSummary(params)
|
||||
```
|
||||
|
||||
这是第四阶段最重要的全局语义层之一。
|
||||
|
||||
## 7.4 `companionResolutionDirector.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 根据 `CompanionArcState + reactions + key consequences`
|
||||
决定队友线的最终收束状态
|
||||
2. 输出:
|
||||
- bonded
|
||||
- reconciled
|
||||
- estranged
|
||||
- departed
|
||||
- sacrificed
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
resolveCompanionResolution(params)
|
||||
resolveAllCompanionResolutions(params)
|
||||
```
|
||||
|
||||
## 7.5 `endingResolver.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 综合:
|
||||
- 主线程结局
|
||||
- 队友收束
|
||||
- faction tension
|
||||
- consequence ledger
|
||||
2. 生成最终 `EndingState`
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
resolveEndingState(params)
|
||||
```
|
||||
|
||||
目标:
|
||||
|
||||
- 真正形成“经典 RPG 结局体验”
|
||||
|
||||
## 7.6 `epilogueComposer.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 为结局后生成尾声摘要
|
||||
2. 回收:
|
||||
- 关键线程
|
||||
- 队友去向
|
||||
- 世界变化
|
||||
- 玩家留下的长期后果
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildEpilogueSummary(params)
|
||||
```
|
||||
|
||||
## 7.7 `narrativeCodex.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 把当前已有的:
|
||||
- facts
|
||||
- residues
|
||||
- carriers
|
||||
- chronicle
|
||||
- documents
|
||||
组织成玩家可浏览的故事档案系统
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildNarrativeCodex(state)
|
||||
buildCodexSections(state)
|
||||
```
|
||||
|
||||
## 7.8 `authorialConstraintPack.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 把当前题材和 campaign 级作者性要求结构化
|
||||
2. 给 AI generation、ending、setpiece、epilogue 全部提供一致约束
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildAuthorialConstraintPack(params)
|
||||
```
|
||||
|
||||
## 7.9 `branchBudgetPlanner.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 控制 major divergence 数量
|
||||
2. 控制 ending family 数量
|
||||
3. 防止 campaign 后期分支爆炸
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
evaluateBranchBudget(params)
|
||||
```
|
||||
|
||||
## 7.10 `narrativeQaReport.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 汇总 consistency / pacing / payoff / leak / branch budget 等问题
|
||||
2. 输出结构化 QA report
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildNarrativeQaReport(params)
|
||||
```
|
||||
|
||||
## 7.11 `narrativeConsistencyChecks.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 做规则化检查
|
||||
2. 捕捉:
|
||||
- 事实泄露
|
||||
- payoff 缺失
|
||||
- unresolved thread 过多
|
||||
- 角色线断裂
|
||||
- ending 收束不足
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
runNarrativeConsistencyChecks(params)
|
||||
```
|
||||
|
||||
## 8. 现有文件改造方案
|
||||
|
||||
## 8.1 `useStoryGeneration.ts`
|
||||
|
||||
第四阶段这里新增 campaign 层接线:
|
||||
|
||||
1. `campaignDirector`
|
||||
2. `actPlanner`
|
||||
3. `authorialConstraintPack`
|
||||
|
||||
并把结果注入 prompt:
|
||||
|
||||
1. 当前 act
|
||||
2. 当前 campaign 目标
|
||||
3. 当前分支预算压力
|
||||
4. 当前必须回收的 payoff
|
||||
|
||||
## 8.2 `progressionActions.ts`
|
||||
|
||||
这是第四阶段最重要的状态推进点。
|
||||
|
||||
新增职责:
|
||||
|
||||
1. 维护 `CampaignState / ActState`
|
||||
2. 回写 `ConsequenceLedger`
|
||||
3. 解析 `CompanionResolution`
|
||||
4. 在满足条件时触发 `EndingResolver`
|
||||
5. 生成 `NarrativeQaReport`
|
||||
|
||||
## 8.3 `prompt.ts`
|
||||
|
||||
第四阶段改造目标:
|
||||
|
||||
1. prompt 不只是围绕当前章节和旅程
|
||||
2. 还要围绕:
|
||||
- 当前 act
|
||||
- campaign 主命题
|
||||
- 已积累的关键后果
|
||||
- 还必须回收的 payoff
|
||||
- 作者性 constraint pack
|
||||
|
||||
## 8.4 `questFlow.ts`
|
||||
|
||||
第四阶段目标:
|
||||
|
||||
1. 任务不只是 thread / chapter 服务
|
||||
2. 还要进入 act/campaign 层的安排
|
||||
|
||||
至少新增:
|
||||
|
||||
1. act 关键任务
|
||||
2. ending 前置任务
|
||||
3. 队友个人线收束任务
|
||||
|
||||
## 8.5 `npcInteractions.ts`
|
||||
|
||||
第四阶段目标:
|
||||
|
||||
1. 队友/NPC 关系可以进入 resolution 判定
|
||||
2. 支持队友去留和最终站队
|
||||
3. 支持更高权重的不可逆关系变化
|
||||
|
||||
## 8.6 `components/*`
|
||||
|
||||
第四阶段不主打大规模 UI 重做,但建议最小补这些:
|
||||
|
||||
1. `AdventurePanel`
|
||||
- 当前 act / chapter / ending pressure
|
||||
|
||||
2. `CharacterPanel`
|
||||
- companion resolution progress
|
||||
|
||||
3. `InventoryPanel`
|
||||
- narrative codex / document archive 入口
|
||||
|
||||
4. `AdventureEntityModal`
|
||||
- 当前角色的关键 consequence / resolution 片段
|
||||
|
||||
## 9. 第四阶段开发顺序
|
||||
|
||||
建议顺序如下:
|
||||
|
||||
1. `campaignDirector`
|
||||
2. `actPlanner`
|
||||
3. `consequenceLedger`
|
||||
4. `companionResolutionDirector`
|
||||
5. `endingResolver`
|
||||
6. `epilogueComposer`
|
||||
7. `narrativeCodex`
|
||||
8. `authorialConstraintPack`
|
||||
9. `branchBudgetPlanner`
|
||||
10. `narrativeConsistencyChecks`
|
||||
11. `narrativeQaReport`
|
||||
12. UI 最小接线
|
||||
|
||||
原因:
|
||||
|
||||
- 没有 campaign / act,结局和 QA 都无从谈起
|
||||
- 没有 consequence ledger,ending 会继续偏表层组合
|
||||
- 没有 authorial constraints 和 QA,长线内容会越来越漂
|
||||
|
||||
## 10. 测试方案
|
||||
|
||||
## 10.1 新增单元测试
|
||||
|
||||
建议新增:
|
||||
|
||||
1. `campaignDirector.test.ts`
|
||||
2. `actPlanner.test.ts`
|
||||
3. `consequenceLedger.test.ts`
|
||||
4. `companionResolutionDirector.test.ts`
|
||||
5. `endingResolver.test.ts`
|
||||
6. `epilogueComposer.test.ts`
|
||||
7. `narrativeCodex.test.ts`
|
||||
8. `authorialConstraintPack.test.ts`
|
||||
9. `branchBudgetPlanner.test.ts`
|
||||
10. `narrativeConsistencyChecks.test.ts`
|
||||
11. `narrativeQaReport.test.ts`
|
||||
|
||||
## 10.2 新增集成测试
|
||||
|
||||
建议补这 6 类:
|
||||
|
||||
1. 主线程推进到 act 切换
|
||||
2. 关键后果进入 ledger 并影响后续 companion resolution
|
||||
3. 队友个人线收束进入 ending
|
||||
4. ending state 正确聚合主线、队友线、世界状态
|
||||
5. epilogue 能回收关键 threads / companions / world mutations
|
||||
6. QA report 能检测未回收 payoff 或分支超预算
|
||||
|
||||
## 10.3 人工回归场景
|
||||
|
||||
至少做这 6 条:
|
||||
|
||||
1. 一条完整主线从开局跑到结局
|
||||
2. 两名队友在同一 campaign 中走向不同 resolution
|
||||
3. 一个重大选择改变结局基调
|
||||
4. 一条暗线在结局中被正式回收
|
||||
5. 玩家可以查看完整 codex / chronicle / documents
|
||||
6. continue game / ending / epilogue 三个摘要层彼此一致
|
||||
|
||||
## 11. 第四阶段验收标准
|
||||
|
||||
做到以下几点,才算第四阶段可收口:
|
||||
|
||||
1. 系统能维护 `CampaignState + ActState`
|
||||
2. 至少一条完整主线可稳定走到 `EndingState`
|
||||
3. 队友线能稳定产出 `CompanionResolution`
|
||||
4. `ConsequenceLedger` 能真实影响 ending 和 epilogue
|
||||
5. `NarrativeCodex` 可供玩家查看关键故事档案
|
||||
6. 系统能输出结构化 `NarrativeQaReport`
|
||||
7. 分支预算和作者性约束已开始进入 generation 主链
|
||||
8. 相关测试通过,`lint` / `typecheck` / `check:encoding` 通过
|
||||
|
||||
## 12. 一句话结论
|
||||
|
||||
前三阶段让当前项目拥有了“会生成、会推进、会分层、会回响、会制造章节感”的 AI 原生剧情引擎。
|
||||
|
||||
第四阶段要做的,是让它进一步成为:
|
||||
|
||||
**一套能稳定完成整部 RPG campaign、能回收长线伏笔、能产出多幕主线和结局、还能被持续生产和校验的完整叙事系统。**
|
||||
@@ -0,0 +1,676 @@
|
||||
# AI 原生剧情引擎第五阶段技术落地方案
|
||||
|
||||
更新时间:`2026-04-06`
|
||||
|
||||
## 0. 文档目的
|
||||
|
||||
这份方案建立在当前仓库第四阶段已经基本落地的前提上,面向第五阶段的技术推进。
|
||||
|
||||
按当前代码审计结果,第四阶段已经基本把这些 campaign 级能力接进了主链:
|
||||
|
||||
1. `CampaignState`
|
||||
2. `ActState`
|
||||
3. `ConsequenceRecord`
|
||||
4. `CompanionResolution`
|
||||
5. `EndingState`
|
||||
6. `NarrativeCodex`
|
||||
7. `AuthorialConstraintPack`
|
||||
8. `NarrativeQaReport`
|
||||
|
||||
并且这些能力已经开始被:
|
||||
|
||||
- `progressionActions`
|
||||
- `useStoryGeneration`
|
||||
- `prompt.ts`
|
||||
- `AdventurePanel`
|
||||
- `CharacterPanel`
|
||||
- `InventoryPanel`
|
||||
- `AdventureEntityModal`
|
||||
|
||||
实际消费。
|
||||
|
||||
因此第五阶段不再解决:
|
||||
|
||||
- campaign / act 有没有
|
||||
- ending / epilogue 有没有
|
||||
- codex / qa / constraint 有没有
|
||||
|
||||
第五阶段要解决的是:
|
||||
|
||||
**如何让这套已经能完成完整 campaign 的引擎,进一步成为一套可批量生产、可多 campaign 复用、可仿真评估、可玩家画像自适应、可发布运营的叙事平台。**
|
||||
|
||||
一句话说:
|
||||
|
||||
**前四阶段把引擎做成“一部完整 RPG 的叙事系统”,第五阶段要把它做成“可以持续生产很多完整 RPG 体验的叙事平台”。**
|
||||
|
||||
## 1. 第四阶段审计结论
|
||||
|
||||
## 1.1 可以判定为“基本落地”的部分
|
||||
|
||||
按代码和测试情况,第四阶段已经基本落地:
|
||||
|
||||
1. 第四阶段新增模块都已存在并有测试:
|
||||
- `campaignDirector`
|
||||
- `actPlanner`
|
||||
- `consequenceLedger`
|
||||
- `companionResolutionDirector`
|
||||
- `endingResolver`
|
||||
- `epilogueComposer`
|
||||
- `narrativeCodex`
|
||||
- `authorialConstraintPack`
|
||||
- `branchBudgetPlanner`
|
||||
- `narrativeConsistencyChecks`
|
||||
- `narrativeQaReport`
|
||||
|
||||
2. 关键主链已接入:
|
||||
- `useStoryGeneration.ts`
|
||||
- `progressionActions.ts`
|
||||
- `prompt.ts`
|
||||
- `AdventurePanel.tsx`
|
||||
- `CharacterPanel.tsx`
|
||||
- `InventoryPanel.tsx`
|
||||
- `AdventureEntityModal.tsx`
|
||||
- `GameShell.tsx`
|
||||
|
||||
3. 第四阶段相关测试通过:
|
||||
- `campaignDirector.test.ts`
|
||||
- `actPlanner.test.ts`
|
||||
- `consequenceLedger.test.ts`
|
||||
- `companionResolutionDirector.test.ts`
|
||||
- `endingResolver.test.ts`
|
||||
- `epilogueComposer.test.ts`
|
||||
- `narrativeCodex.test.ts`
|
||||
- `authorialConstraintPack.test.ts`
|
||||
- `branchBudgetPlanner.test.ts`
|
||||
- `narrativeConsistencyChecks.test.ts`
|
||||
- `narrativeQaReport.test.ts`
|
||||
|
||||
4. 工程门禁通过:
|
||||
- `lint`
|
||||
- `typecheck`
|
||||
- `check:encoding`
|
||||
|
||||
所以,“第四阶段技术落地方案已经基本落地”这个判断成立。
|
||||
|
||||
## 1.2 第四阶段留下的真实缺口
|
||||
|
||||
虽然第四阶段已经把 campaign 层做出来了,但它还更像“单 campaign 可运行系统”,还没有进入真正的“生产平台”和“高重玩度生态”阶段。
|
||||
|
||||
当前最关键的 8 个缺口是:
|
||||
|
||||
1. `CampaignState / EndingState` 已有,但仍偏单线单实例
|
||||
- 当前更像运行时主战役状态,还没有正式进入“多 campaign 包”和“多 ending family 策略”。
|
||||
|
||||
2. `AuthorialConstraintPack` 已有,但仍偏静态
|
||||
- 目前更像运行时约束快照,还不是可以为不同 campaign / world pack / authorship style 配置的资产层。
|
||||
|
||||
3. `NarrativeQaReport` 已有,但仍偏单次运行内检查
|
||||
- 还没有真正的批量仿真、回归矩阵、发布门禁。
|
||||
|
||||
4. `BranchBudgetPlanner` 已有,但仍偏轻量
|
||||
- 当前更像局部预算检查,不是完整的 campaign 分支运营工具。
|
||||
|
||||
5. 缺少玩家画像与自适应导演
|
||||
- 当前系统很强,但还没有回答:
|
||||
- 这位玩家偏剧情、偏探索、偏队友、偏战斗、偏收集哪一种?
|
||||
- 节奏和推荐内容是否应该因玩家风格而微调?
|
||||
|
||||
6. 缺少多 campaign / 多 scenario 资产化管理
|
||||
- 现在能做出一部完整故事,但还没有正式的:
|
||||
- scenario pack
|
||||
- campaign registry
|
||||
- world pack dependency
|
||||
- reusable story modules
|
||||
|
||||
7. 缺少批量仿真和回放能力
|
||||
- 当前以测试和局部运行验证为主,还没有:
|
||||
- playthrough simulation
|
||||
- branch matrix runner
|
||||
- narrative regression playback
|
||||
|
||||
8. 缺少发布与迭代运营链路
|
||||
- 当前系统适合开发,但还没有:
|
||||
- telemetry
|
||||
- release gate report
|
||||
- save migration manifest
|
||||
- content diff report
|
||||
|
||||
## 1.3 结论
|
||||
|
||||
第一阶段解决“骨架”,第二阶段解决“动态系统”,第三阶段解决“章节与旅程”,第四阶段解决“campaign 完整度”,第五阶段要解决的是:
|
||||
|
||||
**这套引擎能不能从“一次做成一部作品”,升级到“可以持续生产、评估、复用、发布和运营很多部作品”。**
|
||||
|
||||
## 2. 第五阶段目标
|
||||
|
||||
第五阶段只做 5 件事:
|
||||
|
||||
1. 建立 `Scenario Pack / Campaign Registry` 多 campaign 资产体系
|
||||
2. 建立 `Simulation Lab / Regression Matrix` 批量仿真与回放评估体系
|
||||
3. 建立 `Player Style Model / Adaptive Narrative Tuner` 玩家画像与自适应导演体系
|
||||
4. 建立 `Release Gate / Telemetry / Save Migration` 发布运营体系
|
||||
5. 建立 `Narrative Production Platform` 内容复用、依赖管理和版本演化体系
|
||||
|
||||
一句话定义第五阶段:
|
||||
|
||||
**从“完整 campaign 引擎”升级到“可持续生产和运营 campaign 的叙事平台”。**
|
||||
|
||||
## 3. 第五阶段完成定义
|
||||
|
||||
第五阶段完成后,至少要同时满足:
|
||||
|
||||
1. 系统可以同时承载多个 `Scenario Pack / Campaign Pack`
|
||||
2. 不同 campaign 能共享部分叙事模块、队友模板、载体模板、约束包
|
||||
3. 发布前可以跑批量 narrative simulation,而不只靠单点测试
|
||||
4. 系统能识别不同玩家风格,并对节奏、事件权重、推荐内容做有限自适应
|
||||
5. 系统有正式的 `Release Gate Report`
|
||||
6. 版本更新时有 `Save Migration Manifest`
|
||||
7. campaign 之间可以被复用、比较、回归和持续优化
|
||||
|
||||
## 4. 第五阶段范围
|
||||
|
||||
## 4.1 纳入范围
|
||||
|
||||
- `src/services/storyEngine/*`
|
||||
- `src/hooks/story/progressionActions.ts`
|
||||
- `src/hooks/useStoryGeneration.ts`
|
||||
- `src/services/prompt.ts`
|
||||
- `src/services/customWorldBuilder.ts`
|
||||
- `src/services/customWorld.ts`
|
||||
- `src/types/storyEngine.ts`
|
||||
- `src/types/game.ts`
|
||||
- `src/types/customWorld.ts`
|
||||
|
||||
## 4.2 新增模块
|
||||
|
||||
- `src/services/storyEngine/scenarioPackRegistry.ts`
|
||||
- `src/services/storyEngine/campaignPackCompiler.ts`
|
||||
- `src/services/storyEngine/contentDependencyGraph.ts`
|
||||
- `src/services/storyEngine/storySimulationRunner.ts`
|
||||
- `src/services/storyEngine/playthroughMatrixLab.ts`
|
||||
- `src/services/storyEngine/narrativeRegressionReplay.ts`
|
||||
- `src/services/storyEngine/playerStyleProfiler.ts`
|
||||
- `src/services/storyEngine/adaptiveNarrativeTuner.ts`
|
||||
- `src/services/storyEngine/narrativeTelemetry.ts`
|
||||
- `src/services/storyEngine/releaseGateReport.ts`
|
||||
- `src/services/storyEngine/saveMigrationManifest.ts`
|
||||
- `src/services/storyEngine/contentDiffReport.ts`
|
||||
|
||||
## 4.3 第五阶段明确不做
|
||||
|
||||
第五阶段仍不做:
|
||||
|
||||
1. 大规模联网运营后台
|
||||
2. 多人协作编辑器平台
|
||||
3. 商业级可视化内容管理系统
|
||||
4. 实时云端剧情编排服务
|
||||
5. 全自动商业数据分析平台
|
||||
|
||||
原因:
|
||||
|
||||
第五阶段目标是把引擎推进到“可工业化生产和可持续运营”的层级,而不是直接变成完整 SaaS。
|
||||
|
||||
## 5. 第五阶段最小闭环
|
||||
|
||||
建议第五阶段最小闭环为:
|
||||
|
||||
```text
|
||||
ScenarioPackRegistry
|
||||
-> CampaignPackCompiler
|
||||
-> StorySimulationRunner
|
||||
-> PlaythroughMatrixLab
|
||||
-> PlayerStyleProfiler
|
||||
-> AdaptiveNarrativeTuner
|
||||
-> NarrativeTelemetry
|
||||
-> ReleaseGateReport
|
||||
-> SaveMigrationManifest
|
||||
```
|
||||
|
||||
对应到实际价值,就是:
|
||||
|
||||
1. campaign 可以被资产化管理
|
||||
2. 发布前可以批量仿真
|
||||
3. 上线后可以持续调优
|
||||
4. 更新时不会轻易打坏旧存档
|
||||
|
||||
## 6. 数据结构升级方案
|
||||
|
||||
## 6.1 `src/types/storyEngine.ts`
|
||||
|
||||
第五阶段建议新增:
|
||||
|
||||
```ts
|
||||
export interface ScenarioPack {
|
||||
id: string;
|
||||
title: string;
|
||||
version: string;
|
||||
worldPackIds: string[];
|
||||
campaignIds: string[];
|
||||
sharedConstraintPackIds: string[];
|
||||
}
|
||||
|
||||
export interface CampaignPack {
|
||||
id: string;
|
||||
scenarioPackId: string;
|
||||
title: string;
|
||||
authoringStyle: string;
|
||||
campaignStateSeed: CampaignState;
|
||||
actTemplates: ActState[];
|
||||
requiredCompanionIds: string[];
|
||||
}
|
||||
|
||||
export interface PlayerStyleProfile {
|
||||
id: string;
|
||||
preferenceWeights: {
|
||||
story: number;
|
||||
exploration: number;
|
||||
combat: number;
|
||||
companion: number;
|
||||
collection: number;
|
||||
};
|
||||
dominantStyle:
|
||||
| 'story_first'
|
||||
| 'explorer'
|
||||
| 'combat_driver'
|
||||
| 'companion_bond'
|
||||
| 'collector';
|
||||
}
|
||||
|
||||
export interface SimulationRunResult {
|
||||
id: string;
|
||||
scenarioPackId: string;
|
||||
campaignPackId: string;
|
||||
seed: string;
|
||||
endingId?: string | null;
|
||||
activeThreadCountPeak: number;
|
||||
fracturedCompanionCount: number;
|
||||
issueCount: number;
|
||||
summary: string;
|
||||
}
|
||||
|
||||
export interface ReleaseGateReport {
|
||||
generatedAt: string;
|
||||
status: 'pass' | 'warn' | 'block';
|
||||
summary: string;
|
||||
blockingIssues: string[];
|
||||
simulationCoverage: number;
|
||||
}
|
||||
|
||||
export interface SaveMigrationManifest {
|
||||
version: string;
|
||||
requiredTransforms: string[];
|
||||
backwardCompatible: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
并扩展:
|
||||
|
||||
```ts
|
||||
export interface StoryEngineMemoryState {
|
||||
playerStyleProfile?: PlayerStyleProfile | null;
|
||||
simulationRunResults?: SimulationRunResult[];
|
||||
releaseGateReport?: ReleaseGateReport | null;
|
||||
saveMigrationManifest?: SaveMigrationManifest | null;
|
||||
}
|
||||
```
|
||||
|
||||
## 6.2 `src/types/customWorld.ts`
|
||||
|
||||
第五阶段建议扩展:
|
||||
|
||||
```ts
|
||||
interface CustomWorldProfile {
|
||||
scenarioPackId?: string | null;
|
||||
campaignPackId?: string | null;
|
||||
}
|
||||
```
|
||||
|
||||
目的:
|
||||
|
||||
- 让世界档案正式进入 pack 体系
|
||||
|
||||
## 6.3 `src/types/game.ts`
|
||||
|
||||
第五阶段建议扩展:
|
||||
|
||||
```ts
|
||||
interface GameState {
|
||||
activeScenarioPackId?: string | null;
|
||||
activeCampaignPackId?: string | null;
|
||||
}
|
||||
```
|
||||
|
||||
## 7. 模块实现方案
|
||||
|
||||
## 7.1 `scenarioPackRegistry.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 维护多个 `ScenarioPack`
|
||||
2. 让不同 world / campaign / constraint pack 成为正式资产
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
registerScenarioPack(pack)
|
||||
resolveScenarioPack(id)
|
||||
listScenarioPacks()
|
||||
```
|
||||
|
||||
## 7.2 `campaignPackCompiler.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 把现有 campaign 结构编译成标准 `CampaignPack`
|
||||
2. 支持:
|
||||
- 不同 authorial style
|
||||
- 不同 required companions
|
||||
- 不同 ending families
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildCampaignPack(params)
|
||||
compileCampaignFromWorldProfile(params)
|
||||
```
|
||||
|
||||
## 7.3 `contentDependencyGraph.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 维护:
|
||||
- campaign -> world
|
||||
- campaign -> companion
|
||||
- campaign -> thread
|
||||
- campaign -> constraint pack
|
||||
之间的依赖关系
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildContentDependencyGraph(params)
|
||||
```
|
||||
|
||||
## 7.4 `storySimulationRunner.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 跑单条 playthrough 仿真
|
||||
2. 输出:
|
||||
- 走到哪类 ending
|
||||
- 多少线程未回收
|
||||
- 队友收束情况
|
||||
- QA 问题数量
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
runStorySimulation(params)
|
||||
```
|
||||
|
||||
## 7.5 `playthroughMatrixLab.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 用多组 seed、多种选择倾向跑批量仿真
|
||||
2. 汇总:
|
||||
- ending 分布
|
||||
- unresolved thread 峰值
|
||||
- fractured companion 分布
|
||||
- branch budget 压力
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
runPlaythroughMatrix(params)
|
||||
buildMatrixSummary(params)
|
||||
```
|
||||
|
||||
## 7.6 `narrativeRegressionReplay.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 记录关键 playthrough 样本
|
||||
2. 在版本升级后回放,检查 narrative regressions
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
recordReplaySeed(params)
|
||||
replayNarrativeRun(params)
|
||||
```
|
||||
|
||||
## 7.7 `playerStyleProfiler.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 根据玩家行为识别风格画像
|
||||
2. 依据:
|
||||
- 选项偏好
|
||||
- 队友互动密度
|
||||
- 探索行为
|
||||
- 战斗投入
|
||||
- 收集倾向
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildPlayerStyleProfile(state)
|
||||
updatePlayerStyleProfileFromAction(params)
|
||||
```
|
||||
|
||||
## 7.8 `adaptiveNarrativeTuner.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 基于 `PlayerStyleProfile` 微调运行时导演参数
|
||||
2. 允许有限自适应:
|
||||
- 更偏队友戏
|
||||
- 更偏探索残痕
|
||||
- 更偏高压冲突
|
||||
- 更偏调查展开
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
resolveAdaptiveNarrativeBias(params)
|
||||
applyAdaptiveTuningToPromptContext(params)
|
||||
```
|
||||
|
||||
注意:
|
||||
|
||||
- 这里必须是“有限微调”,不能破坏作者性和主命题
|
||||
|
||||
## 7.9 `narrativeTelemetry.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 汇总关键 narrative runtime 指标
|
||||
2. 至少包括:
|
||||
- 平均活跃线程数
|
||||
- 队友反应密度
|
||||
- ending family 分布
|
||||
- unresolved payoff 计数
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
captureNarrativeTelemetry(params)
|
||||
buildTelemetrySnapshot(params)
|
||||
```
|
||||
|
||||
## 7.10 `releaseGateReport.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 把:
|
||||
- QA report
|
||||
- simulation results
|
||||
- branch budget
|
||||
- unresolved threads
|
||||
汇总成正式发布门禁报告
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildReleaseGateReport(params)
|
||||
```
|
||||
|
||||
## 7.11 `saveMigrationManifest.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 为不同版本 story engine state 定义迁移要求
|
||||
2. 确保多 campaign、多版本更新后旧存档还能继续用
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildSaveMigrationManifest(params)
|
||||
applyStoryEngineMigration(params)
|
||||
```
|
||||
|
||||
## 7.12 `contentDiffReport.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 比较两个 campaign/world/constraint pack 版本的差异
|
||||
2. 用于发布前评估改动面
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildContentDiffReport(params)
|
||||
```
|
||||
|
||||
## 8. 现有文件改造方案
|
||||
|
||||
## 8.1 `useStoryGeneration.ts`
|
||||
|
||||
第五阶段新增:
|
||||
|
||||
1. 读取 `PlayerStyleProfile`
|
||||
2. 应用 `AdaptiveNarrativeTuner`
|
||||
3. 把 adaptive bias 注入 prompt
|
||||
|
||||
作用:
|
||||
|
||||
- 让同一套 campaign 在不破坏作者性前提下,对不同玩家风格有更好的适配
|
||||
|
||||
## 8.2 `progressionActions.ts`
|
||||
|
||||
第五阶段重点:
|
||||
|
||||
1. 回写 `PlayerStyleProfile`
|
||||
2. 回写 `SimulationRunResult`(仅调试/实验模式)
|
||||
3. 回写 `ReleaseGateReport`(构建或工具态)
|
||||
4. 维护 `SaveMigrationManifest`
|
||||
|
||||
## 8.3 `prompt.ts`
|
||||
|
||||
第五阶段改造目标:
|
||||
|
||||
1. 增加 adaptive bias 提示
|
||||
2. 增加 authoring style / scenario pack 提示
|
||||
3. 继续控制不要让自适应破坏核心主题和 mandatory payoffs
|
||||
|
||||
## 8.4 `customWorldBuilder.ts` / `customWorld.ts`
|
||||
|
||||
第五阶段目标:
|
||||
|
||||
1. 正式支持 `ScenarioPack / CampaignPack` 资产化
|
||||
2. 支持不同 pack 的约束包和版本号
|
||||
3. 支持 build diff / migration 检查
|
||||
|
||||
## 8.5 `useGamePersistence.ts`
|
||||
|
||||
第五阶段重点:
|
||||
|
||||
1. 引入 `SaveMigrationManifest`
|
||||
2. 对 story engine state 做版本迁移
|
||||
3. 确保多 pack、多版本情况下 continue game 仍安全
|
||||
|
||||
## 9. 第五阶段开发顺序
|
||||
|
||||
建议顺序如下:
|
||||
|
||||
1. `scenarioPackRegistry`
|
||||
2. `campaignPackCompiler`
|
||||
3. `contentDependencyGraph`
|
||||
4. `playerStyleProfiler`
|
||||
5. `adaptiveNarrativeTuner`
|
||||
6. `storySimulationRunner`
|
||||
7. `playthroughMatrixLab`
|
||||
8. `narrativeRegressionReplay`
|
||||
9. `narrativeTelemetry`
|
||||
10. `releaseGateReport`
|
||||
11. `saveMigrationManifest`
|
||||
12. `contentDiffReport`
|
||||
|
||||
原因:
|
||||
|
||||
- 先没有 pack 和依赖图,就无法进入平台化
|
||||
- 先没有 player style profile,就无法做自适应
|
||||
- 先没有 simulation/regression,就无法真正做 release gate
|
||||
|
||||
## 10. 测试方案
|
||||
|
||||
## 10.1 新增单元测试
|
||||
|
||||
建议新增:
|
||||
|
||||
1. `scenarioPackRegistry.test.ts`
|
||||
2. `campaignPackCompiler.test.ts`
|
||||
3. `contentDependencyGraph.test.ts`
|
||||
4. `playerStyleProfiler.test.ts`
|
||||
5. `adaptiveNarrativeTuner.test.ts`
|
||||
6. `storySimulationRunner.test.ts`
|
||||
7. `playthroughMatrixLab.test.ts`
|
||||
8. `narrativeRegressionReplay.test.ts`
|
||||
9. `narrativeTelemetry.test.ts`
|
||||
10. `releaseGateReport.test.ts`
|
||||
11. `saveMigrationManifest.test.ts`
|
||||
12. `contentDiffReport.test.ts`
|
||||
|
||||
## 10.2 新增集成测试
|
||||
|
||||
建议补这 6 类:
|
||||
|
||||
1. 同一 scenario pack 下多 campaign 装载
|
||||
2. 版本更新后旧存档迁移
|
||||
3. 同一 campaign 不同 player style 下的有限自适应
|
||||
4. playthrough matrix 跑出多种 ending family
|
||||
5. release gate 正确拦截高风险版本
|
||||
6. regression replay 能检测 narrative drift
|
||||
|
||||
## 10.3 人工回归场景
|
||||
|
||||
至少做这 6 条:
|
||||
|
||||
1. 同一套世界切两条不同 campaign 运行
|
||||
2. 同一 campaign 用两种玩家风格跑出明显不同的节奏偏重
|
||||
3. 更新版本后旧存档继续游戏
|
||||
4. 运行一批 simulation 并生成 release gate report
|
||||
5. narrative codex 在不同 campaign 间内容不串线
|
||||
6. ending 和 epilogue 在 regression replay 中保持稳定
|
||||
|
||||
## 11. 第五阶段验收标准
|
||||
|
||||
做到以下几点,才算第五阶段可收口:
|
||||
|
||||
1. 系统支持 `ScenarioPack + CampaignPack`
|
||||
2. 系统支持 `PlayerStyleProfile + AdaptiveNarrativeTuner`
|
||||
3. 系统支持批量 `playthrough matrix simulation`
|
||||
4. 系统支持 `ReleaseGateReport`
|
||||
5. 系统支持 `SaveMigrationManifest`
|
||||
6. 系统支持 `NarrativeTelemetry`
|
||||
7. campaign 可以被复用、对比、回归和版本迁移
|
||||
8. 相关测试通过,`lint` / `typecheck` / `check:encoding` 通过
|
||||
|
||||
## 12. 一句话结论
|
||||
|
||||
前四阶段让当前项目拥有了一套从世界图谱到 campaign 收束都能运转的 AI 原生剧情引擎。
|
||||
|
||||
第五阶段要做的,是让它进一步成为:
|
||||
|
||||
**一套能够持续生产多个 campaign、进行批量仿真评估、适配不同玩家风格、支持版本演化和发布门禁的叙事平台。**
|
||||
@@ -0,0 +1,559 @@
|
||||
# AI 原生剧情引擎第六阶段技术落地方案
|
||||
|
||||
更新时间:`2026-04-06`
|
||||
|
||||
## 0. 是否需要第六阶段
|
||||
|
||||
结论先说:
|
||||
|
||||
**需要,但第六阶段不应该继续主要围绕“再加一层 runtime 叙事引擎能力”展开,而应该转向“内容生产、策划协同、仿真可视化、版本治理和持续调优”的平台层。**
|
||||
|
||||
原因很明确:
|
||||
|
||||
按当前代码审计结果,前五阶段已经基本把这些核心能力做出来了:
|
||||
|
||||
1. 世界图谱
|
||||
2. 角色叙事档案
|
||||
3. 信息可见性
|
||||
4. 线程与信号推进
|
||||
5. 队友反应与个人线
|
||||
6. 章节 / 旅程 / 高光导演
|
||||
7. campaign / act / ending / epilogue
|
||||
8. codex / chronicle / QA report
|
||||
9. scenario pack / campaign pack
|
||||
10. simulation / regression / release gate / migration
|
||||
|
||||
这说明:
|
||||
|
||||
- “引擎能力不够”已经不是最核心的问题了
|
||||
- 接下来最大的瓶颈会变成:
|
||||
- 内容生产效率
|
||||
- 策划可控性
|
||||
- 多版本治理
|
||||
- 调优闭环
|
||||
- 让设计师和内容作者能真正驾驭这套系统
|
||||
|
||||
所以第六阶段不是 “story engine phase 6 = 再造一个新 runtime 层”,而是:
|
||||
|
||||
**让这套引擎从“强大的技术系统”,进化成“可被持续使用的剧情生产系统”。**
|
||||
|
||||
## 1. 第五阶段审计结论
|
||||
|
||||
## 1.1 可以判定为“基本落地”的部分
|
||||
|
||||
按代码和测试情况,第五阶段已经基本落地:
|
||||
|
||||
1. 第五阶段模块已存在并有测试:
|
||||
- `scenarioPackRegistry`
|
||||
- `campaignPackCompiler`
|
||||
- `contentDependencyGraph`
|
||||
- `storySimulationRunner`
|
||||
- `playthroughMatrixLab`
|
||||
- `narrativeRegressionReplay`
|
||||
- `playerStyleProfiler`
|
||||
- `adaptiveNarrativeTuner`
|
||||
- `narrativeTelemetry`
|
||||
- `releaseGateReport`
|
||||
- `saveMigrationManifest`
|
||||
- `contentDiffReport`
|
||||
|
||||
2. 关键主链已接入:
|
||||
- `progressionActions.ts`
|
||||
- `useStoryGeneration.ts`
|
||||
- `prompt.ts`
|
||||
- `customWorldBuilder.ts`
|
||||
- `useGamePersistence.ts`
|
||||
|
||||
3. 第五阶段相关测试通过:
|
||||
- `scenarioPackRegistry.test.ts`
|
||||
- `campaignPackCompiler.test.ts`
|
||||
- `contentDependencyGraph.test.ts`
|
||||
- `storySimulationRunner.test.ts`
|
||||
- `playthroughMatrixLab.test.ts`
|
||||
- `narrativeRegressionReplay.test.ts`
|
||||
- `playerStyleProfiler.test.ts`
|
||||
- `adaptiveNarrativeTuner.test.ts`
|
||||
- `narrativeTelemetry.test.ts`
|
||||
- `releaseGateReport.test.ts`
|
||||
- `saveMigrationManifest.test.ts`
|
||||
- `contentDiffReport.test.ts`
|
||||
|
||||
## 1.2 当前真实缺口
|
||||
|
||||
虽然第五阶段已经把“平台化骨架”做出来了,但它还明显偏:
|
||||
|
||||
1. 后台能力
|
||||
2. 内部结构
|
||||
3. 代码级接口
|
||||
|
||||
还没有真正形成下面这些“生产工作台”能力:
|
||||
|
||||
1. 设计师 / 内容作者可视化地理解:
|
||||
- 当前 world pack
|
||||
- 当前 campaign pack
|
||||
- 当前 branch budget
|
||||
- 当前 unresolved payoff
|
||||
|
||||
2. 仿真结果可视化与比对
|
||||
- 现在能跑 simulation,但还缺:
|
||||
- matrix dashboard
|
||||
- ending 分布图
|
||||
- unresolved thread 热区
|
||||
- companion fracture 热图
|
||||
|
||||
3. 人机协同编辑闭环
|
||||
- 当前可以生成、回归、校验,但还缺:
|
||||
- 人工批注
|
||||
- 审核通过 / 驳回
|
||||
- 局部重生成
|
||||
- 受控覆盖
|
||||
|
||||
4. 内容治理体系
|
||||
- 当前 pack 可以存在,但还缺:
|
||||
- 版本状态
|
||||
- 草稿 / 候选 / 已发布
|
||||
- 回滚
|
||||
- 依赖冲突提示
|
||||
|
||||
5. 面向策划的 narrative ops
|
||||
- 当前 QA report 存在,但还缺:
|
||||
- 每日 / 每版本比较
|
||||
- 关键指标趋势
|
||||
- 哪条线程最常断
|
||||
- 哪个 ending 最少触发
|
||||
|
||||
## 1.3 额外需要注意的现实问题
|
||||
|
||||
本轮审计里还有一个工程事实需要单独记下:
|
||||
|
||||
- 第五阶段相关测试通过
|
||||
- 但当前全仓 `lint` 仍不是完全绿色,存在 import 排序和未使用导入问题
|
||||
|
||||
这说明:
|
||||
|
||||
**从第六阶段开始,除了继续扩功能,更应该把“生产平台自己的门禁和治理”一起正式纳入。**
|
||||
|
||||
## 2. 第六阶段目标
|
||||
|
||||
第六阶段只做 5 件事:
|
||||
|
||||
1. 建立 `Narrative Studio Workspace` 剧情工作台
|
||||
2. 建立 `Simulation Dashboard / Regression Review` 仿真与回归可视化
|
||||
3. 建立 `Human-in-the-loop Authoring Flow` 人机协同创作流
|
||||
4. 建立 `Pack Governance / Publish Workflow` 内容治理与发布流
|
||||
5. 建立 `Narrative Ops` 指标、比较、告警与持续调优流
|
||||
|
||||
一句话定义第六阶段:
|
||||
|
||||
**从“叙事平台”升级到“叙事生产系统”。**
|
||||
|
||||
## 3. 第六阶段完成定义
|
||||
|
||||
第六阶段完成后,至少要同时满足:
|
||||
|
||||
1. 设计师不看代码,也能看懂当前 campaign 的结构状态。
|
||||
2. 可以用可视化方式查看 simulation / regression / release gate 的结果。
|
||||
3. 可以对 AI 产物做人工批注、重生成、局部覆盖和审批。
|
||||
4. `ScenarioPack / CampaignPack` 有正式的版本状态与发布流。
|
||||
5. narrative QA 和 telemetry 不只是生成结果,而是成为可比较、可追踪、可告警的运营资产。
|
||||
|
||||
## 4. 第六阶段范围
|
||||
|
||||
## 4.1 纳入范围
|
||||
|
||||
- `src/services/storyEngine/*`
|
||||
- `src/components/*`
|
||||
- `src/components/preset-editor/*`
|
||||
- `src/components/CustomWorldGenerationView.tsx`
|
||||
- `src/components/StateFunctionEditor.tsx`
|
||||
- `src/components/SelectionCustomizationModals.tsx`
|
||||
- `src/services/customWorld.ts`
|
||||
- `src/services/customWorldBuilder.ts`
|
||||
- `src/hooks/useGamePersistence.ts`
|
||||
- `src/types/storyEngine.ts`
|
||||
|
||||
## 4.2 新增模块
|
||||
|
||||
- `src/services/storyEngine/narrativeStudioState.ts`
|
||||
- `src/services/storyEngine/simulationDashboardModel.ts`
|
||||
- `src/services/storyEngine/reviewQueue.ts`
|
||||
- `src/services/storyEngine/regenerationPatchPlan.ts`
|
||||
- `src/services/storyEngine/packPublishWorkflow.ts`
|
||||
- `src/services/storyEngine/packRollbackPlan.ts`
|
||||
- `src/services/storyEngine/narrativeOpsMetrics.ts`
|
||||
- `src/services/storyEngine/narrativeAlerting.ts`
|
||||
- `src/services/storyEngine/narrativeReviewNotes.ts`
|
||||
- `src/services/storyEngine/qaTrendReport.ts`
|
||||
|
||||
## 4.3 第六阶段明确不做
|
||||
|
||||
第六阶段仍不做:
|
||||
|
||||
1. 全在线多人协同编辑器
|
||||
2. 完整云端数据平台
|
||||
3. 商业 BI 大盘系统
|
||||
4. 全自动策划代理替代人工审核
|
||||
5. 对外开放市场级内容生态
|
||||
|
||||
原因:
|
||||
|
||||
第六阶段的目标是让内部生产真正运转起来,而不是直接做成对外产品平台。
|
||||
|
||||
## 5. 第六阶段最小闭环
|
||||
|
||||
建议第六阶段最小闭环为:
|
||||
|
||||
```text
|
||||
NarrativeStudioState
|
||||
-> SimulationDashboardModel
|
||||
-> ReviewQueue
|
||||
-> RegenerationPatchPlan
|
||||
-> PackPublishWorkflow
|
||||
-> NarrativeOpsMetrics
|
||||
-> QaTrendReport
|
||||
-> NarrativeAlerting
|
||||
```
|
||||
|
||||
对应到实际价值,就是:
|
||||
|
||||
1. 可以看到当前内容状态
|
||||
2. 可以看 simulation 结果
|
||||
3. 可以对问题内容提出修复
|
||||
4. 可以受控发布和回滚
|
||||
5. 可以持续观察质量变化
|
||||
|
||||
## 6. 数据结构升级方案
|
||||
|
||||
## 6.1 `src/types/storyEngine.ts`
|
||||
|
||||
第六阶段建议新增:
|
||||
|
||||
```ts
|
||||
export interface NarrativeReviewNote {
|
||||
id: string;
|
||||
targetId: string;
|
||||
targetType: 'thread' | 'chapter' | 'companion' | 'carrier' | 'ending' | 'pack';
|
||||
note: string;
|
||||
status: 'open' | 'addressed' | 'ignored';
|
||||
}
|
||||
|
||||
export interface ReviewQueueItem {
|
||||
id: string;
|
||||
source: 'qa_report' | 'simulation' | 'manual';
|
||||
priority: 'low' | 'medium' | 'high';
|
||||
summary: string;
|
||||
relatedIds: string[];
|
||||
}
|
||||
|
||||
export interface PackPublishState {
|
||||
packId: string;
|
||||
version: string;
|
||||
status: 'draft' | 'candidate' | 'released' | 'rolled_back';
|
||||
lastPublishedAt?: string | null;
|
||||
}
|
||||
|
||||
export interface NarrativeOpsSnapshot {
|
||||
generatedAt: string;
|
||||
activePackCount: number;
|
||||
releaseGatePassRate: number;
|
||||
unresolvedIssueCount: number;
|
||||
topRiskAreas: string[];
|
||||
}
|
||||
|
||||
export interface QaTrendPoint {
|
||||
label: string;
|
||||
issueCount: number;
|
||||
blockingCount: number;
|
||||
}
|
||||
```
|
||||
|
||||
并扩展:
|
||||
|
||||
```ts
|
||||
export interface StoryEngineMemoryState {
|
||||
reviewNotes?: NarrativeReviewNote[];
|
||||
reviewQueue?: ReviewQueueItem[];
|
||||
publishStates?: PackPublishState[];
|
||||
narrativeOpsSnapshot?: NarrativeOpsSnapshot | null;
|
||||
qaTrend?: QaTrendPoint[];
|
||||
}
|
||||
```
|
||||
|
||||
## 7. 模块实现方案
|
||||
|
||||
## 7.1 `narrativeStudioState.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 聚合当前:
|
||||
- campaign 状态
|
||||
- branch budget
|
||||
- QA report
|
||||
- ending 状态
|
||||
- simulation 结果
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildNarrativeStudioState(params)
|
||||
```
|
||||
|
||||
## 7.2 `simulationDashboardModel.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 把 matrix / replay / telemetry 结果整理成可展示模型
|
||||
2. 输出:
|
||||
- ending 分布
|
||||
- unresolved threads 排行
|
||||
- fracture companion 排行
|
||||
- regression failure 列表
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildSimulationDashboardModel(params)
|
||||
```
|
||||
|
||||
## 7.3 `reviewQueue.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 把 QA、simulation、手工批注统一收敛成 review queue
|
||||
2. 支持优先级排序与状态流转
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildReviewQueue(params)
|
||||
advanceReviewQueueItem(params)
|
||||
```
|
||||
|
||||
## 7.4 `regenerationPatchPlan.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 把 review item 转成局部重生成 / 局部 override 计划
|
||||
2. 支持:
|
||||
- 角色档案重生成
|
||||
- 线程补偿
|
||||
- ending 修复
|
||||
- 文书 / 载体文本修复
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildRegenerationPatchPlan(params)
|
||||
```
|
||||
|
||||
## 7.5 `packPublishWorkflow.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 管理 pack 的发布状态
|
||||
2. 要求:
|
||||
- 发布前通过 release gate
|
||||
- 生成 publish record
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
advancePackPublishState(params)
|
||||
canPublishPack(params)
|
||||
```
|
||||
|
||||
## 7.6 `packRollbackPlan.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 对已发布 pack 生成回滚方案
|
||||
2. 和 `SaveMigrationManifest` 协作
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildPackRollbackPlan(params)
|
||||
```
|
||||
|
||||
## 7.7 `narrativeOpsMetrics.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 聚合 narrative ops 指标
|
||||
2. 输出:
|
||||
- pass rate
|
||||
- issue density
|
||||
- regression stability
|
||||
- ending diversity
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildNarrativeOpsSnapshot(params)
|
||||
```
|
||||
|
||||
## 7.8 `narrativeAlerting.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 对:
|
||||
- release gate blocking
|
||||
- regression drift
|
||||
- unresolved issue spike
|
||||
发出告警
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
evaluateNarrativeAlerts(params)
|
||||
```
|
||||
|
||||
## 7.9 `narrativeReviewNotes.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 让人工可以对:
|
||||
- chapter
|
||||
- ending
|
||||
- thread
|
||||
- companion
|
||||
记录审核笔记
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
appendNarrativeReviewNote(params)
|
||||
resolveNarrativeReviewNote(params)
|
||||
```
|
||||
|
||||
## 7.10 `qaTrendReport.ts`
|
||||
|
||||
职责:
|
||||
|
||||
1. 把多次 QA report 做趋势比较
|
||||
2. 输出:
|
||||
- issue 趋势
|
||||
- block 趋势
|
||||
- 最常出问题区域
|
||||
|
||||
建议导出:
|
||||
|
||||
```ts
|
||||
buildQaTrendReport(params)
|
||||
```
|
||||
|
||||
## 8. 现有文件改造方案
|
||||
|
||||
## 8.1 `progressionActions.ts`
|
||||
|
||||
第六阶段重点:
|
||||
|
||||
1. 回写 `reviewQueue`
|
||||
2. 回写 `narrativeOpsSnapshot`
|
||||
3. 回写 `qaTrend`
|
||||
|
||||
## 8.2 `useStoryGeneration.ts`
|
||||
|
||||
第六阶段重点:
|
||||
|
||||
1. 在 studio/debug 模式下暴露更多状态
|
||||
2. 不污染正式运行时主链
|
||||
|
||||
## 8.3 `CustomWorldGenerationView.tsx`
|
||||
|
||||
建议成为第六阶段的第一个“工作台入口”,用于展示:
|
||||
|
||||
1. 当前 pack
|
||||
2. 当前 release gate
|
||||
3. 当前 QA trend
|
||||
4. 当前 simulation 摘要
|
||||
|
||||
## 8.4 `StateFunctionEditor.tsx` / `preset-editor/*`
|
||||
|
||||
建议逐步增加 narrative review / patch plan 的入口,而不是只做底层数据编辑。
|
||||
|
||||
## 8.5 `useGamePersistence.ts`
|
||||
|
||||
继续强化:
|
||||
|
||||
1. pack version
|
||||
2. migration status
|
||||
3. rollback safety
|
||||
|
||||
## 9. 第六阶段开发顺序
|
||||
|
||||
建议顺序如下:
|
||||
|
||||
1. `reviewQueue`
|
||||
2. `narrativeReviewNotes`
|
||||
3. `simulationDashboardModel`
|
||||
4. `narrativeOpsMetrics`
|
||||
5. `qaTrendReport`
|
||||
6. `packPublishWorkflow`
|
||||
7. `packRollbackPlan`
|
||||
8. `regenerationPatchPlan`
|
||||
9. `narrativeAlerting`
|
||||
10. `narrativeStudioState`
|
||||
11. UI 工作台最小接线
|
||||
|
||||
原因:
|
||||
|
||||
- 第六阶段的重点是让“平台能力真正可操作”
|
||||
- 所以先做 review / dashboard / publish flow,比继续堆 runtime 更有价值
|
||||
|
||||
## 10. 测试方案
|
||||
|
||||
## 10.1 新增单元测试
|
||||
|
||||
建议新增:
|
||||
|
||||
1. `reviewQueue.test.ts`
|
||||
2. `narrativeReviewNotes.test.ts`
|
||||
3. `simulationDashboardModel.test.ts`
|
||||
4. `narrativeOpsMetrics.test.ts`
|
||||
5. `qaTrendReport.test.ts`
|
||||
6. `packPublishWorkflow.test.ts`
|
||||
7. `packRollbackPlan.test.ts`
|
||||
8. `regenerationPatchPlan.test.ts`
|
||||
9. `narrativeAlerting.test.ts`
|
||||
10. `narrativeStudioState.test.ts`
|
||||
|
||||
## 10.2 新增集成测试
|
||||
|
||||
建议补这 5 类:
|
||||
|
||||
1. QA report -> review queue -> patch plan
|
||||
2. simulation matrix -> dashboard -> release gate
|
||||
3. pack candidate -> publish -> rollback
|
||||
4. old save -> migration -> continue game
|
||||
5. 多版本 QA trend 比较
|
||||
|
||||
## 10.3 人工回归场景
|
||||
|
||||
至少做这 5 条:
|
||||
|
||||
1. 打开 narrative 工作台能看懂当前 campaign 状态
|
||||
2. 一次 regression drift 能正确进入 review queue
|
||||
3. 一个 pack 通过 release gate 成功发布
|
||||
4. 一个 pack 发布后可以生成 rollback plan
|
||||
5. 一组 QA trend 能看出问题是在变好还是变坏
|
||||
|
||||
## 11. 第六阶段验收标准
|
||||
|
||||
做到以下几点,才算第六阶段可收口:
|
||||
|
||||
1. 系统具备可视化 narrative studio 状态模型
|
||||
2. 系统具备 review queue 和 review note 流程
|
||||
3. 系统具备 simulation dashboard 模型
|
||||
4. 系统具备 publish / rollback workflow
|
||||
5. 系统具备 narrative ops snapshot 和 QA trend
|
||||
6. 人工审核与 AI 重生成之间形成闭环
|
||||
7. 相关测试通过,`lint` / `typecheck` / `check:encoding` 通过
|
||||
|
||||
## 12. 一句话结论
|
||||
|
||||
如果前五阶段解决的是“把 AI 原生剧情引擎做成一套完整可运行、可发布、可复用的平台”,
|
||||
|
||||
那么第六阶段要解决的,就是:
|
||||
|
||||
**让这套平台真正变成团队可以长期驾驭、持续生产、持续审核、持续迭代的叙事生产系统。**
|
||||
Reference in New Issue
Block a user