1
This commit is contained in:
171
docs/technical/RPG_OPENING_CG_MANUAL_GENERATION_2026-05-03.md
Normal file
171
docs/technical/RPG_OPENING_CG_MANUAL_GENERATION_2026-05-03.md
Normal file
@@ -0,0 +1,171 @@
|
||||
# RPG 世界草稿开局 CG 手动生成技术方案(2026-05-03)
|
||||
|
||||
## 1. 背景与本次口径
|
||||
|
||||
本方案落地“RPG 游戏开场 CG”第一版。它继承 `docs/prd/AI_NATIVE_RPG_OPENING_ANIMATION_PRD_2026-04-25.md` 的资产化方向,但本次不采用旧 PRD 中“4 张关键帧 + 3 段视频拼接”的方案,而采用更短的两阶段链路:
|
||||
|
||||
```text
|
||||
世界草稿
|
||||
-> GPT Image 2 生成 3*4 故事板图,2k,16:9
|
||||
-> Seedance 使用故事板作为参考图生成单段 15 秒视频,480p,16:9
|
||||
-> OSS 保存故事板与成片
|
||||
-> 前端把 openingCg 回写到当前世界草稿 profile
|
||||
```
|
||||
|
||||
本次明确不在生成世界草稿时自动生成开局 CG。入口只放在世界草稿结果页的世界 Tab,由用户手动触发。
|
||||
|
||||
## 2. 用户体验
|
||||
|
||||
1. 世界 Tab 展示一个轻量的“开局 CG”资产槽。
|
||||
2. 未生成时只提供手动生成按钮。
|
||||
3. 生成中展示阶段状态和进度,不把规则说明长文写进 UI。
|
||||
4. 生成成功后展示视频预览和重新生成按钮。
|
||||
5. 每次点击生成扣 `80` 积分,失败自动退款。
|
||||
6. UI 预计等待文案为 `预计 10 分钟`,真实等待由后端同步请求完成后返回。
|
||||
7. 只在世界草稿中手动生成;世界底稿、角色图、幕背景图自动补齐流程不生成开局 CG。
|
||||
|
||||
## 3. 数据结构
|
||||
|
||||
在 `CustomWorldProfile` 新增可选字段:
|
||||
|
||||
```ts
|
||||
type CustomWorldOpeningCgStatus =
|
||||
| 'not_started'
|
||||
| 'storyboard_generating'
|
||||
| 'video_generating'
|
||||
| 'ready'
|
||||
| 'failed';
|
||||
|
||||
type CustomWorldOpeningCgProfile = {
|
||||
id: string;
|
||||
status: CustomWorldOpeningCgStatus;
|
||||
storyboardImageSrc?: string | null;
|
||||
storyboardAssetId?: string | null;
|
||||
videoSrc?: string | null;
|
||||
videoAssetId?: string | null;
|
||||
posterImageSrc?: string | null;
|
||||
posterAssetId?: string | null;
|
||||
storyboardPrompt?: string | null;
|
||||
videoPrompt?: string | null;
|
||||
imageModel: 'gpt-image-2';
|
||||
videoModel: string;
|
||||
aspectRatio: '16:9';
|
||||
imageSize: '2k';
|
||||
videoResolution: '480p';
|
||||
durationSeconds: 15;
|
||||
pointCost: 80;
|
||||
estimatedWaitMinutes: 10;
|
||||
generatedAt?: string | null;
|
||||
updatedAt: string;
|
||||
errorMessage?: string | null;
|
||||
};
|
||||
```
|
||||
|
||||
该字段保存在现有 profile JSON 内,不新增 SpacetimeDB 表字段。发布与保存沿用当前 `profile_payload_json` 整包存储能力。
|
||||
|
||||
## 4. 后端接口
|
||||
|
||||
新增接口:
|
||||
|
||||
```text
|
||||
POST /api/runtime/custom-world/opening-cg
|
||||
```
|
||||
|
||||
请求:
|
||||
|
||||
```ts
|
||||
type GenerateCustomWorldOpeningCgRequest = {
|
||||
profile: CustomWorldProfile;
|
||||
};
|
||||
```
|
||||
|
||||
响应:
|
||||
|
||||
```ts
|
||||
type GenerateCustomWorldOpeningCgResponse = {
|
||||
openingCg: CustomWorldOpeningCgProfile;
|
||||
};
|
||||
```
|
||||
|
||||
接口职责:
|
||||
|
||||
1. 校验登录态与 profile 基本结构。
|
||||
2. 校验至少存在可扮演角色、世界基调、世界概述、核心冲突和首个场景第一幕背景图。
|
||||
3. 使用 `execute_billable_asset_operation_with_cost(..., 80, ...)` 做预扣和失败退款。
|
||||
4. 生成故事板图片并持久化为 `custom_world_opening_cg_storyboard` 资产。
|
||||
5. 使用故事板图作为 Seedance 参考图生成视频并持久化为 `custom_world_opening_cg_video` 资产。
|
||||
6. 返回可直接合并进 profile 的 `openingCg`。
|
||||
|
||||
## 5. 提示词
|
||||
|
||||
### 5.1 故事板
|
||||
|
||||
图片模型固定使用 `gpt-image-2`,尺寸语义为 `2k`、`16:9`,当前 APIMart/OpenAI 兼容入口用 `2048x1152` 作为下游 size。
|
||||
|
||||
模板:
|
||||
|
||||
```text
|
||||
以3*4网格格式创建故事板,16:9。像素风角色扮演游戏开场动画CG。
|
||||
|
||||
故事流程:先展示角色,展示故事背景,然后表现核心冲突,最后衔接开局场景
|
||||
故事基调:{世界草稿.tone}
|
||||
|
||||
玩家扮演:将玩家扮演角色作为角色参考图并引用世界草稿中的角色简介
|
||||
故事背景:{世界草稿.summary}
|
||||
核心冲突:{世界草稿.coreConflicts}
|
||||
开局场景:将首个场景的第一幕背景图作为参考图
|
||||
```
|
||||
|
||||
参考图:
|
||||
|
||||
1. 玩家扮演角色使用第一个可扮演角色的 `imageSrc`。
|
||||
2. 开局场景使用 `sceneChapterBlueprints[0].acts[0].backgroundImageSrc`。
|
||||
3. 若缺少任一参考图,返回可理解错误,不降级到无参考图生成。
|
||||
|
||||
### 5.2 视频
|
||||
|
||||
视频模型复用当前 Ark Seedance 配置,分辨率 `480p`,比例 `16:9`,时长 `15` 秒。
|
||||
|
||||
提示词固定:
|
||||
|
||||
```text
|
||||
利用参考图作为故事板,生成一段连贯的动画,没有旁白
|
||||
```
|
||||
|
||||
请求参数必须开启生成音频与联网搜索。若当前上游字段名存在差异,后端在 Ark 请求体中以 `audio` / `generate_audio` / `web_search` 的兼容布尔字段表达,保证不会影响现有角色动画接口。
|
||||
|
||||
开局 CG 视频链路的上游等待窗口不得低于 `10` 分钟,以匹配产品侧“预计 10 分钟”的展示口径。
|
||||
|
||||
## 6. 资产与计费
|
||||
|
||||
资产写入:
|
||||
|
||||
| 产物 | assetKind | entityKind | slot |
|
||||
| --- | --- | --- | --- |
|
||||
| 故事板图 | `custom_world_opening_cg_storyboard` | `custom_world_profile` | `opening_cg_storyboard` |
|
||||
| 成片视频 | `custom_world_opening_cg_video` | `custom_world_profile` | `opening_cg_video` |
|
||||
|
||||
计费:
|
||||
|
||||
1. 每次点击生成消耗 `80` 积分。
|
||||
2. 故事板生成失败、视频任务创建失败、轮询失败、下载失败或 OSS 持久化失败都退款。
|
||||
3. 扣费流水的 asset id 使用本次 opening CG id,避免同一次请求重试重复扣费。
|
||||
|
||||
## 7. 前端落点
|
||||
|
||||
1. `CustomWorldEntityCatalog` 在世界 Tab 增加开局 CG 槽。
|
||||
2. `rpgCreationAssetClient` 新增 `generateOpeningCg`。
|
||||
3. `RpgCreationResultViewImpl` 持有生成中状态,生成完成后 `onProfileChange({ ...profile, openingCg })`。
|
||||
4. 视频展示使用签名 URL 读取组件,不把签名 URL 写入 profile。
|
||||
5. 草稿生成时不调用该接口。
|
||||
|
||||
## 8. 验收点
|
||||
|
||||
1. 新草稿生成完成后 `openingCg` 为空或不存在。
|
||||
2. 世界 Tab 可以手动生成开局 CG。
|
||||
3. 生成请求 payload 包含角色参考图与开局第一幕背景图。
|
||||
4. 故事板请求使用 `gpt-image-2`、`2048x1152`/`2k` 语义、`16:9`。
|
||||
5. 视频请求使用 Seedance、`480p`、`16:9`、`15` 秒,并传入故事板参考图。
|
||||
6. 单次生成扣 `80` 积分,任一失败路径退款。
|
||||
7. 生成成功后 profile 内出现 `openingCg.videoSrc`,刷新/保存/发布后能保留。
|
||||
8. 视频链路上游超时不低于 `10` 分钟,避免低于产品展示的预计等待时长。
|
||||
Reference in New Issue
Block a user