feat: add wooden fish play template
This commit is contained in:
348
docs/prd/【玩法创作】敲木鱼玩法模板PRD-2026-05-20.md
Normal file
348
docs/prd/【玩法创作】敲木鱼玩法模板PRD-2026-05-20.md
Normal file
@@ -0,0 +1,348 @@
|
||||
# 敲木鱼玩法模板 PRD 2026-05-20
|
||||
|
||||
## 1. 目标
|
||||
|
||||
新增一个可创作、可试玩、可发布的轻量休闲玩法模板:
|
||||
|
||||
```text
|
||||
敲木鱼
|
||||
```
|
||||
|
||||
模板按平台新增玩法 SOP 接入完整闭环:
|
||||
|
||||
```text
|
||||
创作入口 -> 工作台 -> 生成页 -> 结果页 -> 试玩 -> 发布 -> 运行态 -> 公开详情/分享
|
||||
```
|
||||
|
||||
首版默认屏幕中央展示内置卡通透明敲击物图案 `/wooden-fish/default-hit-object.png`。玩家点击运行态非功能区时触发一次敲击:播放敲击音效、敲击物图案执行被敲击动画,并在敲击物上方随机飘出一条祝福词。顶部计数器只在某条祝福词首次出现时创建,之后该词每次出现都累加。计数仅属于当前单次 run,不进入账号长期账本。
|
||||
|
||||
## 2. 模板定位
|
||||
|
||||
模板 ID:
|
||||
|
||||
```text
|
||||
wooden-fish
|
||||
```
|
||||
|
||||
用户展示名:
|
||||
|
||||
```text
|
||||
敲木鱼
|
||||
```
|
||||
|
||||
公开作品号前缀:
|
||||
|
||||
```text
|
||||
WF-*
|
||||
```
|
||||
|
||||
体验关键词:
|
||||
|
||||
1. 单屏点击;
|
||||
2. 轻量解压;
|
||||
3. 飘字反馈;
|
||||
4. 单局累计;
|
||||
5. 可自定义敲击物、敲击音效和祝福词。
|
||||
|
||||
## 3. 与拼图创作流程的复用边界
|
||||
|
||||
可以复用:
|
||||
|
||||
1. 创作入口配置、入口开关和作品架;
|
||||
2. 表单/图片输入工作台;
|
||||
3. 生成过程页和生成中恢复;
|
||||
4. 结果页的返回编辑、局部重生成、试玩、发布;
|
||||
5. 公开列表、公开详情、分享码和推荐流分发;
|
||||
6. 平台资产对象、OSS 私有读取换签和音频资产持久化能力。
|
||||
|
||||
不复用:
|
||||
|
||||
1. 拼图关卡、棋盘、拼块、排行榜和关卡推进语义;
|
||||
2. 跳一跳地块图集和蓄力判定语义;
|
||||
3. 抓大鹅物品消除、五视角图集和容器语义;
|
||||
4. 任何长期功德账本、账号维度排行榜或全局累计。
|
||||
|
||||
## 4. 创作工具平台接入声明
|
||||
|
||||
- 工作台模式:表单/图片输入创作工作台
|
||||
- 创作链路:入口 -> 工作台 -> 生成页 -> 结果页 -> 试玩 -> 发布 -> 运行态
|
||||
- 单图资产槽位:
|
||||
- `slotId=hit-object`
|
||||
- `slotType=hit-object-image`
|
||||
- `slotName=敲击物图案`
|
||||
- 提示词来源:`hitObjectPrompt` 与可选 `hitObjectReferenceImageSrc`
|
||||
- 写回字段:`hitObjectAsset`
|
||||
- 是否允许历史图:允许
|
||||
- 是否允许 AI 重绘:允许;上传图只作为 image2 参考,最终运行态只消费 image2 生成图
|
||||
- 系列素材槽位:无;首版只有单图敲击物,不生成图集
|
||||
- 音频资产槽位:
|
||||
- `slotId=hit-sound`
|
||||
- `slotType=hit-sound-audio`
|
||||
- `slotName=敲击音效`
|
||||
- 来源:`hitSoundPrompt` 生成,或上传/麦克风录制音频
|
||||
- 写回字段:`hitSoundAsset`
|
||||
- 描述生成能力:复用通用创作音频接口 `/api/creation/audio/sound-effect` 的 VectorEngine Vidu 音效生成与 OSS 持久化链路
|
||||
- API 命名空间:
|
||||
- `/api/creation/wooden-fish/...`
|
||||
- `/api/runtime/wooden-fish/...`
|
||||
- 业务真相:
|
||||
- 后端裁决并持久化 session、work profile、发布状态、run 摘要和公开投影;
|
||||
- 前端只负责点击低延迟表现、音频播放、动画、飘字渲染和定期 checkpoint。
|
||||
- 创作工具模式例外:无
|
||||
- 验证命令:
|
||||
- `npm run check:encoding`
|
||||
- `npm run typecheck`
|
||||
- `cargo test -p shared-contracts wooden_fish --manifest-path server-rs/Cargo.toml`
|
||||
- `cargo test -p module-wooden-fish --manifest-path server-rs/Cargo.toml`
|
||||
- `cargo check -p api-server --manifest-path server-rs/Cargo.toml`
|
||||
- `npm run spacetime:generate`
|
||||
- `npm run check:spacetime-schema`
|
||||
- `npm run dev:api-server` 后检查 `/healthz`
|
||||
|
||||
## 5. 创作输入
|
||||
|
||||
工作台提交结构化 payload,不提交聊天消息。
|
||||
|
||||
必填字段:
|
||||
|
||||
1. `templateId = "wooden-fish"`;
|
||||
2. `workTitle`:作品标题;
|
||||
3. `hitObjectPrompt`:用户想敲的对象关键词或描述,默认“默认敲击物图案,圆润木质质感,透明背景”;
|
||||
4. `floatingWords[]`:祝福词,最多 8 条,不填或清空时使用默认祝福词。
|
||||
|
||||
可选字段:
|
||||
|
||||
1. `workDescription`:作品简介;
|
||||
2. `themeTags[]`:最多 6 个标签;
|
||||
3. `hitObjectReferenceImageSrc`:上传或历史图引用,只能作为 image2 参考,不可直接进入运行态;
|
||||
4. `hitSoundPrompt`:生成音效描述;
|
||||
5. `hitSoundAsset`:用户上传或录音产生的音频资产。
|
||||
|
||||
默认祝福词:
|
||||
|
||||
```text
|
||||
幸运
|
||||
健康
|
||||
财富
|
||||
姻缘
|
||||
幸福
|
||||
事业
|
||||
成功
|
||||
功德
|
||||
```
|
||||
|
||||
`floatingWords[]` 保存词条名本身,不保存 `+1` 后缀;运行态每次敲击时再把飘字展示为“词条+1”。
|
||||
|
||||
## 6. 生成规则
|
||||
|
||||
### 6.1 敲击物图案
|
||||
|
||||
默认模板在用户未自定义关键词且未上传参考图时,`compile-draft` 使用内置透明 PNG `/wooden-fish/default-hit-object.png` 写回 `hitObjectAsset`,`generationProvider="bundled-default"`。这张图来自 image2 对原始参考图的卡通风格化重绘,固定为模板默认资源,避免默认关键词在每次生成时改变造型。
|
||||
|
||||
用户输入自定义关键词、上传参考图,或在结果页主动重生成敲击物时,`compile-draft` 与 `regenerate-hit-object` 必须为敲击物图案生成 image2 单图资产,并由 `api-server` 注入写回 `hitObjectAsset`。前端 action 请求不得自带 `hitObjectAsset` 短路生成。如果用户上传参考图,后端只能把该图作为 image2 参考图或编辑输入;运行态不得直接使用上传图。
|
||||
|
||||
落库链路固定为:`api-server` 调用 VectorEngine `gpt-image-2-all` -> 服务端上传 OSS 私有对象 -> `confirm_asset_object` 登记资产对象 -> `bind_asset_object_to_entity` 绑定到 `entityKind='wooden_fish_work'`、`slot='hit_object'`、`assetKind='wooden_fish_hit_object'` -> 把 `legacyPublicPath` 写入 `hitObjectAsset.imageSrc`。不得只拼 `/generated-wooden-fish-assets/...` 占位路径;前端会对 generated legacy path 走 `/api/assets/read-url` 换签,OSS 中没有真实对象时图片无法显示。
|
||||
|
||||
默认图案要求:
|
||||
|
||||
1. 中央主体使用 `/wooden-fish/default-hit-object.png`;
|
||||
2. 透明背景;
|
||||
3. 适合移动端居中展示;
|
||||
4. 不包含 UI、按钮、说明文字、水印或品牌标识;
|
||||
5. 图片主体需留出敲击动画缩放空间。
|
||||
|
||||
### 6.2 敲击音效
|
||||
|
||||
音效统一写回 `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. 若两者都没有,后端生成默认“清脆短促木鱼敲击声”;
|
||||
4. 音效资产必须包含可播放地址、对象键、asset object id、来源和可选时长;
|
||||
5. 通用创作音频接口对 `wooden_fish` 的 `hit_sound` 目标不得返回 `410 Gone`,对应 `storagePrefix='wooden_fish_assets'`;
|
||||
6. `spacetime-client` 不得自行合成 `/generated-wooden-fish-assets/...` 音效占位路径,缺少真实 `hitSoundAsset` 时必须拒绝编译。
|
||||
|
||||
### 6.3 封面
|
||||
|
||||
首版封面使用 `hitObjectAsset.imageSrc` 作为 `coverImageSrc`。不单独新增第三次图片生成。
|
||||
|
||||
## 7. 契约草案
|
||||
|
||||
`WoodenFishDraft` 至少包含:
|
||||
|
||||
1. `templateId = "wooden-fish"`;
|
||||
2. `templateName = "敲木鱼"`;
|
||||
3. `profileId`;
|
||||
4. `workTitle`;
|
||||
5. `workDescription`;
|
||||
6. `themeTags[]`;
|
||||
7. `hitObjectPrompt`;
|
||||
8. `hitObjectReferenceImageSrc`;
|
||||
9. `hitSoundPrompt`;
|
||||
10. `floatingWords[]`;
|
||||
11. `hitObjectAsset`;
|
||||
12. `hitSoundAsset`;
|
||||
13. `coverImageSrc`;
|
||||
14. `generationStatus`。
|
||||
|
||||
`WoodenFishImageAsset` 至少包含:
|
||||
|
||||
1. `assetId`;
|
||||
2. `imageSrc`;
|
||||
3. `imageObjectKey`;
|
||||
4. `assetObjectId`;
|
||||
5. `generationProvider`;
|
||||
6. `prompt`;
|
||||
7. `width`;
|
||||
8. `height`。
|
||||
|
||||
`WoodenFishAudioAsset` 至少包含:
|
||||
|
||||
1. `assetId`;
|
||||
2. `audioSrc`;
|
||||
3. `audioObjectKey`;
|
||||
4. `assetObjectId`;
|
||||
5. `source = generated | uploaded | recorded | placeholder`;
|
||||
6. `prompt`;
|
||||
7. `durationMs`。
|
||||
|
||||
`WoodenFishRunSnapshot` 至少包含:
|
||||
|
||||
1. `runId`;
|
||||
2. `profileId`;
|
||||
3. `ownerUserId`;
|
||||
4. `status = playing | finished`;
|
||||
5. `totalTapCount`;
|
||||
6. `wordCounters[]`;
|
||||
7. `startedAtMs`;
|
||||
8. `updatedAtMs`;
|
||||
9. `finishedAtMs`。
|
||||
|
||||
## 8. API 草案
|
||||
|
||||
HTTP 路由:
|
||||
|
||||
```text
|
||||
POST /api/creation/wooden-fish/sessions
|
||||
GET /api/creation/wooden-fish/sessions/{sessionId}
|
||||
POST /api/creation/wooden-fish/sessions/{sessionId}/actions
|
||||
GET /api/creation/wooden-fish/works/{profileId}
|
||||
POST /api/creation/wooden-fish/works/{profileId}/publish
|
||||
GET /api/runtime/wooden-fish/works/{profileId}
|
||||
POST /api/runtime/wooden-fish/runs
|
||||
POST /api/runtime/wooden-fish/runs/{runId}/checkpoint
|
||||
POST /api/runtime/wooden-fish/runs/{runId}/finish
|
||||
GET /api/runtime/wooden-fish/gallery
|
||||
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
|
||||
publish
|
||||
start-run
|
||||
checkpoint
|
||||
finish
|
||||
```
|
||||
|
||||
`compile-draft` 是长耗时动作。前端进入生成页后应展示可恢复进度;如果请求失败,标记失败前必须复读 session,确认后端是否已经生成并写回草稿。
|
||||
|
||||
## 9. SpacetimeDB 表和 view
|
||||
|
||||
新增表:
|
||||
|
||||
1. `wooden_fish_agent_session`;
|
||||
2. `wooden_fish_work_profile`;
|
||||
3. `wooden_fish_runtime_run`;
|
||||
4. `wooden_fish_event`。
|
||||
|
||||
新增 view:
|
||||
|
||||
1. `wooden_fish_gallery_card_view`:公开列表卡片投影,只暴露已发布作品;
|
||||
2. `wooden_fish_gallery_view`:公开详情兼容投影,包含图案、音效和祝福词配置。
|
||||
|
||||
新增或调整表、procedure、view 后必须同步 `migration.rs`、后端表目录、生成 bindings,并执行 `npm run check:spacetime-schema`。
|
||||
|
||||
## 10. 结果页能力
|
||||
|
||||
结果页必须展示:
|
||||
|
||||
1. 作品标题和简介;
|
||||
2. 敲击物图案;
|
||||
3. 敲击音效试听;
|
||||
4. 祝福词配置;
|
||||
5. 标签;
|
||||
6. 试玩;
|
||||
7. 发布;
|
||||
8. 返回编辑。
|
||||
|
||||
结果页必须支持:
|
||||
|
||||
1. 重生成敲击物图案;
|
||||
2. 生成、上传或替换敲击音效;
|
||||
3. 修改标题、简介和标签;
|
||||
4. 修改祝福词,最多 8 条。
|
||||
|
||||
图案重生成和音效生成是独立局部生成态,不得把已有可查看结果重新变成不可打开的全局生成中。
|
||||
|
||||
## 11. 运行态规则
|
||||
|
||||
运行态采用全屏单击模型。
|
||||
|
||||
功能区:
|
||||
|
||||
1. 顶部计数器;
|
||||
2. 设置、暂停、返回、发布分享等按钮;
|
||||
3. 结果弹层和音频授权提示。
|
||||
|
||||
点击规则:
|
||||
|
||||
1. 点击非功能区才算一次敲击;
|
||||
2. 每次敲击立即本地累加 `totalTapCount`;
|
||||
3. 随机等概率从 `floatingWords[]` 中取一个词条;
|
||||
4. 若词条首次出现,顶部创建对应计数器;
|
||||
5. 后续同词条出现时对应计数器 +1;
|
||||
6. 播放敲击音效;
|
||||
7. 敲击物图案执行压缩、回弹或轻微震动动画;
|
||||
8. 木鱼上方飘出“词条+1”并淡出。
|
||||
|
||||
音频播放:
|
||||
|
||||
1. 前端使用小复音池;
|
||||
2. 设置最小播放间隔,避免极端连点导致浏览器抖动;
|
||||
3. 点击计数不能因为音频节流而丢失;
|
||||
4. 签名 URL 未就绪时先静音表现,不请求裸 generated 私有路径。
|
||||
|
||||
后端只保存 run 摘要,不保存每次点击的完整明细;`checkpoint` 和 `finish` 都写入总敲击次数与词条计数快照。
|
||||
|
||||
## 12. 公开链路
|
||||
|
||||
平台首页推荐、发现、公开详情、搜索、已玩作品和公开试玩统一按 `sourceType='wooden-fish'` 与 `WF-*` 公开作品号识别敲木鱼作品。
|
||||
|
||||
公开列表优先消费 `wooden_fish_gallery_card_view` 订阅缓存。公开详情如果卡片摘要不足以进入运行态,必须补读完整 work profile。
|
||||
|
||||
## 13. 验收
|
||||
|
||||
1. 创作入口能看到 `敲木鱼` 模板;
|
||||
2. 工作台可以填写敲击物描述、上传参考图、配置音效和祝福词;
|
||||
3. 提交后生成 image2 敲击物图案;
|
||||
4. 上传图不会直接进入运行态;
|
||||
5. 用户上传或录制音效时跳过音效生成并持久化该资产;
|
||||
6. 结果页能看到图案、试听音效、编辑祝福词并试玩;
|
||||
7. 运行态功能区点击不触发敲击;
|
||||
8. 非功能区点击会计数、播放音效、播放敲击动画并飘字;
|
||||
9. 顶部计数器只在词条首次出现时创建;
|
||||
10. 连点不丢计数;
|
||||
11. `checkpoint` 和 `finish` 只保存单次 run 摘要;
|
||||
12. 作品可以发布、进入公开列表和公开详情;
|
||||
13. `WF-*` 公开作品号能进入分享和运行态;
|
||||
14. `npm run check:encoding` 通过;
|
||||
15. schema 变更后 `npm run check:spacetime-schema` 通过。
|
||||
Reference in New Issue
Block a user