Files
Genarrative/docs/planning/CUSTOM_WORLD_PROFILE_MAPPING_OPTIMIZATION_PLAN_2026-04-18.md
kdletters cbc27bad4a
Some checks failed
CI / verify (push) Has been cancelled
init with react+axum+spacetimedb
2026-04-26 18:06:23 +08:00

22 KiB
Raw Blame History

世界 Profile 映射优化方案2026-04-18

更新时间:2026-04-18

0. 文档目标

这份文档基于以下结论继续推进:

  • docs/audits/CUSTOM_WORLD_PROFILE_MAPPING_AUDIT_2026-04-18.md 已确认,当前世界 profile 已打通主干映射,但还没有成为“所有预设内容与实时生成规则共同优先读取的单一真相源”。
  • 当前最主要的缺口不是“没有世界设定”,而是“世界设定没有被所有运行时链路以同等强度消费”。
  • 优化重点应优先放在后端运行时消费链、跨题材兼容链、世界级内容对象化三条主线上,而不是继续堆新预设内容。

本文目标不是重复审计结论,而是把问题整理成:

  1. 分优先级的落地改造项
  2. 每一项的目标状态
  3. 需要修改的关键模块
  4. 具体实施步骤
  5. 验收标准
  6. 风险与回滚策略

1. 目标状态

本轮优化完成后,系统应达到以下状态:

  1. CustomWorldProfile 成为预设内容和实时生成规则的统一主数据源。
  2. 前端剧情链、后端任务链、后端物品链消费的是同一套世界语义,而不是“前端懂世界、后端只懂摘要”。
  3. templateWorldType 只承担兼容字段职责,不再主导跨题材世界的角色、场景、怪物和视觉映射。
  4. items / factions / conflicts / threads 不再只是文本种子,而是能驱动运行时行为的结构对象。
  5. landmark、场景、怪物、掉落、任务、奖励之间的对应关系优先由世界 profile 决定,模板补位只在缺口场景下触发。

2. 优先级总览

P0先补“真实消费不完整”的运行时主链

  • 让后端 runtimeItemModule / runtimeQuestModule 接入完整可控的世界 profile 子集。
  • 去掉后端运行时里“伪线程 id 冒充真实线程”的弱映射。
  • 建立后端世界消费 contract统一前后端字段裁剪方式。

P1再补“世界设定被模板压扁”的兼容链与物品链

  • templateWorldType 退回兼容层,不再主导真实映射。
  • 为世界级 items 建立 seed 与引用链,补齐“世界物件图谱”。
  • 让任务奖励、场景宝藏、运行时物品生成优先读取世界物品种子。

P2把文本种子升级为游戏对象

  • majorFactions / coreConflicts 升级成可索引、可关联、可推进的结构对象。
  • 调整 landmark 场景怪物注入逻辑,停止“模板怪物硬补丁”主导场景内容。
  • 让世界冲突、势力归属真正影响任务、场景压力、敌对关系。

P3补齐长尾映射与创作层沉淀

  • 扩展 referenceProfile.roleArchetypes 的来源覆盖,补上 storyNpcs 长尾 archetype。
  • 重新定义 creatorIntent / anchorPack / lockState / anchorContent 中哪些字段需要进入运行时。
  • 为后续第四阶段的世界编辑器、运行时回写和世界演化能力预留稳定接口。

3. 设计原则

  1. 前端只做表现与编排,世界规则解释、任务生成、物品生成、状态持久化都在 Express 后端完成。
  2. 优先改造现有链路与现有类型,不新造平行系统。
  3. 兼容字段只做 fallback不反向主导真实世界内容。
  4. 所有新增结构都必须能同时服务“预设内容生成”和“运行时规则生成”,避免再次分叉。
  5. 每一个优化项都必须带测试入口、验收口径和回滚开关。

4. P0 优化方案:补齐后端真实世界消费链

P0-1建立统一的运行时世界消费 Contract

问题定义

当前前端剧情主链可以拿到较完整的 customWorldProfile,但后端任务与物品模块只消费 { name, summary } 这类瘦身字段,导致同一个世界在不同链路里语义强度不一致。

目标状态

  • 后端所有运行时生成模块统一读取 RuntimeWorldContext
  • RuntimeWorldContext 来源于 CustomWorldProfile 的受控裁剪,而不是各模块各自手写轻量字段。
  • 前后端消费世界信息时,共享同一套字段分层。

关键文件

  • E:\Repos\Genarrative\server-node\src\modules\ai\customWorldOrchestrator.ts
  • E:\Repos\Genarrative\server-node\src\modules\runtime-item\runtimeItemModule.ts
  • E:\Repos\Genarrative\server-node\src\modules\quest\runtimeQuestModule.ts
  • E:\Repos\Genarrative\src\types\customWorld.ts
  • E:\Repos\Genarrative\src\hooks\story\storyContextBuilder.ts

实施步骤

  1. 在后端新增统一的 RuntimeWorldContext 类型与构建函数。
  2. 首批纳入字段:
    • name
    • summary
    • themePack
    • storyGraph
    • knowledgeFacts
    • threadContracts
    • majorFactions
    • coreConflicts
    • ownedSettingLayers.ruleProfile
    • referenceProfile
  3. 在 orchestrator 层完成一次裁剪与归一化,禁止 runtimeItemModuleruntimeQuestModule 自己拼 world summary。
  4. 为后端 prompt 构造器增加“世界上下文来源检查”,缺字段时直接走 fallback 分支并记录日志。
  5. 将前端剧情链现有世界裁剪逻辑与后端世界裁剪逻辑对齐,避免出现同字段两套解释。

前后端职责

  • 前端:只传递当前线程、当前场景、当前 encounter、当前角色状态等调用上下文。
  • 后端:解释世界 profile、构造任务 prompt、构造物品 prompt、产出最终结构化结果。

验收标准

  • 后端任务和物品生成日志中可看到相同世界的 themePack / activeThreads / ruleProfile 已进入 prompt 上下文。
  • 同一世界下,前端剧情 prompt 与后端任务/物品 prompt 的核心势力、冲突、世界基调不再明显割裂。
  • 缺失字段时有稳定 fallback不会因为世界 profile 某块为空直接报错。

风险与回滚

  • 风险:一次性带入字段过多,可能导致 prompt 膨胀。
  • 回滚策略:保留 RuntimeWorldContextLite 开关,出现 token 或稳定性问题时,可按模块退回精简字段集。

P0-2让后端 active threads 读取真实故事线程

问题定义

当前后端运行时物品模块里的 activeThreadIds 只是 thread:${encounter.id}thread:${scene.id} 这类伪 id不是真正来自 storyGraph 的线程对象。

目标状态

  • 后端运行时统一读取真实 storyGraph 线程。
  • 若当前 scene / encounter 未命中真实线程,再进入显式 fallback。
  • 运行时物品、任务奖励、事件物件都能解释“为什么此刻出现”。

关键文件

  • E:\Repos\Genarrative\server-node\src\modules\runtime-item\runtimeItemModule.ts
  • E:\Repos\Genarrative\src\services\storyEngine\worldStoryGraph.ts
  • E:\Repos\Genarrative\src\services\storyEngine\threadContract.ts

实施步骤

  1. 在后端新增 resolveActiveWorldThreads(...),输入 scene、encounter、knowledge facts、runtime memory。
  2. 线程命中优先顺序:
    • 当前 scene 关联线程
    • 当前 encounter / npc 关联线程
    • 当前已激活 threadContracts
    • 当前 knowledgeFacts 所属线程
    • fallback synthetic thread
  3. synthetic thread 必须显式标记 source: fallback,防止伪装成真实世界线程。
  4. 物品与任务模块统一消费 ResolvedThreadRef[],不再直接消费裸字符串 id。

验收标准

  • 后端日志中可区分真实线程与 fallback 线程。
  • 运行时物品说明、任务目标和世界冲突有明确对应,不再只围绕当前场景 id 即时拼接。

风险与回滚

  • 风险:现有 scene / encounter 到 thread 的映射不完整,可能导致命中率不高。
  • 回滚策略:保留 synthetic fallback但必须在日志和结构体中显式标识来源。

P0-3先补基础验证链避免后端世界消费升级后失控

问题定义

世界上下文一旦进入后端主链,后续所有任务和物品生成都将更依赖字段质量;若没有结构化校验,很容易引入“字段有了但解释不一致”的新问题。

目标状态

  • RuntimeWorldContext 建立结构校验与测试样例。
  • 世界映射升级后可以快速回归。

实施步骤

  1. RuntimeWorldContext 增加 schema 校验或最小断言层。
  2. 建立 3 组回归世界:
    • 武侠
    • 现代都市
    • 科幻/魔法混合
  3. 增加任务模块、物品模块的世界消费快照测试。
  4. 对“缺 storyGraph、缺 items、缺 factions”的情况补边界测试。

验收标准

  • 世界消费链新增测试可稳定通过。
  • 新增字段不会让现有预设世界直接失效。

5. P1 优化方案:弱化模板主导,补齐世界物件图谱

P1-1templateWorldType 退回兼容层

问题定义

当前 templateWorldType / compatibilityTemplateWorldType 仍然过度参与角色模板、场景视觉、怪物池、fallback 映射,导致跨题材世界被粗暴压回 WUXIA/XIANXIA

目标状态

  • templateWorldType 仅用于兼容旧模板与最低保底 fallback。
  • 真实映射优先读取 ownedSettingLayersthemePackreferenceProfile、世界表达层信号。
  • 新世界生成不再被强制压成二元题材。

关键文件

  • E:\Repos\Genarrative\server-node\src\modules\ai\customWorldOrchestrator.ts
  • E:\Repos\Genarrative\src\services\customWorldTheme.ts
  • E:\Repos\Genarrative\src\data\customWorldVisuals.ts
  • E:\Repos\Genarrative\src\data\customWorldNpcMonsters.ts
  • E:\Repos\Genarrative\src\data\characterPresets.ts

实施步骤

  1. 梳理所有直接读取 templateWorldType 的模块,按用途拆成:
    • 必须兼容旧内容
    • 实际主导内容生成
  2. 新增 worldFlavorProfile 或等价归一层,从以下信号综合得出世界风味:
    • 世界主题摘要
    • themePack
    • expressionProfile
    • ownedSettingLayers
    • referenceProfile.sceneBuckets
    • referenceProfile.creatureArchetypes
  3. 将视觉、怪物、角色模板选择改为优先读取 worldFlavorProfile
  4. templateWorldType 只在真实信号不足时参与兜底。
  5. 补 5 类题材测试样本:
    • 现代金融
    • 赛博 AI 战争
    • 校园悬疑
    • 海洋奇幻
    • 仙侠科技混合

验收标准

  • 非武侠/仙侠世界不再默认掉进 WUXIA/XIANXIA preset 池。
  • 视觉、怪物、角色原型对同一世界的选择结果更加一致。
  • 旧世界内容仍能被兼容字段兜住。

风险与回滚

  • 风险:移除模板主导后,部分老世界可能暂时失去稳定视觉锚点。
  • 回滚策略:保留兼容开关,允许单模块临时回退到旧模板选择逻辑。

P1-2建立世界级 Item Seed 与 World Item Graph

问题定义

CustomWorldProfile.items 虽然在类型层存在,但主链会主动清空,导致世界级物品图谱缺席,任务奖励、宝藏、掉落、交易更依赖运行时临时生成。

目标状态

  • 世界生成阶段可产出一批结构化 item seeds
  • item seeds 能挂接到 knowledgeFactslandmarksfactionsthreadstreasure hints
  • 运行时物品生成优先从世界级物件图谱中取材,而不是完全现场即兴。

关键文件

  • E:\Repos\Genarrative\server-node\src\modules\ai\customWorldOrchestrator.ts
  • E:\Repos\Genarrative\src\services\customWorldBuilder.ts
  • E:\Repos\Genarrative\src\data\customWorldRuntime.ts
  • E:\Repos\Genarrative\src\services\storyEngine\knowledgeGraph.ts
  • E:\Repos\Genarrative\server-node\src\modules\runtime-item\runtimeItemModule.ts

实施步骤

  1. 停止在主链里无条件把 items 压空。
  2. 新增 WorldItemSeed 结构,最少包含:
    • id
    • name
    • category
    • rarity
    • originType
    • relatedFactionIds
    • relatedThreadIds
    • relatedLandmarkIds
    • knowledgeSummary
  3. 世界生成阶段只产出“有限世界物件 seed”不预生成全量成品装备。
  4. 运行时物品模块新增两段式生成:
    • 先从 WorldItemSeed 中挑选相关 seed
    • 再根据当前场景和奖励语境编译成最终 runtime item
  5. 任务奖励、宝藏提示、交易货单优先引用世界 item seed。

验收标准

  • 同一世界内的物品来源能够被追溯到特定势力、地标或线程。
  • 宝藏、任务奖励和偶发掉落之间开始出现统一世界物件语义。
  • 即使不预生成大量装备,系统也已具备稳定的世界物件骨架。

风险与回滚

  • 风险:若 seed 太多,会拖慢世界生成与存档体积。
  • 回滚策略:限制每个世界的 seed 上限,只保留高价值世界物件骨架。

P1-3统一“任务奖励 / 宝藏 / 掉落 / 交易”的物品取材顺序

问题定义

即使补上世界 items,如果各入口仍各自即时生成,世界物件图谱仍然无法变成真实运行时约束。

目标状态

  • 物品相关入口统一读取同一套 world-first 取材顺序。

实施步骤

  1. 制定统一物品取材优先级:
    • 世界线程相关 seed
    • 当前场景相关 seed
    • 当前势力相关 seed
    • 当前角色 build / 属性补位型 seed
    • 程序化 fallback
  2. 将该顺序接入:
    • runtime item
    • quest reward
    • treasure hint
    • shop inventory
  3. 为每种入口记录 itemSourceType,便于后续审计。

验收标准

  • 不同入口产出的物品不再像来自多个无关池子。
  • 同一阶段的奖励和世界冲突、场景语境具有明显一致性。

6. P2 优化方案:把文本世界升级成可操作对象世界

P2-1majorFactions / coreConflicts 升级成结构对象

问题定义

当前势力与冲突已能进入 ThemePackStoryGraphFactionTensionState,但本质仍偏文本语义层,尚未形成可索引、可归属、可推进的游戏对象。

目标状态

  • faction 成为正式实体。
  • conflict 成为正式实体。
  • NPC、scene、shop、quest、thread 可以明确挂接到 faction/conflict。

关键文件

  • E:\Repos\Genarrative\src\services\storyEngine\themePack.ts
  • E:\Repos\Genarrative\src\services\storyEngine\worldStoryGraph.ts
  • E:\Repos\Genarrative\src\services\storyEngine\factionTensionState.ts
  • E:\Repos\Genarrative\server-node\src\modules\quest\runtimeQuestModule.ts

实施步骤

  1. 新增 WorldFactionWorldConflict 结构类型。
  2. majorFactions 进入标准化流程,最少补:
    • id
    • name
    • publicImage
    • stanceTags
    • homeLandmarkIds
    • relatedNpcIds
  3. coreConflicts 进入标准化流程,最少补:
    • id
    • title
    • parties
    • stakes
    • relatedThreadIds
    • pressureLevel
  4. 任务模块改为先选 conflict再派生 quest intent。
  5. scene / npc / 商店 / 敌对阵营状态优先读取 faction 归属。

验收标准

  • 任一任务都可追溯到某个 faction 或 conflict而不只是笼统“世界 tension”。
  • NPC 与场景可以明确展示势力归属或冲突立场。

风险与回滚

  • 风险:结构化后,旧世界数据可能缺字段。
  • 回滚策略:保留旧字符串字段作为输入源,通过标准化编译器补齐对象字段。

P2-2修正 landmark 场景中的模板怪物硬注入

问题定义

当前 landmark scene 在放入 landmark.sceneNpcIds 对应实体之外,还会从模板怪物池额外拼入敌对实体,导致地标设定与实际战斗实体池出现偏移。

目标状态

  • landmark 场景内容优先由 landmark + storyNpcs + factions + conflicts 决定。
  • 模板怪物仅在内容缺口时补位。
  • 补位结果也必须受世界题材和当前线程约束。

关键文件

  • E:\Repos\Genarrative\src\data\scenePresets.ts
  • E:\Repos\Genarrative\src\data\customWorldNpcMonsters.ts

实施步骤

  1. 将场景实体池拆成三层:
    • 显式指定实体
    • 世界关系推导实体
    • 模板补位实体
  2. 补位触发条件必须显式化,例如:
    • 当前场景无敌对实体
    • 当前任务需要战斗对象
    • 当前地标存在压力标签但无实体承载
  3. 模板补位时必须额外经过:
    • 世界风味过滤
    • faction/conflict 过滤
    • landmark 标签过滤
  4. 记录实体来源,供后续审计。

验收标准

  • landmark 场景中的实体构成更忠于世界原始设定。
  • 非武侠/仙侠世界不再被模板怪物池轻易拖偏。

P2-3让冲突与势力真实进入任务和场景状态推进

问题定义

即使 faction/conflict 对象化,如果任务与场景状态推进仍然只吃文本 tension总体改善也会有限。

目标状态

  • 冲突和势力状态能驱动任务来源、场景压力、敌我关系和奖励语境。

实施步骤

  1. 任务生成先选 conflict再根据 pressureLevelpartystakes 生成目标和阶段。
  2. 场景压力读取当前 conflictfaction tension,决定:
    • 敌对出现概率
    • 商店风格
    • 场景描述张力
  3. 奖励语义优先与 conflict/faction 绑定。

验收标准

  • 同一冲突升温后,任务、场景、物品奖励能出现同步变化。

7. P3 优化方案:补齐长尾 archetype 与创作层沉淀

P3-1扩展 referenceProfile.roleArchetypes 来源

问题定义

当前 roleArchetypes 主要从 playableNpcs.slice(0, 6) 派生,导致可玩角色映射稳定,但长尾 storyNpcs、平民、敌对成员、怪物的 archetype 覆盖不足。

目标状态

  • roleArchetypes 来源覆盖 playableNpcs + storyNpcs
  • 长尾角色也能沉淀为稳定 archetype。

关键文件

  • E:\Repos\Genarrative\src\services\customWorldOwnedSettingLayers.ts
  • E:\Repos\Genarrative\src\services\customWorldReferenceSignals.ts
  • E:\Repos\Genarrative\src\data\characterPresets.ts

实施步骤

  1. 调整 archetype 编译输入,加入 storyNpcs
  2. 按角色用途拆 archetype 桶:
    • playable
    • civilian
    • hostile
    • monster
    • faction member
  3. 为长尾 archetype 增加抽样上限与去重规则,避免噪声过大。

验收标准

  • 非主角型角色在模板选择时命中率更高。
  • 长尾场景角色的表现更稳定,不再过度依赖 heuristics fallback。

P3-2重新定义哪些创作层元数据需要进入运行时

问题定义

creatorIntent / anchorPack / lockState / anchorContent 当前主要停留在创作与编辑器链路,对正式运行时作用较弱。

目标状态

  • 明确区分“只服务创作编辑”的元数据和“应进入运行时约束”的元数据。
  • 防止未来编辑器功能越做越多,但运行时仍读不到关键锚点。

实施步骤

  1. 对四类元数据逐项分层:
    • 创作态专用
    • 编译态可消费
    • 运行时必须消费
  2. 首批建议进入运行时的内容:
    • 不可违背的世界禁令
    • 必须保留的主势力/主线锚点
    • 必须保留的世界表达边界
  3. 将运行时需要消费的部分编译进 ownedSettingLayersRuntimeWorldContext,不要让运行时直接读取编辑器原始字段。

验收标准

  • 世界编辑器中被锁定的高优先级设定,能在任务、剧情、物品和场景中持续生效。
  • 创作层字段不会原样泄漏进运行时,仍保持清晰编译边界。

8. 推荐实施顺序

第一阶段:先打通后端世界消费主链

  1. P0-1 统一 RuntimeWorldContext
  2. P0-2 接入真实线程解析
  3. P0-3 补回归验证链

第二阶段:弱化模板主导,补齐世界物件骨架

  1. P1-1 模板退回兼容层
  2. P1-2 建立世界 item seed
  3. P1-3 统一物品入口取材顺序

第三阶段:把世界对象化

  1. P2-1 faction/conflict 对象化
  2. P2-2 修正 landmark 怪物注入
  3. P2-3 接入任务与场景状态推进

第四阶段:补齐长尾映射与创作层沉淀

  1. P3-1 扩展 archetype 来源
  2. P3-2 明确创作层入运行时边界

9. 里程碑拆分建议

M1世界消费对齐

  • 输出物:RuntimeWorldContext、后端任务/物品世界消费升级、真实线程解析
  • 结果判定:前后端都能围绕同一世界线程与规则说话

M2跨题材映射纠偏

  • 输出物:worldFlavorProfile、模板兼容层瘦身、跨题材测试集
  • 结果判定:现代/科幻/混合题材不再被压回武侠/仙侠

M3世界物件与势力冲突对象化

  • 输出物:WorldItemSeedWorldFactionWorldConflict
  • 结果判定:任务、场景、物品奖励开始围绕世界对象图谱运转

M4长尾稳定化

  • 输出物:扩展 archetype、运行时锚点编译边界
  • 结果判定:长尾 NPC 与世界编辑器高优先级设定都能稳定进入运行时

10. 验收口径

本轮优化建议至少按以下 8 条验收:

  1. 后端任务与物品模块都已消费统一 RuntimeWorldContext
  2. 后端 activeThreadIds 已能区分真实线程与 fallback 线程。
  3. 非武侠/仙侠世界的视觉、怪物、角色模板选择明显更加合理。
  4. 世界 profile 中的 items 已形成有限但真实可用的 item seed 图谱。
  5. faction/conflict 已可被任务、场景、物品奖励直接引用。
  6. landmark 场景的实体池优先由地标与世界对象决定,不再被模板怪物硬主导。
  7. storyNpcs 已进入 archetype 编译链。
  8. 高优先级创作锚点已通过编译层进入运行时,而不是停留在编辑器态。

11. 本轮不建议优先做的事

  • 不建议先扩充更多世界 preset、怪物 preset、场景 preset。
  • 不建议先美化编辑器文案或增加说明性 UI 文本。
  • 不建议在前端直接补更多规则判断,避免继续把世界逻辑留在表现层。
  • 不建议在没有统一后端世界 contract 之前分别微调 quest prompt 和 item prompt。

原因很明确:

当前最缺的不是内容数量,而是“世界设定是否真的被一致消费”。在这一层没补齐前,继续加内容只会把映射偏差放大。


12. 一句话结论

这轮优化最应该优先做的,不是继续往世界编辑器里加更多设定项,而是先把 CustomWorldProfile -> 后端运行时任务/物品 -> 场景/NPC/奖励 这条真实消费主链补齐;只有先把世界 profile 收束成单一真相源,后续跨题材世界、世界级物件、势力冲突和长尾 NPC 映射才会越做越稳。