Feat/游戏场景需求v1.0 (#139)
实现[游戏场景需求v1.0](https://kcnz41bksl1c.feishu.cn/wiki/JSF3wdhduinpqhkrVGKcZFp4nng?psg_id=8477599259997387860&refer_index=1&refer_type=citation)。 --------- Co-authored-by: 段舒康 <kdletters@qq.com> Co-authored-by: suzmii <suzmii@foxmail.com> Reviewed-on: http://192.168.35.82/git/GenarrativeAI/Genarrative/pulls/139 Co-authored-by: 董羽秦 <suzmii@qq.com> Co-committed-by: 董羽秦 <suzmii@qq.com>
This commit was merged in pull request #139.
This commit is contained in:
@@ -0,0 +1,166 @@
|
||||
# 图片画布游戏场景生成链路
|
||||
|
||||
更新时间:`2026-08-04`
|
||||
|
||||
## 1. 目标
|
||||
|
||||
在现役图片画布中补齐单张、静态、非分层游戏环境背景的专用生成链路:
|
||||
|
||||
```text
|
||||
首页游戏场景 / 画布底部游戏场景
|
||||
-> 场景专用生成表单
|
||||
-> 后端确定性组装场景 Prompt
|
||||
-> 现有 editor_image_generation 队列与 Worker
|
||||
-> 现有计费、失败、资源持久化和 canvasCompletion
|
||||
```
|
||||
|
||||
本期不是 Agent 工作流,不新增场景 Agent、场景 Worker、场景任务表或场景专属计费系统。
|
||||
|
||||
## 2. 输入和默认值
|
||||
|
||||
用户输入:
|
||||
|
||||
- 必填画面内容。
|
||||
- 视觉风格:日系动画、清透水彩、平面几何、定格模型、自定义。
|
||||
- 自定义风格下必填自定义画风。
|
||||
- 可选用户参考图,沿用普通图片生成的参考图处理能力。
|
||||
- 图片比例、清晰度和图片模型。
|
||||
|
||||
默认值:
|
||||
|
||||
- 图片比例:`16:9`。
|
||||
- 清晰度:`1K`。
|
||||
- 模型:`gemini-3.1-flash-image-preview`,产品展示名沿用现有画布。
|
||||
- 视觉风格:日系动画。
|
||||
- 参考图:无。
|
||||
|
||||
`model`、`aspectRatio`、`imageSize` 继续使用现有编辑器的字符串契约、模型选项、尺寸选项和后端标准化函数,不维护场景专属枚举列表。
|
||||
|
||||
## 3. 前端边界
|
||||
|
||||
前端只保存和提交结构化场景意图,不保存或拼接完整场景 Prompt。
|
||||
|
||||
正式场景状态使用 `GenerateDialogState.mode = "scene"`,不沿用前端壳中的 `generatorVariant = "game-scene"` Demo 标识。
|
||||
|
||||
交接壳复用范围:
|
||||
|
||||
- 画风选择控件、交互和局部样式。
|
||||
- 自定义画风条件输入框。
|
||||
- 底部游戏场景按钮。
|
||||
- 四张固定画风预览图。
|
||||
|
||||
不复用:
|
||||
|
||||
- Demo `App.tsx`。
|
||||
- `setTimeout` 模拟生成。
|
||||
- FileReader Data URL 正式请求。
|
||||
- 复制出的整套画布和缩减版类型。
|
||||
|
||||
四张固定图片只用于前端预览,不进入 `generationReferences`,不随生成请求提交。保留原分辨率,只做轻量无损压缩;画风菜单打开时不同时挂载全部预览图,只在用户悬停、键盘聚焦或点击对应预览入口时按需挂载当前图片。点击同一入口可关闭预览,保证无 hover 的触屏设备可用。
|
||||
|
||||
## 4. API 契约
|
||||
|
||||
主站新增:
|
||||
|
||||
```text
|
||||
POST /api/editor/scenes/generations
|
||||
```
|
||||
|
||||
请求字段:
|
||||
|
||||
```text
|
||||
sceneContent
|
||||
stylePreset
|
||||
customStyle?
|
||||
model?
|
||||
aspectRatio?
|
||||
imageSize?
|
||||
referenceImageSrcs?
|
||||
projectId?
|
||||
generationInputs?
|
||||
assetFolderId?
|
||||
assetLabel?
|
||||
canvasCompletion?
|
||||
```
|
||||
|
||||
请求不接受前端组装后的完整 `prompt`。通用 `/api/editor/images/generations` 与 `/api/external/v1/editor/images/generations` 共用同一边界校验,均拒绝 `kind = scene` 或 `assetKind = scene`,防止调用方绕过结构化字段校验和后端 Prompt 组装。External v1 当前没有场景专用路由,因此不能通过通用图片接口提交结构化场景;主站 `/api/editor/scenes/generations` 构造规范请求后直接复用队列,不经过通用入口校验。
|
||||
|
||||
完整 Provider Prompt 仍只能由后端生成。
|
||||
|
||||
场景参考图沿用普通图片生成的客户端前置门禁,最多 5 张;超限时不得发送 HTTP 请求。场景生成 POST 使用生成专用零重试策略,避免 inline 响应丢失后重复调用 Provider。
|
||||
|
||||
后端对模型、比例和清晰度先沿用 `normalize_editor_generation_options` 标准化,再使用标准化比例决定画幅描述和入队价格。
|
||||
|
||||
## 5. Prompt
|
||||
|
||||
场景 Prompt 在 `server-rs/crates/api-server/src/prompt/editor_scene.rs` 中维护,经 `api-server::prompt` 现役模块出口编译,沿用现有后端 Prompt 常量和 builder 模式,不拆分为运行时文本模板文件,不调用 LLM 润色、扩写或改写。旧 `prompt/scene_background.rs` 属于已退役的自定义世界 / RPG 场景链路,不作为本功能复用入口。
|
||||
|
||||
提示词来源为产品提供的 `scene_prompt.md`:
|
||||
|
||||
- 删除文档章节编号和 `[图片]` 占位。
|
||||
- 保留场景结构约束和四套完整预设风格正文。
|
||||
- 自定义模式只使用用户自定义画风,不附加预设风格正文。
|
||||
- `视觉风格:` 标题只由场景结构模板输出,预设正文不重复携带标题。
|
||||
- 先替换受控的比例和画幅方向,再切分静态用户占位符并一次性拼入画面内容与画风正文;用户输入中的模板占位符按原文保留,不参与后续替换。
|
||||
|
||||
画幅方向按标准化比例映射:
|
||||
|
||||
- `16:9`、`4:3`、`3:2`:横幅。
|
||||
- `1:1`:方形。
|
||||
- `9:16`、`2:3`:竖幅。
|
||||
|
||||
## 6. 队列和计费
|
||||
|
||||
场景请求在后端组装完整 Prompt 后,转换成现有 `EditorImageGenerationRequest`:
|
||||
|
||||
```text
|
||||
kind = scene
|
||||
assetKind = scene
|
||||
prompt = 后端完整 Prompt
|
||||
```
|
||||
|
||||
随后复用 `enqueue_editor_image_generation_for_owner`,队列类型继续是 `editor_image_generation`,Worker 继续执行 `generate_editor_image_for_owner`。
|
||||
|
||||
队列标题固定为“图片画布生成游戏场景”。任务摘要只展示 `generationInputs.fields` 中的“画面内容”,不得把队列 payload 里的后端完整 Prompt 暴露到任务侧栏;历史错误摘要在投影刷新时按同一规则重新派生。`assetLabel` 省略、空字符串或纯空白时统一使用“游戏场景”,不能退回完整 Prompt 作为素材名称。
|
||||
|
||||
计费规则:
|
||||
|
||||
- 前端展示价继续读取 `/api/editor/generation-pricing`。
|
||||
- 入队时按标准化后的模型和清晰度由后端计算并固化 `external_generation_job.price_mud_points`。
|
||||
- Worker 按入队价格扣费,不能在场景接口增加第二层扣费。
|
||||
- `scene` 明确按普通图片模型档位计价。
|
||||
- Provider 失败、执行取消和 lease 耗尽沿用现有扣退费语义。
|
||||
- Provider 成功后的持久化或画布写回失败语义不在本期调整。
|
||||
- inline 响应中的通用生成告警必须在队列终态处理前转发;有项目画布占位但响应缺少权威 `project` 快照时,不得追加本地图层或把占位标记为已完成。
|
||||
- 队列任务进入 `completed` 后,首次项目快照仍可能短暂保留同一 `dialogId` 的 `generating` 占位。场景提交必须把 completion 的 `dialogId` 传给统一项目回读逻辑;首个权威快照仍未收口时做一次有界延迟重读,不能把该快照当作最终状态永久套用。
|
||||
|
||||
## 7. 数据落点
|
||||
|
||||
不修改 SpacetimeDB schema,继续复用:
|
||||
|
||||
- `external_generation_job`。
|
||||
- `editor_canvas_generation_dialog`。
|
||||
- `editor_project_resource`。
|
||||
- `editor_asset`。
|
||||
- `editor_canvas_layer`。
|
||||
- `asset_object` / `asset_entity_binding`。
|
||||
- 现有钱包流水和 `asset_operation_wallet_settlement`。
|
||||
|
||||
字段语义:
|
||||
|
||||
- `prompt`:后端最终提交给图片 Provider 的完整场景 Prompt。
|
||||
- `actual_prompt`:Provider 返回的 actual/revised Prompt。
|
||||
- `asset_kind`:`scene`。
|
||||
- `generation_inputs_json`:画面内容、视觉风格、自定义画风和用户参考图引用。
|
||||
|
||||
## 8. 验收
|
||||
|
||||
- 首页和底部按钮进入同一个场景生成器。
|
||||
- 默认值为 `16:9 / 1K / Banana / 日系动画 / 无参考图`。
|
||||
- 预设顺序和自定义条件输入正确。
|
||||
- 预览图不进入请求参考图。
|
||||
- 前端请求中不存在完整场景 Prompt。
|
||||
- 后端正确组装四种预设、一个自定义风格和三类画幅。
|
||||
- 展示价、入队价、实际扣费和资源成本一致。
|
||||
- 任务复用现有等待、失败、轮询、资源入库和画布添加逻辑。
|
||||
- 场景产物以 `assetKind = scene` 持久化,画布图层右上角显示“场景”标签,不降级为“未知”。
|
||||
Reference in New Issue
Block a user