Files
Genarrative/docs/technical/CUSTOM_WORLD_AUTO_ASSET_VISIBILITY_FIX_2026-04-20.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

6.8 KiB
Raw Blame History

世界草稿自动资产可见性修复说明 2026-04-20

更新时间:2026-04-20

1. 问题现象

在世界草稿生成完成后,用户反馈:

  1. 草稿里看不到角色主形象
  2. 场景里看不到每一幕的背景图

这类反馈容易被误判成“自动资产没有生成”,但实际排查后发现,问题主要集中在结果页展示链路,同时叠加了一个fallback 资源不可预览的问题。

2. 链路排查结论

本轮检查后确认:

  1. 服务端自动资产服务会把角色主形象写回 draftProfile.playableNpcs[].imageSrc / generatedVisualAssetId
  2. 服务端自动资产服务会把幕背景图写回 draftProfile.sceneChapters[].acts[].backgroundImageSrc / backgroundAssetId
  3. agent draft -> result profile 的适配层也会保留这些字段

真正的问题出在后续两个环节。

3. 根因

3.1 结果页可扮演角色卡优先用了运行时预览

结果页 CustomWorldEntityCatalog 的可扮演角色卡,之前优先显示:

  1. previewCharacter
  2. 再回退到 role.imageSrc

这会导致:

  1. 草稿里已经有真实生成主图
  2. 但界面仍优先渲染模板/运行时预览角色
  3. 用户视觉上看不到最新生成主形象

3.2 场景页没有把多幕背景图真正展示出来

结果页 场景 Tab 之前只展示:

  1. 开局场景
  2. 地点卡

但没有把:

sceneChapterBlueprints[].acts[].backgroundImageSrc

按可见结构渲染到结果页中。

因此即使后端已经生成并回写每一幕背景图,用户仍然只能看到“场景主图/地点图”,看不到“每一幕的图”。

3.3 fallback 自动资产写回的是 .txt

在没有 DashScope 图像能力时,CustomWorldAgentAutoAssetService 的 fallback 生成器之前会写:

  1. 角色主形象:master.txt
  2. 幕背景图:scene.txt

这虽然保证了字段被回写,但前端无法把 .txt 当图片展示,于是会进一步加重“好像没生成”的感知。

3.4 Agent 结果页入口优先读取 legacyResultProfile遮蔽了最新资产字段

世界草稿结果页不是直接读取当前 draftProfile,而是先经过:

  1. buildCustomWorldProfileFromAgentDraft
  2. normalizeCustomWorldProfileRecord

如果 draftProfile.legacyResultProfile 存在,旧逻辑会直接优先返回这份历史编译结果。

但自动资产服务在 Phase3/Phase4 后续补齐时,更新的是当前 draftProfile 中的:

  1. playableNpcs[].imageSrc / generatedVisualAssetId
  2. storyNpcs[].imageSrc / generatedVisualAssetId
  3. landmarks[].imageSrc
  4. sceneChapters[].acts[].backgroundImageSrc / backgroundAssetId

这会导致:

  1. 服务端真实已经生成并回写了最新角色主图和分幕图
  2. 结果页入口却仍然取到一份更早的 legacyResultProfile
  3. 页面看到的是“旧草稿快照”,不是“当前带资产的草稿结果”

因此用户会表现为“完全看不到这轮刚生成出来的图片”。

4. 修复策略

4.1 结果页角色卡优先显示真实生成主图

src/components/CustomWorldEntityCatalog.tsx 中调整逻辑:

  1. role.imageSrc 已存在,则优先显示该图片
  2. 只有在缺失真实主图时,才回退到运行时角色预览

这样可扮演角色卡能直接展示当前草稿回写的角色主形象。

4.2 场景列表改为只展示场景卡,章节内容留在二级页

结合后续体验反馈,本轮又进一步收口了结果页结构:

  1. 结果页 -> 场景列表 不再直接展开章节与分幕内容
  2. 场景列表卡片只负责展示:
    • 场景名
    • 场景摘要
    • 场景图
  3. 场景卡图片优先取该场景章节的首幕 backgroundImageSrc
  4. 若首幕图缺失,再回退到场景主图 / 地标图
  5. 章节标题、幕标题、幕目标等信息只在点击场景后的二级编辑页中查看

这样结果页列表保持清爽,但用户仍然能在列表里直接看到当前场景已生成的图片。

4.3 fallback 改为可显示 PNG

server-node/src/services/customWorldAgentAutoAssetService.ts 中调整 fallback

  1. 不再写 master.txt / scene.txt
  2. 改为写合法可显示的占位 png
  3. prompt 信息单独写进 manifest.json
  4. 角色主形象 fallback PNG 统一输出为 1:1

这样即使当前环境没有真实图像生成能力,草稿层也仍然会回写“前端能直接显示的图片资源”。

4.4 结果页读取 legacy profile 时强制合并当前草稿的最新资产字段

src/services/customWorldAgentDraftResult.ts 中补上合并逻辑:

  1. 若存在 legacyResultProfile,继续保留它的完整运行时字段
  2. 但会把当前 draftProfile 里最新回写的角色主图、地标图、分幕图再覆盖回结果页 profile
  3. 这样结果页既不会丢失旧 runtime profile 的完整结构,也不会再被旧快照遮蔽最新图片资产

这一层修的是结果页真实入口,而不是仅修展示组件。

5. 影响范围

本次修复涉及:

  1. src/components/CustomWorldEntityCatalog.tsx
  2. src/components/CustomWorldResultView.test.tsx
  3. src/services/customWorldAgentDraftResult.test.ts
  4. server-node/src/services/customWorldAgentAutoAssetService.ts
  5. server-node/src/services/customWorldAgentAutoAssetService.test.ts
  6. docs/technical/CUSTOM_WORLD_AUTO_ASSET_VISIBILITY_FIX_2026-04-20.md
  7. 历史 saved profile 资产同步脚本 / 数据修复动作

6. 验收标准

修复后需要满足:

  1. 世界草稿结果页的可扮演角色卡能直接看到生成主形象
  2. 世界草稿结果页的场景列表能直接看到场景图片,且优先展示首幕背景图
  3. 场景章节与分幕内容只在场景二级页中展示
  4. agent draft -> result profile 不会丢失角色主图与幕背景字段
  5. fallback 环境下回写的仍是前端可显示图片,而不是文本文件
  6. 角色主形象 fallback PNG 尺寸必须满足 1:1
  7. 即使存在 legacyResultProfile,结果页也必须展示当前草稿最新同步的角色主图与幕背景图

6.1 历史保存档案补充结论

本轮在真实 PostgreSQL 数据中又确认了一类历史问题:

  1. agent session 中的草稿资产字段可能已经补齐
  2. 但较早时刻自动保存过的 custom_world_profiles.payload_json 仍停留在旧路径
  3. 用户如果从作品库打开的是 saved profile就会继续看到旧图或空图

因此这次修复除了改默认生成与展示逻辑,还需要对受影响的历史 saved profile 做一次同步刷新。

7. 后续建议

后续继续迭代这条链路时,建议保持:

  1. “资产已生成”必须和“用户已看见”同时验证,不能只验证字段回写
  2. 结果页与草稿工作区都要把多幕背景视为正式资产,不要只停留在编辑弹层里
  3. 所有 fallback 资源都应保持为 UI 可直接消费的媒体格式