feat: 完善敲木鱼玩法模板链路

This commit is contained in:
2026-05-24 02:49:13 +08:00
parent 2ba4691bc0
commit 8638397faa
402 changed files with 2329 additions and 1781 deletions

View File

@@ -14,7 +14,7 @@
创作入口 -> 工作台 -> 生成页 -> 结果页 -> 试玩 -> 发布 -> 运行态 -> 公开详情/分享
```
首版默认屏幕中央展示内置卡通透明敲击物图案 `/wooden-fish/default-hit-object.png`。玩家点击运行态非功能区时触发一次敲击:播放敲击音效、敲击物图案执行被敲击动画,并在敲击物上方随机飘出一条祝福词。顶部计数器只在某条祝福词首次出现时创建,之后该词每次出现都累加。计数仅属于当前单次 run不进入账号长期账本。
首版默认屏幕中央展示内置卡通透明敲击物图案 `/wooden-fish/default-hit-object.png`。玩家点击运行态非功能区时触发一次敲击:播放敲击音效、敲击物图案执行被敲击动画,并在敲击物上方随机飘出一条祝福词。顶部只展示总数记录;子项计数收纳到总数卡片下方的折叠面板中,总数卡片点击后展开各子项计数,词条在面板中预置显示,未出现时初始值为 0点击面板外收起。计数仅属于当前单次 run不进入账号长期账本。
## 2. 模板定位
@@ -86,9 +86,9 @@ WF-*
- `slotId=hit-sound`
- `slotType=hit-sound-audio`
- `slotName=敲击音效`
- 来源:`hitSoundPrompt` 生成,或上传/麦克风录制音频
- 来源:用户上传/麦克风录制音频,或使用默认木鱼音
- 写回字段:`hitSoundAsset`
- 描述生成能力:复用通用创作音频接口 `/api/creation/audio/sound-effect` 的 VectorEngine Vidu 音效生成与 OSS 持久化链路
- 默认兜底:`/wooden-fish/default-hit-sound.mp3`
- API 命名空间:
- `/api/creation/wooden-fish/...`
- `/api/runtime/wooden-fish/...`
@@ -122,8 +122,8 @@ WF-*
1. `workDescription`:作品简介;
2. `themeTags[]`:最多 6 个标签;
3. `hitObjectReferenceImageSrc`:上传或历史图引用,只能作为 image2 参考,不可直接进入运行态;
4. `hitSoundPrompt`生成音效描述
5. `hitSoundAsset`:用户上传录音产生的音频资产。
4. `hitSoundPrompt`历史兼容字段,当前创作流程不再使用
5. `hitSoundAsset`:用户上传录音或默认音频资产。
默认祝福词:
@@ -142,39 +142,54 @@ WF-*
## 6. 生成规则
### 6.1 敲击物图案背景环境图
### 6.1 敲击物图案背景环境图与返回按钮图
默认模板在用户未自定义关键词且未上传参考图时,`compile-draft` 使用内置透明 PNG `/wooden-fish/default-hit-object.png` 写回 `hitObjectAsset``generationProvider="bundled-default"`。这张图来自 image2 对原始参考图的卡通风格化重绘,固定为模板默认资源,避免默认关键词在每次生成时改变造型。即使使用内置默认敲击物,首版仍需要生成 `backgroundAsset`,背景环境图使用默认敲击物作为主题和画风参考。
默认模板在用户未自定义关键词且未上传参考图时,`compile-draft` 使用内置透明 PNG `/wooden-fish/default-hit-object.png` 写回 `hitObjectAsset``generationProvider="bundled-default"`。这张图来自 image2 对原始参考图的卡通风格化重绘,固定为模板默认资源,避免默认关键词在每次生成时改变造型。即使使用内置默认敲击物,首版仍需要生成 `backgroundAsset``backButtonAsset`,背景环境图和主题返回按钮图都使用默认敲击物作为主题和画风参考。
用户输入自定义关键词、上传参考图,或在结果页主动重生成敲击物时,`compile-draft``regenerate-hit-object` 必须先为敲击物图案生成 image2 单图资产,再基于新敲击物图案生成背景环境图,并由 `api-server` 注入写回 `hitObjectAsset``backgroundAsset`。前端 action 请求不得自带 `hitObjectAsset``backgroundAsset` 短路生成。如果用户上传参考图,后端只能把该图作为 image2 参考图或主题参考;运行态不得直接使用上传图。
用户输入自定义关键词、上传参考图,或在结果页主动重生成敲击物时,`compile-draft``regenerate-hit-object` 必须先为敲击物图案生成 image2 单图资产,再基于新敲击物图案生成背景环境图,最后基于去绿后的敲击物主体和背景环境图生成主题返回按钮图,并由 `api-server` 注入写回 `hitObjectAsset``backgroundAsset``backButtonAsset`。前端 action 请求不得自带 `hitObjectAsset``backgroundAsset``backButtonAsset` 短路生成。如果用户上传参考图,后端只能把该图作为 image2 参考图或主题参考;运行态不得直接使用上传图。
敲击物图案生成流程固定为:
1. 调用 VectorEngine `/v1/images/edits`,模型固定为 `gpt-image-2`
2. multipart 参考图固定包含默认木鱼图 `/wooden-fish/default-hit-object.png`,作为基础结构和画风参考;
3. 若用户上传参考图,该图只作为新主题参考追加到同一次 image2 edits 请求,不直接进入运行态;
4. 尺寸固定 `1:1`透明底
4. 尺寸固定 `1:1`必须输出绿色背景主体图(纯绿色绿幕),背景为单一纯绿色 `#00FF00`,并显式禁止黑底、白底、棋盘格、纸板底或任何其它实底背景
5. 提示词严格使用:
```text
生成敲木鱼新样式,要求结构,画风与参考图保持高度一致,新样式颜色搭配使用新主题对应的颜色。
生成敲木鱼新样式,要求结构,画风与参考图保持高度一致,新样式颜色搭配使用新主题对应的颜色。尺寸1:1先输出绿色背景主体图纯绿色绿幕背景必须是单一纯绿色 #00FF00 且平整无纹理、无渐变、无阴影、无道具,主体完整居中,主体边缘必须干净,不要直接输出透明底。随后由服务端对绿色背景主体图做抠图去除绿色背景。最终结果只保留单个敲击物图案,禁止黑底、白底、棋盘格、纸板底或任何实底背景;主体本身不要使用与绿幕接近的纯绿色,若新主题天然包含绿色,请改用偏深、偏黄或偏蓝的绿色并与绿幕清晰区分。
新主题为:(用户提供参考图或用户输入关键词)
```
敲击物图案落盘前,`api-server` 必须只对第一步生成的纯绿色绿幕背景执行去绿处理,把绿色背景转成真实透明 alpha PNG不得对黑底、白底或其它未知实底执行泛抠图避免误伤玉米等主体像素。去绿处理必须保留主体内部深色结构和主题细节。
背景环境图生成流程固定为:
1. 调用 VectorEngine `/v1/images/edits`,模型固定为 `gpt-image-2`
2. multipart 参考图固定为第一步新生成的敲击物图案;默认未生成新敲击物时使用内置默认敲击物图案;
2. multipart 参考图固定为第一步敲击物图案抠图完成后的透明图;默认未生成新敲击物时使用内置默认敲击物图案的透明兜底图
3. 尺寸固定竖屏 `9:16`
4. 背景环境图只适配新敲击物主题和画风,背景中不得包含新敲击物本体,也不得增加木槌互动物品;
4. 背景环境图只适配新敲击物主题和画风,背景中不得包含新敲击物本体,也不得增加木槌互动物品;中央主体预留区必须保持干净,画面中央 40% 区域禁止出现主题主体、主体局部特写、主体轮廓影子、重复元素或主题主体的局部碎片;
5. 提示词严格使用:
```text
生成敲木鱼背景,要求主题,画风与参考图保持高度一致,背景元素和颜色搭配与主题对应,木鱼预设在屏幕中央位置,木鱼主体周围元素保持干净,背景氛围围绕外围设计,背景环境图中不包含新木鱼物品,背景氛围中不增加木槌互动物品。
生成敲木鱼背景,要求主题,画风与参考图保持高度一致,背景元素和颜色搭配与主题对应,木鱼预设在屏幕中央位置,木鱼主体周围元素保持干净,背景氛围围绕外围设计,背景环境图中不包含新木鱼物品,背景氛围中不增加木槌互动物品。尺寸竖屏9:16。参考图必须是第一步敲击物抠图完成后的透明图不继承任何绿色底色、绿幕底色或纯绿色画布并要求最终输出完整不透明的背景环境图。中央主体预留区必须保持干净画面中央 40% 区域禁止出现主题主体、主体局部特写、主体轮廓影子、重复元素或主题主体的局部碎片;主题元素只允许出现在外围氛围,不得把主题物品画在画面中央,也不要把主题物品作为背景中心装饰。
主题为:(用户提供参考图或用户输入关键词)
```
落库链路固定为:`api-server` 调用 VectorEngine `/v1/images/edits` -> 服务端上传 OSS 私有对象 -> `confirm_asset_object` 登记资产对象 -> `bind_asset_object_to_entity` 绑定到 `entityKind='wooden_fish_work'`。敲击物绑定 `slot='hit_object'``assetKind='wooden_fish_hit_object'`,背景绑定 `slot='background'``assetKind='wooden_fish_background'`。写回时把 `legacyPublicPath` 分别写入 `hitObjectAsset.imageSrc``backgroundAsset.imageSrc`。不得只拼 `/generated-wooden-fish-assets/...` 占位路径;前端会对 generated legacy path 走 `/api/assets/read-url` 换签OSS 中没有真实对象时图片无法显示。
返回按钮图生成流程固定为:
1. 调用 VectorEngine `/v1/images/edits`,模型固定为 `gpt-image-2`
2. multipart 参考图固定包含第一步去除绿色背景后的敲击物主体图,以及第二步生成的背景环境图;
3. 尺寸固定 `1:1`,必须输出绿色背景主体图(纯绿色绿幕),后端落库前执行同一套去绿背景处理;
4. 按主题、画风、材质和配色生成左上角返回按钮图,但参考图只用于约束圆形底色和中央左箭头的颜色搭配,不得借鉴复杂造型、花纹、浮雕边、异形外框或装饰图案;按钮必须始终是标准圆形,中央只保留单个清晰左箭头或返回箭头,不得包含文字、数字、水印、额外 UI 面板、木槌或敲击道具;
5. 提示词严格使用:
```text
生成敲木鱼左上角返回按钮图。要求以参考图-去除绿色背景后的敲击物主体和背景环境图为主题、画风、材质和配色参考,但参考图只用来约束圆形底色和中央左箭头的颜色搭配,不要继承复杂造型、花纹、浮雕边、异形外框或装饰图案。按钮必须始终是标准圆形,整体像单个圆形图标,圆心居中,圆形内部只保留一个清晰、简洁、居中的向左返回箭头,不要出现文字、数字、水印、按钮外标签、额外 UI 面板、木槌或敲击道具。尺寸1:1输出绿色背景主体图纯绿色绿幕背景必须是单一纯绿色 #00FF00 且平整无纹理、无渐变、无阴影。按钮主体边缘干净,后续由服务端扣除绿色背景;按钮底色不要使用与绿幕接近的纯绿色,若主题天然包含绿色,请仅在圆形底色上使用偏深、偏黄或偏蓝的主题绿色,并用更高对比的箭头颜色区分。
主题为:(用户提供参考图或用户输入关键词)
```
落库链路固定为:`api-server` 调用 VectorEngine `/v1/images/edits` -> 服务端上传 OSS 私有对象 -> `confirm_asset_object` 登记资产对象 -> `bind_asset_object_to_entity` 绑定到 `entityKind='wooden_fish_work'`。敲击物绑定 `slot='hit_object'``assetKind='wooden_fish_hit_object'`,背景绑定 `slot='background'``assetKind='wooden_fish_background'`,返回按钮绑定 `slot='back_button'``assetKind='wooden_fish_back_button'`。写回时把 `legacyPublicPath` 分别写入 `hitObjectAsset.imageSrc``backgroundAsset.imageSrc``backButtonAsset.imageSrc`。不得只拼 `/generated-wooden-fish-assets/...` 占位路径;前端会对 generated legacy path 走 `/api/assets/read-url` 换签OSS 中没有真实对象时图片无法显示。
默认图案要求:
@@ -188,18 +203,18 @@ WF-*
音效统一写回 `hitSoundAsset`
生成或写回规则:
写回规则:
1. 若 payload 已包含上传/录音音频资产,`compile-draft` 跳过音效生成,直接持久化该资产;
2. 若 payload 只包含 `hitSoundPrompt``api-server` 复用通用创作音频能力提交 VectorEngine Vidu `sound_effect` 任务,轮询生成结果,下载音频,写入 OSS 私有对象,登记 `asset_object`,并绑定到 `entityKind='wooden_fish_work'``slot='hit_sound'``assetKind='wooden_fish_hit_sound'`,最后注入 `hitSoundAsset`
3. 若两者都没有,后端生成默认“清脆短促木鱼敲击声”
2. 若 payload 已上传或录制音频,则直接写回 `hitSoundAsset`
3. 若两者都没有,后端写回默认木鱼音 `/wooden-fish/default-hit-sound.mp3`
4. 音效资产必须包含可播放地址、对象键、asset object id、来源和可选时长
5. 通用创作音频接口对 `wooden_fish``hit_sound` 目标不得返回 `410 Gone`对应 `storagePrefix='wooden_fish_assets'`
6. `spacetime-client` 不得自行合成 `/generated-wooden-fish-assets/...` 音效占位路径缺少真实 `hitSoundAsset`必须拒绝编译
5. 通用创作音频接口当前`wooden_fish``hit_sound` 目标返回 `410 Gone`不得在创作流程中按提示词生成音效
6. `spacetime-client` 不得自行合成 `/generated-wooden-fish-assets/...` 音效占位路径缺少真实 `hitSoundAsset`应使用默认木鱼音兜底展示与播放
### 6.3 封面
首版封面使用 `hitObjectAsset.imageSrc` 作为 `coverImageSrc`。背景环境图不作为封面图,不单独新增第三次图片生成
首版封面使用 `hitObjectAsset.imageSrc` 作为 `coverImageSrc`。背景环境图与返回按钮图不作为封面图。
## 7. 契约草案
@@ -213,13 +228,14 @@ WF-*
6. `themeTags[]`
7. `hitObjectPrompt`
8. `hitObjectReferenceImageSrc`
9. `hitSoundPrompt`
9. `hitSoundPrompt`,历史兼容字段,当前创作流程恒为 `null`
10. `floatingWords[]`
11. `hitObjectAsset`
12. `backgroundAsset`
13. `hitSoundAsset`
14. `coverImageSrc`
15. `generationStatus`
13. `backButtonAsset`
14. `hitSoundAsset`
15. `coverImageSrc`
16. `generationStatus`
`WoodenFishImageAsset` 至少包含:
@@ -238,7 +254,7 @@ WF-*
2. `audioSrc`
3. `audioObjectKey`
4. `assetObjectId`
5. `source = generated | uploaded | recorded | placeholder`
5. `source = uploaded | recorded | bundled-default`
6. `prompt`
7. `durationMs`
@@ -277,7 +293,6 @@ GET /api/runtime/wooden-fish/gallery/{publicWorkCode}
```text
compile-draft
regenerate-hit-object
generate-hit-sound
replace-hit-sound
update-work-meta
update-floating-words
@@ -289,19 +304,21 @@ finish
`compile-draft` 是长耗时动作。前端进入生成页后应展示可恢复进度;如果请求失败,标记失败前必须复读 session确认后端是否已经生成并写回草稿。
敲木鱼创作请求在前端必须使用长等待窗口,避免 `createSession``executeAction` 仍沿用共享创作工厂默认的 15 秒超时。因为 `compile-draft` 会串行等待敲击物、背景、返回按钮和 OSS 落库,木鱼 client 需要单独配置与整条 image2 链路匹配的超时。
## 9. SpacetimeDB 表和 view
新增表:
1. `wooden_fish_agent_session`
2. `wooden_fish_work_profile`,其中 `background_asset_json` 保存背景环境图资产快照;
2. `wooden_fish_work_profile`,其中 `background_asset_json` 保存背景环境图资产快照`back_button_asset_json` 保存主题返回按钮图资产快照
3. `wooden_fish_runtime_run`
4. `wooden_fish_event`
新增 view
1. `wooden_fish_gallery_card_view`:公开列表卡片投影,只暴露已发布作品;
2. `wooden_fish_gallery_view`:公开详情兼容投影,包含图案、音效和祝福词配置。
2. `wooden_fish_gallery_view`:公开详情兼容投影,包含图案、背景、返回按钮、音效和祝福词配置。
新增或调整表、procedure、view 后必须同步 `migration.rs`、后端表目录、生成 bindings并执行 `npm run check:spacetime-schema`
@@ -322,11 +339,11 @@ finish
结果页必须支持:
1. 重生成敲击物图案;
2. 生成、上传或替换敲击音效;
2. 上传、录制或替换敲击音效;未提供时使用默认木鱼音;
3. 修改标题、简介和标签;
4. 修改祝福词,最多 8 条。
图案重生成和音效生成是独立局部生成态,不得把已有可查看结果重新变成不可打开的全局生成中。
图案重生成是独立局部生成态,不得把已有可查看结果重新变成不可打开的全局生成中。音效替换只接受上传或录音资产,不触发提示词音效生成。
## 11. 运行态规则
@@ -334,7 +351,7 @@ finish
功能区:
1. 顶部计数器;
1. 顶部总数记录卡和其下拉的子项计数器面板
2. 设置、暂停、返回、发布分享等按钮;
3. 结果弹层和音频授权提示。
@@ -343,11 +360,13 @@ finish
1. 点击非功能区才算一次敲击;
2. 每次敲击立即本地累加 `totalTapCount`
3. 随机等概率从 `floatingWords[]` 中取一个词条;
4. 若词条首次出现,顶部创建对应计数器
4. 子项计数面板中预置展示所有词条,未出现词条初始值为 0
5. 后续同词条出现时对应计数器 +1
6. 播放敲击音效;
7. 敲击物图案执行压缩、回弹或轻微震动动画;
8. 木鱼上方飘出“词条+1”并淡出。
8. 木鱼上方飘出“词条+1”并淡出,飘字只显示文字本体,不加底板、胶囊背景或说明面板
运行态左上角返回按钮必须优先使用 `backButtonAsset` 渲染主题化按钮图;缺失时才回退通用图标按钮。运行态不提供右上角重开按钮。
音频播放:
@@ -367,18 +386,20 @@ finish
## 13. 验收
1. 创作入口能看到 `敲木鱼` 模板;
2. 工作台可以填写敲击物描述、上传参考图、配置音效和祝福词;
2. 工作台可以填写敲击物描述、上传参考图、上传或录制音效、配置祝福词;
3. 提交后按默认木鱼参考图生成 image2 敲击物图案;
4. 提交后按新敲击物图案参考图生成 9:16 背景环境图;
5. 上传图不会直接进入运行态
6. 用户上传或录制音效时跳过音效生成并持久化该资产
7. 结果页能看到背景、图案、试听音效、编辑祝福词并试玩
8. 运行态功能区点击不触发敲击
9. 功能区点击会计数、播放音效、播放敲击动画并飘字
10. 顶部计数器只在词条首次出现时创建
11. 连点不丢计数
12. `checkpoint``finish` 只保存单次 run 摘要
13. 作品可以发布、进入公开列表和公开详情
14. `WF-*` 公开作品号能进入分享和运行态
15. `npm run check:encoding` 通过
16. schema 变更后 `npm run check:spacetime-schema` 通过。
5. 提交后按去绿后的敲击物主体和背景环境图生成主题返回按钮图
6. 上传图不会直接进入运行态
7. 用户上传或录制音效时直接持久化该资产,未提供时使用默认木鱼音
8. 结果页能看到背景、图案、试听音效、编辑祝福词并试玩
9. 运行态功能区点击不触发敲击
10. 运行态左上角使用主题返回按钮图,右上角不出现重开按钮
11. 非功能区点击会计数、播放音效、播放敲击动画并飘出无底板大号文字
12. 顶部总数卡点击后展开子项计数器面板,面板内预置全部词条且未出现词条初始值为 0面板外点击可收起
13. 连点不丢计数
14. `checkpoint``finish` 只保存单次 run 摘要
15. 作品可以发布、进入公开列表和公开详情
16. `WF-*` 公开作品号能进入分享和运行态;
17. `npm run check:encoding` 通过;
18. schema 变更后 `npm run check:spacetime-schema` 通过。