Merge remote-tracking branch 'origin/codex/wooden-fish-template'

This commit is contained in:
kdletters
2026-05-22 08:09:58 +08:00
617 changed files with 31612 additions and 237 deletions

View File

@@ -0,0 +1,36 @@
# 寓教于乐电视端乐园地图入口概念图
更新时间:`2026-05-18`
## 背景
寓教于乐板块需要一个面向电视端 / 横屏大屏的图形化入口,整体感觉接近主题乐园地图,但必须保留 Genarrative 现有的明亮卡通绘本插画风,不借用任何真实品牌乐园或版权角色。
## 目标
- 远看像一个完整乐园地图,近看能分辨每个玩法入口。
- 入口区域清晰分区,后续可以叠加焦点框、按钮和中文标题。
- 中心和下方保留足够留白,适合遥控器焦点、儿童角色或主推荐位。
- 风格保持和寓教于乐现有草地舞台资源一致。
## 本次概念方向
1. 环形乐园岛:中央草地广场 + 外圈入口环路。
2. 展开绘本地图:横向展开的大绘本页,左右页自然衔接。
3. 云朵空中岛:多个浮岛通过彩虹桥和云朵步道连接。
4. 草地舞台地图:更接近实际运行态的横屏草地入口首屏。
## 推荐方向
优先推荐 `草地舞台地图` 作为后续落地主方向,因为它与现有寓教于乐草地舞台最接近,且中央下方留白最适合后续叠加交互焦点。
## 生图脚本
- 生成脚本:`scripts/generate-edutainment-tv-map-concepts.mjs`
- 默认尺寸:`2048x1152`
- 风格参考:`public/child-motion-demo/picture-book-grass-stage.png`
- 输出目录:`output/imagegen/edutainment-tv-map-entry-concepts-20260518/`
## 说明
本次结果是设计概念稿,不直接进入 `public/` 正式资源目录。后续若要继续细化,可在同一脚本里增加新的横屏变体,并保持“不写文字、不露品牌 IP、绘本插画风”这三条底线。

View File

@@ -0,0 +1,384 @@
# 敲木鱼玩法模板 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=background`
- `slotType=background-image`
- `slotName=背景环境图`
- 提示词来源:第一步生成的敲击物图案与用户原始题材关键词 / 参考图主题
- 写回字段:`backgroundAsset`
- 是否允许历史图:不单独选择;由敲击物图案生成链路派生
- 是否允许 AI 重绘:允许;随敲击物图案一起重生成
- 系列素材槽位:无;首版只有敲击物图案与背景环境图两个单图资产,不生成图集
- 音频资产槽位:
- `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 对原始参考图的卡通风格化重绘,固定为模板默认资源,避免默认关键词在每次生成时改变造型。即使使用内置默认敲击物,首版仍需要生成 `backgroundAsset`,背景环境图使用默认敲击物作为主题和画风参考。
用户输入自定义关键词、上传参考图,或在结果页主动重生成敲击物时,`compile-draft``regenerate-hit-object` 必须先为敲击物图案生成 image2 单图资产,再基于新敲击物图案生成背景环境图,并由 `api-server` 注入写回 `hitObjectAsset``backgroundAsset`。前端 action 请求不得自带 `hitObjectAsset``backgroundAsset` 短路生成。如果用户上传参考图,后端只能把该图作为 image2 参考图或主题参考;运行态不得直接使用上传图。
敲击物图案生成流程固定为:
1. 调用 VectorEngine `/v1/images/edits`,模型固定为 `gpt-image-2`
2. multipart 参考图固定包含默认木鱼图 `/wooden-fish/default-hit-object.png`,作为基础结构和画风参考;
3. 若用户上传参考图,该图只作为新主题参考追加到同一次 image2 edits 请求,不直接进入运行态;
4. 尺寸固定 `1:1`,透明底;
5. 提示词严格使用:
```text
生成敲木鱼新样式,要求结构,画风与参考图保持高度一致,新样式颜色搭配使用新主题对应的颜色。
新主题为:(用户提供参考图或用户输入关键词)
```
背景环境图生成流程固定为:
1. 调用 VectorEngine `/v1/images/edits`,模型固定为 `gpt-image-2`
2. multipart 参考图固定为第一步新生成的敲击物图案;默认未生成新敲击物时使用内置默认敲击物图案;
3. 尺寸固定竖屏 `9:16`
4. 背景环境图只适配新敲击物主题和画风,背景中不得包含新敲击物本体,也不得增加木槌互动物品;
5. 提示词严格使用:
```text
生成敲木鱼背景,要求主题,画风与参考图保持高度一致,背景元素和颜色搭配与主题对应,木鱼预设在屏幕中央位置,木鱼主体周围元素保持干净,背景氛围围绕外围设计,背景环境图中不包含新木鱼物品,背景氛围中不增加木槌互动物品。
主题为:(用户提供参考图或用户输入关键词)
```
落库链路固定为:`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. 中央主体使用 `/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. `backgroundAsset`
13. `hitSoundAsset`
14. `coverImageSrc`
15. `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`,其中 `background_asset_json` 保存背景环境图资产快照;
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. 发布;
9. 返回编辑。
结果页必须支持:
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. 提交后按新敲击物图案参考图生成 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` 通过。

View File

@@ -49,6 +49,8 @@
热身结束后展示“开始游戏”按钮,用户点击后进入宝贝识物首关本地 Demo。该入口只用于热身关后的本地体验验证正式平台体验仍必须通过“宝贝识物”创作模板发布后在寓教于乐板块进入。
发现页的寓教于乐频道同时提供独立热身关入口,用户可直接进入 `/child-motion-demo`
### 3.3 固定流程顺序
热身关必须按照以下顺序执行:

View File

@@ -44,7 +44,7 @@ npm run check:server-rs-ddd
`server-rs/crates/spacetime-client/src/mapper.rs` 只作为聚合入口,负责声明 `src/mapper/` 下的领域子模块并 re-export 原有 record / mapper 能力;不要在该文件继续堆叠大段映射实现。
当前子模块按调用领域拆分:`assets.rs``auth.rs``runtime.rs``runtime_profile.rs``custom_world.rs``puzzle.rs``match3d.rs``square_hole.rs``visual_novel.rs``big_fish.rs``story.rs``ai.rs``bark_battle.rs``combat.rs``inventory.rs``npc.rs`,跨领域轻量 helper 和共享 record 统一放在 `common.rs`。该拆分只改变 `spacetime-client` 文件组织,不改变 SpacetimeDB schema、生成绑定、procedure result 契约或外部 DTO后续新增 mapper 时优先落到对应领域子模块,不得重新引入跨层 JSON 字符串兼容结构。
当前子模块按调用领域拆分:`assets.rs``auth.rs``runtime.rs``runtime_profile.rs``custom_world.rs``puzzle.rs``match3d.rs``jump_hop.rs``wooden_fish.rs``square_hole.rs``visual_novel.rs``big_fish.rs``story.rs``ai.rs``bark_battle.rs``combat.rs``inventory.rs``npc.rs`,跨领域轻量 helper 和共享 record 统一放在 `common.rs`。该拆分只改变 `spacetime-client` 文件组织,不改变 SpacetimeDB schema、生成绑定、procedure result 契约或外部 DTO后续新增 mapper 时优先落到对应领域子模块,不得重新引入跨层 JSON 字符串兼容结构。
## API 路由分组
@@ -60,6 +60,7 @@ npm run check:server-rs-ddd
- 自定义世界 / RPG`/api/runtime/custom-world*``/api/story/*``/api/runtime/chat/*`
- 拼图:`/api/runtime/puzzle/*`
- 抓大鹅 Match3D`/api/creation/match3d/*``/api/runtime/match3d/*`
- 敲木鱼:`/api/creation/wooden-fish/*``/api/runtime/wooden-fish/*`
- 方洞挑战:`/api/creation/square-hole/*``/api/runtime/square-hole/*`
- 视觉小说:`/api/creation/visual-novel/*``/api/runtime/visual-novel/*`
- 大鱼吃小鱼:`/api/runtime/big-fish/*`
@@ -158,8 +159,10 @@ npm run check:server-rs-ddd
- 图片生成VectorEngine / APIMart / DashScope密钥只在后端环境变量中。
- Match3D 物品 sheet关卡整图完成后走 VectorEngine `/v1/images/edits` multipart `image`,模型为 `gpt-image-2``2K 1:1` 输出 `10*10` spritesheet物品 sheet prompt 固定要求纯绿色绿幕背景,后端上传 OSS 前必须把绿幕扣成透明 PNG并把透明整图写入 `itemSpritesheetImageSrc/itemSpritesheetImageObjectKey`。后端固定从该 sheet 解析并持久化 20 个物品、每个 5 个形态;通用系列素材图集的行列索引按每行 2 个物品计算,必须落在 `1..=10`,难度只决定运行态加载 3 / 9 / 15 / 20 种。
- Match3D UI spritesheet 和背景派生图:关卡整图作为参考图并发生成 `1K 1:1` UI spritesheet 与 `1K 9:16` 背景图,模型均为 `gpt-image-2`。UI spritesheet prompt 固定要求纯绿色绿幕背景,后端上传 OSS 前必须把绿幕扣成透明 PNG背景图必须合成为全画幅不透明 PNG。
- Match3D 1:1 容器 UIVectorEngine `/v1/images/edits` multipart 参考图。该容器参考图是后端生图协议输入,必须通过 `include_bytes!``api-server` 编译进二进制,避免 API 单独发布或运行目录缺少 `public/` 时生成失败。
- 敲木鱼敲击物和背景环境图VectorEngine `/v1/images/edits`,模型固定 `gpt-image-2`。敲击物支持 multipart 多参考图,第一张固定为后端内嵌默认木鱼图,用户上传图只作为新主题参考;背景环境图只使用新敲击物图作为参考。
- Hyper3D / Rodin只保留后端安全代理和旧数据兼容新 Match3D 草稿和批量新增不再生成 GLB。
- 音频:视觉小说专用音频路由保留;拼图和抓大鹅生成入口暂时关闭,通用 `/api/creation/audio/*` 对相关目标返回 `410 Gone`
- 音频:视觉小说专用音频路由保留;拼图和抓大鹅生成入口暂时关闭,通用 `/api/creation/audio/*` 对相关目标返回 `410 Gone`;敲木鱼 `hit_sound` 目标例外开放,复用 VectorEngine Vidu 音效生成、OSS 私有对象、`asset_object` 和 entity binding 链路,目标字段固定为 `entityKind='wooden_fish_work'``slot='hit_sound'``assetKind='wooden_fish_hit_sound'``storagePrefix='wooden_fish_assets'`
- OSS私有 generated legacy path 进入浏览器前必须通过 `/api/assets/read-url` 换签;不要裸请求 `/generated-*`
- 外部 API 失败审计:外部供应商调用未成功时,`api-server` 必须发送 OTLP 失败事件并写入 `tracking_event`。当前通用 VectorEngine `gpt-image-2-all` 图片生成 / 编辑适配器在 `request_send``response_body``upstream_status``response_parse``missing_image``image_download` 阶段失败时记录 `external_api_call_failure``scope_kind = module``scope_id = provider``module_key = external-api`metadata 固定包含 provider、endpoint、operation、failureStage、statusCode、statusClass、timeout、retryable、errorMessage、latencyMs、promptChars、referenceImageCount 和 imageModel。入库优先复用 tracking outboxoutbox 不可写或保护阈值拒绝时回退同步写 SpacetimeDB不得新增前端兜底或在 SpacetimeDB reducer 内做外部 I/O。
@@ -401,6 +404,41 @@ npm run check:server-rs-ddd
- 源码:`server-rs/crates/spacetime-module/src/jump_hop.rs`
- 说明:跳一跳公开详情兼容投影,包含作品、路径和素材字段;公开列表主路径优先使用 `jump_hop_gallery_card_view`
### `wooden_fish_agent_session`
- Rust 结构体:`WoodenFishAgentSessionRow`
- 源码:`server-rs/crates/spacetime-module/src/wooden_fish/tables.rs`
### `wooden_fish_event`
- Rust 结构体:`WoodenFishEventRow`
- 源码:`server-rs/crates/spacetime-module/src/wooden_fish/tables.rs`
### `wooden_fish_runtime_run`
- Rust 结构体:`WoodenFishRuntimeRunRow`
- 源码:`server-rs/crates/spacetime-module/src/wooden_fish/tables.rs`
### `wooden_fish_work_profile`
- Rust 结构体:`WoodenFishWorkProfileRow`
- 源码:`server-rs/crates/spacetime-module/src/wooden_fish/tables.rs`
- 说明:敲木鱼作品 profile 真相,包含敲击物图案、背景环境图、敲击音效、飘字配置、发布状态和公开计数;`background_asset_json` 是后加入字段,保存 image2 生成的 9:16 背景环境图资产快照,旧迁移数据按 `None` 兼容。
### SpacetimeDB view`wooden_fish_gallery_card_view`
- Rust view`wooden_fish_gallery_card_view`
- 返回类型:`Vec<WoodenFishGalleryCardViewRow>`
- 源码:`server-rs/crates/spacetime-module/src/wooden_fish.rs`
- 说明:敲木鱼公开广场列表卡片投影,只暴露 `publication_status = published` 的作品卡片字段;`api-server``spacetime-client` 长期订阅 `SELECT * FROM wooden_fish_gallery_card_view` 后,从本地 cache 构造敲木鱼公开列表响应。个人作品列表、详情、发布和运行态仍按 procedure 路径处理。
### SpacetimeDB view`wooden_fish_gallery_view`
- Rust view`wooden_fish_gallery_view`
- 返回类型:`Vec<WoodenFishGalleryViewRow>`
- 源码:`server-rs/crates/spacetime-module/src/wooden_fish.rs`
- 说明:敲木鱼公开详情兼容投影,包含敲击物图案、敲击音效和飘字配置;公开列表主路径优先使用 `wooden_fish_gallery_card_view`
### `match3d_agent_message`
- Rust 结构体:`Match3DAgentMessageRow`

View File

@@ -45,6 +45,10 @@ npm run dev:api-server
后端日志默认写入 `logs/api-server/`。后端 API smoke 使用 `npm run dev:api-server` 并检查 `/healthz`;不要使用旧 `api-server:maincloud` 或任何 `GENARRATIVE_SPACETIME_MAINCLOUD_*` 口径。
如果本地 `GET /api/creation-entry/config` 返回 `No such procedure`,通常是 `.env.local` 指向的 SpacetimeDB 库还没有发布当前 `spacetime-module`,或当前 CLI 身份无权发布该库。debug 构建的 `api-server` 会临时使用后端默认入口配置兜底,避免创作作品架整块消失;正式修复仍应切换到拥有目标库权限的 SpacetimeDB 身份后重新运行 `npm run dev` 完成发布,或用 gitignored 的 `spacetime.local.json` 指向可发布的本地库。
本地 `npm run dev:spacetime` 发布模块时必须显式忽略仓库根目录的 `spacetime.json`,由脚本固定追加 `--no-config` 并使用命令参数里传入的数据库名和 `--server http://127.0.0.1:3101`。否则 CLI 可能把发布目标改写到配置文件里的其他数据库,导致 `dev:spacetime` 启动后又因发布失败自动退出,浏览器随后会在 `ws://127.0.0.1:3101/v1/database/.../subscribe` 看到连接拒绝。
本地 `.env``.env.local``.env.secrets.local` 修改后必须重启 `api-server` 才会生效;若已经通过 `npm run dev` 启动完整联调,可在该终端输入 `rs api-server`。排查 RPG / 拼图 / 抓大鹅等 VectorEngine 生图链路时,确认 `VECTOR_ENGINE_BASE_URL``VECTOR_ENGINE_API_KEY``VECTOR_ENGINE_IMAGE_REQUEST_TIMEOUT_MS` 只在本地或服务器密钥文件中配置,不能写入 Git。开局 CG 故事板、首图、背景和图集都属于长耗时图片请求;后端默认会把 `VECTOR_ENGINE_IMAGE_REQUEST_TIMEOUT_MS` 下限收口到 `1000000`,旧进程仍可能沿用重启前的短超时。若开局 CG 故事板在 `send()` 阶段失败且日志显示 `SendRequest`,先看同一 request_id 的 `request_body_bytes``reference_data_url_bytes``sourceChain``rootSource`;当前开局 CG 会把角色图与首幕背景图压到单边 768 的 JPEG 后再作为 generations `image` 数组发送,`/v1/images/generations` 使用默认 HTTP 协商,只有 multipart `/v1/images/edits` 单独强制 HTTP/1.1。
查看本地 Rust / SpacetimeDB 日志:
@@ -167,6 +171,7 @@ UI 相关修改要重点验证:
4. 身份问题先查 `spacetime login show``spacetime server list` 和目标库权限,不通过切回旧 Node / PostgreSQL 绕过。
5. 旧库迁移或 private 表数据保留走 `migration.rs` 的 JSON 导入导出和分片导入思路。
6. Jenkins 数据库导入 / 导出流水线会先加载 `scripts/jenkins-prepare-toolchain-env.sh`,显式补齐 Jenkins 用户的 Node、Cargo、SpacetimeDB 工具链目录;如果目标机器安装路径不同,用 `GENARRATIVE_JENKINS_TOOL_PATHS` 传入额外 `bin` 目录。
7. 本地 `npm run dev` / `npm run dev:api-server` 若没有显式 `GENARRATIVE_SPACETIME_TOKEN`,会在 SpacetimeDB 就绪后调用 `/v1/identity` 创建当前进程专用 Web API identity token并只注入本次 `api-server` 环境,不写回 `.env.local`。启动日志只打印 identity 前缀,禁止打印 token 明文;若仍出现 `subscribe ... 401 Unauthorized`,先确认是否绕过了项目 dev 脚本或是否连接到非本次启动的 SpacetimeDB server。
## 生产运维

View File

@@ -120,6 +120,28 @@ RPG / 拼图等运行态存档选择入口统一在个人中心 `常用功能 >
平台首页推荐、精选、最新、公开详情、搜索、已玩作品和公开试玩统一按 `sourceType='jump-hop'``JH-*` 公开作品号识别跳一跳作品;从公开详情或推荐流启动运行态时,若卡片摘要不足以携带角色图、地块图集和路径配置,必须先补读完整 work profile 再传入运行态。平台壳层必须同步注册 `jump-hop-workspace``jump-hop-generating``jump-hop-result``jump-hop-runtime``jump-hop-gallery-detail` 阶段,并在 `appPageRoutes.ts` 映射 `/creation/jump-hop/workspace``/creation/jump-hop/generating``/creation/jump-hop/result``/gallery/jump-hop/detail``/runtime/jump-hop`,同时持有 session、work、run、gallery、busy/error 与生成进度状态,避免只合入渲染分支但遗漏状态源或分享路径导致 typecheck 失败、刷新回首页。
## 敲木鱼
对外名称:`敲木鱼`。工程域:`wooden-fish`。PRD 见 `docs/prd/【玩法创作】敲木鱼玩法模板PRD-2026-05-20.md`
首版定位为单屏点击解压模板,链路对齐拼图的创作闭环:
```text
创作入口 -> 工作台 -> 生成过程页 -> 结果页 -> 试玩 -> 发布 -> 运行态
```
创作输入固定为:
1. `敲什么`:敲击物单图资产槽位。默认模板使用内置透明 PNG `/wooden-fish/default-hit-object.png` 作为 `bundled-default` 敲击物资产,避免默认关键词被重新语义化改形;用户输入自定义关键词或上传参考图时,后端必须以默认木鱼图作为基础结构和画风参考,使用 image2 生成最终敲击物图案,上传图只作为新主题参考,不直接进入运行态。自定义 `compile-draft` / `regenerate-hit-object` 必须完成 image2 -> OSS 私有对象 -> asset object 登记和绑定后,再由 `api-server` 注入真实 `hitObjectAsset.imageSrc`,不能只写 `/generated-wooden-fish-assets/...` 占位路径,也不能接受前端请求自带的 `hitObjectAsset` 短路生成。
2. `敲击音效`:音频资产槽位,支持描述生成、上传和麦克风录制,统一写回 `hitSoundAsset`。描述生成复用通用 `/api/creation/audio/sound-effect` 的 VectorEngine Vidu 音效生成、下载、OSS 私有对象、asset object 登记和 entity binding 链路;木鱼目标固定为 `entityKind='wooden_fish_work'``slot='hit_sound'``assetKind='wooden_fish_hit_sound'``storagePrefix='wooden_fish_assets'`,不得再返回 `410 Gone`,也不得由 `spacetime-client` 合成假音频路径。
3. `功德有什么`:最多 8 条飘字,默认 `幸运、健康、财富、姻缘、幸福、事业、成功、功德`;创作态只保存词条名,运行态飘字展示时再追加 `+1`
图片生成链路固定为双图 image2 流程:第一步用默认木鱼图作为结构和画风参考,按用户题材关键词或参考图主题生成 `1:1` 透明底新敲击物;第二步用新敲击物作为主题和画风参考生成 `9:16` 背景环境图,背景图只适配主题和画风,不能包含新敲击物本体,也不能增加木槌互动物品。两个资产分别写回 `hitObjectAsset``backgroundAsset`,并绑定到 `wooden_fish_work``hit_object` / `background` 槽位。运行态和结果页消费 `backgroundAsset` 做竖屏背景,中央再叠加 `hitObjectAsset`
运行态规则真相以后端 run 摘要为准,前端只做点击低延迟表现、敲击动画、音频播放和飘字渲染。每次非功能区点击在当前 run 内累计 `totalTapCount``wordCounters`;计数不进入账号长期账本,不做排行榜。顶部计数器仅在词条首次出现时创建,后续同词条继续累加。
平台首页推荐、精选、最新、公开详情、搜索、已玩作品和公开试玩统一按 `sourceType='wooden-fish'``WF-*` 公开作品号识别敲木鱼作品;公开列表应走 `wooden_fish_gallery_card_view` 订阅缓存,公开详情或运行态启动时卡片摘要不足则补读完整 work profile。
## 抓大鹅 Match3D
对外名称:`抓大鹅`。工程域:`match3d`
@@ -249,9 +271,9 @@ RPG / 拼图等运行态存档选择入口统一在个人中心 `常用功能 >
当前包含:
- `baby-object-match`:宝贝识物当前入口状态为 `visible=true``open=false`,创作 Tab 展示为“敬请期待”,进入创作与发布链路;历史资产接口为 `/api/creation/edutainment/baby-object-match/assets`,后续重新开放时继续复用该资产链路
- `baby-object-match`:宝贝识物当前入口状态为 `visible=true``open=true`,创作 Tab 展示为“可创建”,进入宝贝识物创作、生成、结果页、试玩和发布链路;资产生成接口为 `/api/creation/edutainment/baby-object-match/assets`。入口关闭只允许通过 SpacetimeDB / 后台入口配置显式调整,默认种子和 debug 兜底都必须保持可创建
- `baby-love-drawing`:宝贝爱画本地 demo魔法生成接口为 `/api/creation/edutainment/baby-love-drawing/magic`
- `child-motion-demo`:儿童动作识别热身关。真实动作数据来自 mocap WebSocket不要把浏览器摄像头视频流当作主动作数据源。
- `child-motion-demo`:儿童动作识别热身关。真实动作数据来自 mocap WebSocket不要把浏览器摄像头视频流当作主动作数据源;发现页的寓教于乐频道同时提供独立热身关入口,点击后进入 `/child-motion-demo`
## 创意互动 Agent