feat: add edutainment drawing and visual package flows

This commit is contained in:
2026-05-14 14:17:10 +08:00
parent 10e8beea80
commit e444266e1e
109 changed files with 8788 additions and 996 deletions

View File

@@ -5,6 +5,7 @@
## 文档列表
- [CHILD_MOTION_DEMO_WARMUP_LEVEL_DESIGN_2026-05-09.md](./CHILD_MOTION_DEMO_WARMUP_LEVEL_DESIGN_2026-05-09.md)4-8 岁儿童动作识别互动玩法 Demo 固定热身关的横屏体验流程、识别目标、表现需求与待确认事项。
- [TAONIER_BRAND_LOGO_CONCEPTS_2026-05-13.md](./TAONIER_BRAND_LOGO_CONCEPTS_2026-05-13.md)候选产品名“陶泥儿”的品牌定位归纳、gpt-image-2 Logo 概念图和主标选择建议。
- [CUSTOM_WORLD_CREATOR_INPUT_AND_AI_BOUNDARY_DESIGN_2026-04-06.md](./CUSTOM_WORLD_CREATOR_INPUT_AND_AI_BOUNDARY_DESIGN_2026-04-06.md):自定义世界里陶泥儿主输入与 AI 分工边界设计。
- [CUSTOM_WORLD_CREATOR_MANUAL_AI_SYSTEM_BALANCE_DESIGN_2026-04-12.md](./CUSTOM_WORLD_CREATOR_MANUAL_AI_SYSTEM_BALANCE_DESIGN_2026-04-12.md):自定义世界创作里“手填锚点 / AI 可改初稿 / 系统托管层”的平衡设计。
- [CUSTOM_WORLD_CREATOR_PURE_AGENT_COMPARISON_AND_CONVERSION_DESIGN_2026-04-12.md](./CUSTOM_WORLD_CREATOR_PURE_AGENT_COMPARISON_AND_CONVERSION_DESIGN_2026-04-12.md):纯 Agent 式创作工具与结构化工作台方案的优缺点对比,以及转型设计。

View File

@@ -0,0 +1,423 @@
# 陶泥儿品牌 Logo 概念稿
> 本稿是围绕候选产品名“陶泥儿”的品牌视觉探索,不替代当前已冻结的“百梦”正式命名口径。若后续确认更名,需要另起产品命名、前后端文案和商标检索落地方案。
## 1. 品牌定位归纳
“陶泥儿”适合承接的不是传统陶艺或儿童黏土,而是“把灵感塑形成可玩内容”的 AI 创作平台隐喻。
核心关键词:
- 精品:作品不是随手糊出来,而是经过 AI 辅助打磨、可被消费和传播的轻精品内容。
- UGC用户是主要造物者平台降低创作门槛。
- 创作:从一句脑洞、一个梗、一张图,生成小游戏、互动作品或可分享内容。
- 裂变与梗:名字要支持“开捏”“捏个梗”“捏个小游戏”这类用户语言。
- 轻度休闲:体验应松弛、即时、好玩,不走硬核生产工具气质。
- AIAI 是塑形能力,不是冷冰冰的技术标签。
推荐品牌主张:
```text
把脑洞捏成小游戏
```
备选表达:
```text
捏个脑洞,马上开玩
AI 开捏,人人会创作
随手造梗,随心开玩
```
## 2. 生成原则
本轮使用仓库 GPT-image-2 / VectorEngine 工作流生成 Logo 概念图,生成时刻意要求“无文字 Logo 图标”。
原因:
- AI 生图直接生成中文品牌字容易出现笔画错误,不适合作为正式字标。
- 当前阶段更适合先确定图形符号方向,再由设计师或前端继续做矢量化、字标搭配和多尺寸适配。
- 图标需要优先服务 App icon、平台左上角品牌、分享卡片和加载页而不是一次性海报图。
生成文件:
```text
public/branding/taonier-logo-v3-concepts/
├─ taonier-logo-v3-contact-sheet.png
├─ taonier-v3-finger-spark.png
├─ taonier-v3-seed-pop.png
├─ taonier-v3-magic-dot.png
├─ taonier-v3-work-gem.png
└─ taonier-v3-soft-t.png
public/branding/taonier-logo-magic-dot-concepts/
├─ taonier-logo-magic-dot-contact-sheet.png
├─ taonier-magic-dot-orbit.png
├─ taonier-magic-dot-seal.png
├─ taonier-magic-dot-squish.png
├─ taonier-magic-dot-mold.png
└─ taonier-magic-dot-bloom.png
public/branding/taonier-logo-flat-concepts/
├─ taonier-logo-flat-contact-sheet.png
├─ taonier-flat-play-clay.png
├─ taonier-flat-spark-clay.png
├─ taonier-flat-meme-smile.png
├─ taonier-flat-loop-mold.png
└─ taonier-flat-seal-blocks.png
public/branding/taonier-logo-concepts/
├─ taonier-logo-contact-sheet.png
├─ taonier-clay-spark.png
├─ taonier-play-mold.png
├─ taonier-meme-bubble.png
├─ taonier-creation-loop.png
└─ taonier-premium-seal.png
```
生成脚本:
```text
scripts/generate-taonier-logo-concepts.mjs
```
## 3. V3-03 一捏成型延展
这一组专门沿 V3 “一捏成型”继续打磨。目标是保留“两个软形触点 + 中央作品核”的成型瞬间,同时降低括号感、碰撞特效感和功能按钮感。
![陶泥儿 Logo 一捏成型延展总览](../../public/branding/taonier-logo-magic-dot-concepts/taonier-logo-magic-dot-contact-sheet.png)
### 3.1 捏合星核
![捏合星核](../../public/branding/taonier-logo-magic-dot-concepts/taonier-magic-dot-orbit.png)
定位:一捏成型方向的主标首选。
这个方向最稳地保留了“左右合拢、中央成型”的核心动作,中心青绿色星核形成了明确焦点,整体比原 V3-03 更完整,也没有明显播放器、聊天或表情联想。
优点:
- 结构清楚,第一眼能看出“合拢生成”。
- 元素少,小尺寸适配潜力好。
- 中央星核可以做加载、生成成功、发布完成等动效延展。
风险:
- 左右软形仍有一点括号感,后续矢量化可把外轮廓做得更不对称、更像被捏塑的软泥。
建议用途:主 Logo 备选首选、AI 生成按钮、启动动效核心符号。
### 3.2 成型印记
![成型印记](../../public/branding/taonier-logo-magic-dot-concepts/taonier-magic-dot-seal.png)
定位:完整主标感最强的延展方向。
这个方向把左右触点收成一个更完整的软形图腾,减少了“两个括号”的割裂感。视觉上更像独立品牌符号,但也因此少了一点“捏合动作”的即时感。
建议用途:主 Logo 强备选;若选择它,后续应去掉背景底色并强化中心负形星点。
### 3.3 软泥合拍
![软泥合拍](../../public/branding/taonier-logo-magic-dot-concepts/taonier-magic-dot-squish.png)
定位:轻松、年轻、动效友好。
这个方向的上下软形更活泼,适合表达“啪嗒一下成型”。但静态 Logo 中的黄色星点和短线略像特效贴纸,主标使用前需要继续简化。
建议用途:生成中动效、运营图、互动反馈,不建议直接定为主 Logo。
### 3.4 灵感模口
![灵感模口](../../public/branding/taonier-logo-magic-dot-concepts/taonier-magic-dot-mold.png)
定位:最有“模口 / 造物容器”意味。
这个方向图形独特,和“从软泥模口里生成作品”的隐喻贴合。但外形复杂度比 01、02 更高,边缘细节在小尺寸下可能损失。
建议用途:主 Logo 备选探索,适合继续做专业矢量简化。
### 3.5 捏开灵感
![捏开灵感](../../public/branding/taonier-logo-magic-dot-concepts/taonier-magic-dot-bloom.png)
定位:温和、包裹、生成容器。
这个方向亲和、平衡,但整体像眼睛 / 容器 / 开合结构,陶泥儿的“捏”动作弱一些。
建议用途AI 生成入口、等待态、创作容器辅助图形。
## 4. V3 抽象主标候选
V3 根据评审反馈重新避开了五个问题:播放三角、褐色陶土主色、聊天气泡 / 表情包、循环符号,以及过多碎元素。方向转为更抽象、更亮眼、更像长期主 Logo 的符号。
![陶泥儿 Logo V3 概念总览](../../public/branding/taonier-logo-v3-concepts/taonier-logo-v3-contact-sheet.png)
### 4.1 灵感捏痕
![灵感捏痕](../../public/branding/taonier-logo-v3-concepts/taonier-v3-finger-spark.png)
定位:主 Logo 首选。
这个方向用醒目的珊瑚红软形、指纹捏痕和星点负形建立记忆点。它不再依赖“陶泥的褐色”,而是用“被捏过的痕迹”表达陶泥儿的核心动作:用户把脑洞捏成作品。
优点:
- 第一眼足够醒目,远离旧版褐色和播放器感。
- 指纹捏痕有独特性,能承接“人人创作”和“亲手塑形”。
- 元素少,适合继续矢量化和小尺寸适配。
风险:
- 指纹弧线后续需要进一步简化,避免在 24px 以下变糊。
- 星点比例要克制,避免变成普通灵感图标。
建议用途:主 Logo、App icon、平台顶栏、启动页、生成按钮。
### 4.2 脑洞种子
![脑洞种子](../../public/branding/taonier-logo-v3-concepts/taonier-v3-seed-pop.png)
定位:创意生长与新手友好。
这个方向从“灵感发芽”切入,比陶泥更偏创造生命力。它亲和、可爱,但容易让用户联想到教育、植物、儿童启蒙或种植类产品。
建议用途:新手引导、创作孵化、儿童 / 寓教于乐支线,不建议作为主 Logo。
### 4.3 一捏成型
![一捏成型](../../public/branding/taonier-logo-v3-concepts/taonier-v3-magic-dot.png)
定位AI 把灵感合成为作品的瞬间。
这个方向很简洁,用左右两个软形触点和中心星点表达“捏合”。它避开了播放器和聊天气泡,也能做动效,但静态图形目前稍像碰撞特效或括号,需要继续重绘增强独特轮廓。
建议用途生成按钮、AI 施法动效、主 Logo 备选微调方向。
### 4.4 作品胶囊
![作品胶囊](../../public/branding/taonier-logo-v3-concepts/taonier-v3-work-gem.png)
定位:精品内容和作品沉淀。
这个方向更稳、更精品,青绿色也比褐色更吸睛。但整体像水滴、宝石或通用内容图标,和“捏”这个动作的关系弱。
建议用途:精选作品、作品库、创作者中心,不建议优先做主 Logo。
### 4.5 软体 T 形
![软体 T 形](../../public/branding/taonier-logo-v3-concepts/taonier-v3-soft-t.png)
定位:英文辅助名 / Taonier 的抽象首字母。
这个方向试图做更品牌化的抽象符号,但当前形体还不够自然,也未形成足够强的“陶泥儿”心智。若未来英文名确定为 `Taonier` 或类似形式,可以继续沿这个方向做专业字母标重绘。
建议用途:英文标识探索,不作为当前主 Logo 首选。
## 5. V2 扁平矢量候选
第一批图形偏 3D 和拟物,更适合作为吉祥物、运营图或启动页气氛图,不适合作为长期主 Logo。V2 已把约束收紧为扁平、矢量、少元素、强轮廓和小尺寸可识别。
![陶泥儿 Logo 扁平概念总览](../../public/branding/taonier-logo-flat-concepts/taonier-logo-flat-contact-sheet.png)
### 5.1 扁平开捏
![扁平开捏](../../public/branding/taonier-logo-flat-concepts/taonier-flat-play-clay.png)
定位:最直接的主 Logo 候选。
这个方向用一团柔软陶泥承载播放符号,用户一眼能理解“点开玩 / 马上玩”,同时外形保留“捏出来”的不规则软泥感。
优点:
- 识别速度最快,移动端小尺寸也成立。
- 符合主流 App Logo 语言,亲和、不重、不技术冷。
- 和“把脑洞捏成小游戏”的主张绑定最强。
风险:
- 播放符号是常见母题,后续矢量化时要通过不规则软泥外轮廓、颜色和字标形成独特资产。
建议用途:主 Logo 首选、App icon、平台顶栏、分享卡片角标。
### 5.2 灵感泥星
![灵感泥星](../../public/branding/taonier-logo-flat-concepts/taonier-flat-spark-clay.png)
定位AI 创作与灵感生成。
这个方向比“扁平开捏”更品牌化中心负形星点表达灵感、AI 生成和创意爆发。它没有播放符号那么直白,但更容易和“陶泥儿”的创作平台气质绑定。
优点:
- 图形更简洁,品牌记忆点强。
- 陶泥心智、AI 灵感和精品感比较平衡。
- 适合未来扩成字标、启动页和生成态动效。
风险:
- 对“小游戏/马上玩”的表达弱于播放符号。
建议用途:主 Logo 强备选、创作首页、AI 生成按钮和品牌主视觉。
### 5.3 造梗笑泥
![造梗笑泥](../../public/branding/taonier-logo-flat-concepts/taonier-flat-meme-smile.png)
定位:社交传播和玩梗亲和力。
这个方向的气泡与笑脸非常亲和,适合表达“分享快乐”和“造梗”。但它和聊天、社区类产品的通用图形过近,作为主 Logo 可能会让用户误判产品品类。
建议用途:社区、评论、分享、活动贴纸,不建议做主 Logo。
### 5.4 共创泥环
![共创泥环](../../public/branding/taonier-logo-flat-concepts/taonier-flat-loop-mold.png)
定位AI 与用户共创闭环。
这个方向表达共创与循环,但生成结果带有偏柔和彩虹渐变的视觉倾向,与“陶泥儿”的软泥名称关联不够直观,也不如 01/02 容易记住。
建议用途:创作流程、共创能力、生成进度辅助图形。
### 5.5 精品泥印
![精品泥印](../../public/branding/taonier-logo-flat-concepts/taonier-flat-seal-blocks.png)
定位:精品作品和内容集合。
这个方向像内容平台或作品库入口,能表达图片、用户、游戏等多形态内容。但图形元素较多,主标识别不如 01/02 凝练。
建议用途:精选作品、作品集、创作者中心、内容品质标识。
## 6. V1 立体探索
### 6.1 灵感陶团
![灵感陶团](../../public/branding/taonier-logo-concepts/taonier-clay-spark.png)
定位AI 共创与灵感造物。
这个方向把“陶泥”作为主视觉,内部用发光火花和节点表达 AI 赋能。它最贴“陶泥儿”名字本身,也能说明平台不是普通小游戏集合,而是从灵感生成作品的创作容器。
优点:
- 与“陶泥儿”的名称绑定最强。
- 有 AI、创作、造物的综合含义。
- 适合启动页、品牌介绍、创作首页空状态。
风险:
- 小尺寸下细节偏多,需要后续矢量化时压缩节点和纹理。
- 如果色彩处理不当,会回到手工陶艺联想。
建议用途:品牌主视觉备选、官网/启动页、创作入口图形。
### 6.2 开玩模具
![开玩模具](../../public/branding/taonier-logo-concepts/taonier-play-mold.png)
定位:把脑洞捏成小游戏。
这个方向用软陶捏出播放符号,最直接地连接“创作”和“马上玩”。它比单纯陶泥团更有产品动作,也更适合轻休闲、小游戏、短内容传播。
优点:
- 识别强,小尺寸也清楚。
- 与轻度休闲小游戏的关系最直接。
- 适合作为 App icon 和主 Logo 图形。
风险:
- 播放符号相对常见,需要后续在外轮廓、捏痕和色彩上做独特性。
- 如果三角形过硬,会削弱“陶泥儿”的柔软感。
建议用途:主 Logo 首选、App icon、分享卡片角标、加载态图形。
### 6.3 造梗气泡
![造梗气泡](../../public/branding/taonier-logo-concepts/taonier-meme-bubble.png)
定位:社交传播、玩梗、裂变。
这个方向把陶泥变形成聊天气泡和表情,强调“梗”和“传播”。它最有社交平台感,也适合表情包、活动贴纸和运营视觉。
优点:
- 传播感强,年轻、轻松、容易做 IP 化。
- 能承接社区、评论、分享和玩梗场景。
- 比较容易延展成贴纸和表情包。
风险:
- 偏软萌,可能削弱“精品 AI 创作平台”的质感。
- 作为主 Logo 容易显得像聊天或表情产品。
建议用途社区模块、活动运营、IP 辅助形象,不建议作为唯一主 Logo。
### 6.4 共创回路
![共创回路](../../public/branding/taonier-logo-concepts/taonier-creation-loop.png)
定位AI 与用户共同迭代生成。
这个方向用软陶带形成循环和造物轨迹,表达“灵感 -> AI 塑形 -> 用户修改 -> 作品传播”的闭环。它比其他方向更抽象,也更有平台级和工具级气质。
优点:
- 高级、简洁,避免儿童化。
- 适合表达 AI 共创、迭代和作品循环。
- 可用于创作者工作台或生成进度标识。
风险:
- 与“陶泥儿”名称的直观关联较弱。
- 缺少小游戏和玩梗的即时识别。
建议用途创作流程标识、AI 共创能力图标、品牌辅助图形。
### 6.5 精品泥印
![精品泥印](../../public/branding/taonier-logo-concepts/taonier-premium-seal.png)
定位:精品内容、作品认证、创作者成果。
这个方向像一个被压印的软陶徽章,中间有方块和火花,比较适合表达“作品被打磨成型”。它的内容平台感强于游戏入口感。
优点:
- 精品感和作品库气质较强。
- 适合作品认证、精选、创作者徽章。
- 与“陶泥压印”隐喻相对自然。
风险:
- 细节较多,主 Logo 小尺寸可读性不如“开玩模具”。
- 徽章感偏静态,轻休闲的即时性稍弱。
建议用途:精选作品标识、创作者荣誉、内容品质标签。
## 7. 推荐结论
优先级建议:
```text
主 Logo 首选V3 01 灵感捏痕
一捏成型首选V3-03 延展 01 捏合星核
完整主标备选V3-03 延展 02 成型印记
英文标识探索V3 05 软体 T 形
精品内容辅助V3 04 作品胶囊
新手 / 寓教于乐辅助V3 02 脑洞种子
```
若要兼顾主流、亲和、醒目和“陶泥儿”的动作隐喻,优先继续打磨 V3 “灵感捏痕”。
若想把 Logo 做得更抽象、更像 AI 生成瞬间,可以继续打磨 V3-03 延展中的“捏合星核”或“成型印记”。
V1 的 3D 图标不建议直接作为主 Logo只适合做运营图、吉祥物探索或风格参考V2 的播放、气泡、碎元素方向本轮已降级为历史探索。
## 8. 后续落地建议
1. 先围绕 V3 “灵感捏痕”做 3 到 5 个专业矢量微调版:减少指纹线条、强化软形轮廓、测试深色 / 浅色底。
2. 同步对 V3-03 “捏合星核”做一版更独特的轮廓重绘,弱化括号感,保留中央成型星核。
3. 字标不要直接使用生图结果,应单独设计“陶泥儿”中文字标,并准备英文辅助名。
4. 正式应用前做商标近似检索,重点覆盖第 9、35、38、41、42 类。
5. 若确认替换“百梦”再更新现有命名规范文档、前端品牌组件、HTML metadata、后台和后端默认文案。

View File

@@ -0,0 +1,101 @@
# 宝贝爱画寓教于乐独立关卡 PRD 2026-05-13
## 1. 目标
新增寓教于乐内容线独立关卡:
```text
宝贝爱画
```
工程 ID 固定为:
```text
baby-love-drawing
```
该关卡默认出现在“发现 / 寓教于乐”板块下方。当前阶段只做本地 Demo 保存,验证完成后再补正式持久化。
## 2. 关卡结构
启动宝贝爱画后进入绘画运行态:
1. 屏幕中央是带边框的空白画板;
2. 画板边框内是可绘画区域;
3. 画板外左侧展示彩虹 7 色;
4. 画板外右侧中下方展示画笔和橡皮;
5. 用户进入内容后默认手持画笔;
6. 手持画笔或橡皮时,屏幕上实时显示跟随右手位置的工具图案标识。
## 3. 输入规则
颜色选择:
1. 仅检测左手;
2. 左手悬停在某个颜色区域 1.5 秒后,选中该颜色;
3. 颜色固定为彩虹 7 色。
工具切换:
1. 右手移动到画笔或橡皮工具区域;
2. 右手握拳后,将手里的工具切换为对应工具。
绘画与擦除:
1. 右手在画布区域握拳时,当前工具生效;
2. 当前工具为画笔时留下轨迹;
3. 当前工具为橡皮时擦除轨迹;
4. 右手张开时,画笔或橡皮抬起,不在画布上生效。
按钮选择:
1. 完成;
2. 使用绘画魔法;
3. 保存;
4. 再画一张;
5. 返回。
以上按钮都使用任一手悬停 2 秒完成选中。
## 4. 绘画魔法
用户完成绘画后,可使用“绘画魔法”。
绘画魔法使用 image-2以用户绘画内容和笔触轨迹生成对应绘本风格图片内容。
前端不得直接读取、拼接或暴露图片生成密钥。image-2 调用必须通过后端代理。
## 5. 保存规则
当前只做本地 Demo 保存。
保存规则:
1. 魔法生成前保存,只保存一张原图;
2. 若用户未保存原图,直接点击魔法生成,则魔法生成后保存时同时保存原图和魔法图;
3. 保存完毕后,可继续“再画一张”或“返回”。
## 6. 展示与开关
宝贝爱画只属于寓教于乐内容线。
`VITE_ENABLE_EDUTAINMENT_ENTRY` 关闭时:
1. 不展示“发现 / 寓教于乐”频道;
2. 不展示宝贝爱画默认卡片;
3. 不允许通过 `/runtime/baby-love-drawing` 直达运行态。
## 7. 验收
1. 寓教于乐开启时,“发现 / 寓教于乐”下方展示“宝贝爱画”默认关卡卡片;
2. 寓教于乐关闭时,不展示宝贝爱画,也不能直达运行态;
3. 进入后展示空白画板、彩虹 7 色、画笔和橡皮;
4. 默认工具为画笔;
5. 左手悬停颜色 1.5 秒后选中颜色;
6. 右手移动到工具区并握拳后切换画笔或橡皮;
7. 右手握拳在画布内绘制或擦除,张开时不生效;
8. 任一手悬停按钮 2 秒后触发按钮;
9. 完成后可保存原图;
10. 完成后可使用绘画魔法生成绘本风格图片;
11. 未保存原图直接使用绘画魔法后,保存会同时保存原图和魔法图;
12. 保存后可再画一张或返回。

View File

@@ -29,11 +29,24 @@
2. 模板名称:`宝贝识物`
3. 两个物品;
4. 两个物品图;
5. 作品标签。
5. 游戏视觉主题包;
6. 作品标签。
物品图使用 VectorEngine `gpt-image-2-all` / image-2 生成。图片生成只能走后端或后续后端预留接口,前端不得泄`VECTOR_ENGINE_API_KEY`
物品图使用 VectorEngine `gpt-image-2-all` / image-2 生成。图片生成只能走后端接口,前端不得读取、拼接或暴`VECTOR_ENGINE_API_KEY`
本地 Demo 阶段若真实生图接口未接入完成,允许前端 service 返回明确标记为 `placeholder` 的占位图形,用于打通创作到结果页的交互链路;该占位结果不得伪装成正式 image-2 资产
每个关键词只生成一张围绕该关键词的单一物品形象。生成 prompt 必须锁定寓教于乐板块统一的卡通绘本草地舞台插画风,但最终画面不生成背景、场景、氛围渲染、人物、手、篮子、礼物盒、文字、水印或 UI。服务端必须把生成结果转成透明 PNG并执行透明抠图后处理只有透明抠图后的素材才允许写入草稿 `itemAssets` 并进入游戏运行态
同一次创作还必须使用 image-2 生成游戏视觉主题包包含背景环境、UI 装饰框、礼物盒、篮子和烟雾弹出特效资源。主题包必须继续保持寓教于乐插画风,并根据用户填写的两个物品关键词匹配主题:例如关键词偏动漫角色或玩具时,背景环境和元素可使用动漫、玩具主题;关键词偏水果时,背景环境和元素可匹配果园、自然主题;其它关键词按其语义匹配合适主题。主题包不得改变关卡玩法规则,不新增文字说明、额外按钮或额外判定规则。
视觉主题包的资源边界:
1. 背景环境图不做透明抠图,但必须保证屏幕中间、中下方和底部左右篮子区域清爽,不遮挡放大后的物品、礼物盒和篮子;
2. UI 装饰框用于字幕条和计数器风格化包装,只生成装饰边框和主题点缀,不生成文字、数字或按钮;
3. 礼物盒资源输出为透明 PNG运行态按当前礼盒视觉的 2 倍尺寸展示,素材主体必须饱满清晰;
4. 篮子资源输出为透明 PNG运行态按当前篮子视觉的 1.5 倍尺寸展示,左右篮子仍固定为两个物品对应选项,篮子造型资源可以复用同一张主题篮子图;
5. 烟雾弹出特效资源输出为透明 PNG用于礼物盒打开瞬间覆盖开盒区域并承接中央物品弹出不生成物品、篮子、礼物盒或文字。
当前本地 Demo 阶段已接入真实 image-2 资源链路。创作提交必须成功获得 `generationProvider = "vector-engine-gpt-image-2"` 的两个物品透明 PNG 和完整视觉主题包后才能进入结果页、试玩或发布若后端接口、登录态、VectorEngine 配置或上游生成失败,前端必须停留在生成失败状态并展示错误,不得静默回退为占位图。历史草稿中若仍存在 `generationProvider = "placeholder"` 的占位资源,结果页必须提示重新生成,试玩和发布前必须先补齐 image-2 资源。
## 4. 标签规则
@@ -63,6 +76,8 @@
试玩按钮进入宝贝识物首关运行态,运行态消费当前草稿中的两个物品名称和两张物品图,不重新生成或改写物品内容。
若草稿包含视觉主题包运行态还必须消费该主题包中的背景环境、UI 装饰、礼物盒、篮子和烟雾弹出特效资源;旧草稿或接口失败时允许回退到当前 CSS 绘本风兜底。
## 6. 发布后体验
发布完成后作品应进入寓教于乐内容线,并在寓教于乐入口开启时可被板块消费。
@@ -73,27 +88,30 @@
本 PRD 同步约束首关运行态,已确认规则包括:
1. 礼物盒打开在本地调试绑定 `F`
1. 进入关卡后礼物盒自动打开并弹出首个随机物品
2. 每轮仅中间礼物盒跳出的物品随机;左右两侧篮子固定为当前草稿两个物品的顺序;
3. 下一关按钮当前占位;
4. 不新增用户未确认的计时、失败次数、分数、体力或难度递增。
5. 屏幕中上方字幕固定为“将物品放入对应的篮子里”。
6. 礼物盒位于屏幕中下方,任意手抬起后打开并跳出下一个随机物品
6. 礼物盒位于屏幕中下方并按当前视觉放大一倍,首次进入关卡和每次正确反馈结束后的新轮次都从上方落下后自动打开
7. 屏幕下方左侧和右侧分别展示两个固定篮子,左侧固定使用草稿第一个物品图,右侧固定使用草稿第二个物品图。
8. 明确左手连续横向移动达到阈值时将当前物品送入左侧篮子,明确右手连续横向移动达到阈值时将当前物品送入右侧篮子;选篮不使用动作名判定,侧别未知的手部轨迹不参与选篮
9. 正确时展示“真棒”字幕和正确特效;错误时展示“再想一想吧”字幕和错误特效,物品回到中央
10. 成功 20 次后展示“恭喜你!小朋友!”字幕和特效,并展示“再来一次”和“下一关”按钮
11. 当前本地 Demo 阶段音效与语音播报接口只预留调用点,不在前端写死外部硬件或服务接口
8. 左右篮子按当前视觉放大 50%
9. 礼物盒打开时播放烟雾特效,中央物品从烟雾特效中弹出;物品弹出后礼物盒从舞台移除
10. 明确左手连续横向移动达到阈值时将当前物品送入左侧篮子,明确右手连续横向移动达到阈值时将当前物品送入右侧篮子;选篮不使用动作名判定,侧别未知的手部轨迹不参与选篮
11. 正确时展示“真棒”字幕和正确特效;错误时展示“再想一想吧”字幕和错误特效,物品回到中央
12. 成功 20 次后展示“恭喜你!小朋友!”字幕和特效,并展示“再来一次”和“下一关”按钮。
13. 当前本地 Demo 阶段音效与语音播报接口只预留调用点,不在前端写死外部硬件或服务接口。
## 8. 验收
1. 创作入口显示 `宝贝识物` 并可进入模板表单。
2. 未填写任一物品名称时不能生成草稿。
3. 生成草稿后进入结果页,展示两个物品名称和物品图。
4. 草稿标签中始终包含精确 `寓教于乐`
5. 发布 payload 始终包含精确 `寓教于乐`
6. 发布完成后出现分享弹窗或发布完成状态
7. 前端不读取或暴露 VectorEngine 密钥
8. 结果页试玩进入宝贝识物运行态,不再显示“试玩关卡正在接入中”
9. 运行态可通过 `F` 打开礼物盒,通过鼠标左键拖动映射左手横向移动,通过鼠标右键拖动映射右手横向移动
10. 成功 20 次后出现“再来一次”和“下一关”按钮。
4. 生成草稿后包含视觉主题包主题包含背景环境、UI 装饰框、礼物盒、篮子和烟雾弹出特效资源
5. 草稿标签中始终包含精确 `寓教于乐`
6. 发布 payload 始终包含精确 `寓教于乐`
7. 发布完成后出现分享弹窗或发布完成状态
8. 前端不读取或暴露 VectorEngine 密钥
9. 结果页试玩进入宝贝识物运行态,不再显示“试玩关卡正在接入中”
10. 运行态通过鼠标左键拖动映射左手横向移动,通过鼠标右键拖动映射右手横向移动。
11. 成功 20 次后出现“再来一次”和“下一关”按钮。

View File

@@ -4,6 +4,7 @@
## 重点入口
- [宝贝爱画寓教于乐独立关卡 PRD](./BABY_LOVE_DRAWING_EDUTAINMENT_LEVEL_PRD_2026-05-13.md):定义寓教于乐内容线的 `宝贝爱画` 独立本地 Demo 关卡,覆盖画板、七色选择、画笔/橡皮、手部绘画、完成、image-2 绘画魔法、本地保存和关闭入口隐藏边界。
- [宝贝识物寓教于乐模板 PRD](./BABY_OBJECT_MATCH_EDUTAINMENT_TEMPLATE_PRD_2026-05-11.md):定义寓教于乐内容线的 `宝贝识物` 创作模板覆盖两个物品名称输入、image-2 物品图生成、精确 `寓教于乐` 标签、结果页和发布边界。
- [AI 原生幕间文字游戏模板 PRD参考 MOKU 的剧本模拟器闭环](./AI_NATIVE_TEXT_GAME_TEMPLATE_MOKU_REFERENCE_PRD_2026-05-05.md):参考 MOKU / 幕间类 AI 文游的剧本游乐场、自由行动、AI GM、记忆和模拟器强反馈经验但只落为陶泥儿 `text-game` 模板,复用平台接口,不迁入外部社区、支付、私有存档或回放。
- [AI 原生视觉小说模板 PRDTXT 玩法平台化接入](./AI_NATIVE_VISUAL_NOVEL_TEMPLATE_PRD_2026-05-05.md):参考 `Interactive-fiction-backend` / `Interactive-fiction-frontend` 的 TXT 玩法经验,但只保留视觉小说模板创作与运行闭环,完全使用 Genarrative 平台接口,并明确删除回放和外部平台功能。

View File

@@ -0,0 +1,202 @@
# 宝贝爱画本地 Demo 运行态实现方案 2026-05-13
## 1. 范围
本方案落地寓教于乐独立关卡:
```text
baby-love-drawing / 宝贝爱画
```
当前范围只做本地 Demo 闭环:
1. 寓教于乐频道默认关卡卡片;
2. 独立运行态;
3. mocap 与开发者调试输入;
4. Canvas 绘制和擦除;
5. image-2 绘画魔法后端代理;
6. localStorage 本地保存;
7. 直达路由开关保护。
本阶段不接正式持久化表,不新增作品发布、作品号、公开详情或搜索入口。
## 2. 前端接入点
已新增页面阶段:
```text
baby-love-drawing-runtime
```
已新增路由:
```text
/runtime/baby-love-drawing
```
已新增文件:
```text
packages/shared/src/contracts/edutainmentBabyDrawing.ts
src/services/edutainment-baby-drawing/babyDrawingClient.ts
src/components/edutainment-runtime/babyLoveDrawingModel.ts
src/components/edutainment-runtime/BabyLoveDrawingRuntimeShell.tsx
server-rs/crates/api-server/src/edutainment_baby_drawing.rs
```
已接入:
1. `src/components/rpg-entry/RpgEntryHomeView.tsx`:寓教于乐频道默认展示宝贝爱画卡片;
2. `src/components/platform-entry/PlatformEntryFlowShellImpl.tsx`:启动宝贝爱画运行态;
3. `src/components/platform-entry/platformEntryTypes.ts`:扩展 `SelectionStage`
4. `src/routing/appPageRoutes.ts`:扩展路由;
5. `src/routing/appRoutes.tsx`:直达路由开关保护;
6. `src/index.css`:补齐寓教于乐默认关卡卡片和宝贝爱画运行态样式;
7. `server-rs/crates/api-server/src/app.rs`:挂载绘画魔法后端路由。
## 3. 契约
契约放在:
```text
packages/shared/src/contracts/edutainmentBabyDrawing.ts
```
核心字段:
1. `templateId = "baby-love-drawing"`
2. `templateName = "宝贝爱画"`
3. `originalImageSrc` 保存原始画布图;
4. `magicImageSrc` 保存 image-2 魔法图,可为 `null`
5. `strokeTrace` 保存画笔和橡皮轨迹;
6. `saveMode = "original-only" | "original-and-magic"` 记录保存结果。
## 4. 运行态模型
运行态状态:
```text
drawing
finished
magicPending
magicReady
saved
```
工具:
```text
brush
eraser
```
颜色:
```text
红、橙、黄、绿、青、蓝、紫
```
按钮悬停:
1. 颜色选择只接受左手悬停,阈值 1500ms
2. 按钮选择接受任一手悬停,阈值 2000ms
3. 工具切换只接受右手在工具区域握拳。
4. 画笔 / 橡皮光标位置只接受右手坐标;左手缺帧或左手移动不得重置、替换或驱动画笔位置。
5. 左手需要显示独立位置指示器,帮助用户确认当前是否悬停在目标颜色上;该指示器只表达左手位置,不参与画笔 / 橡皮操作。
6. 本地 mocap handedness 当前按摄像头视角输出,宝贝爱画运行态消费前需要换算为用户身体视角:`rightHand` 作为用户左手,`leftHand` 作为用户右手。键鼠调试输入不做该换算。
7. 真实硬件短暂缺失某只手时,显示层保留上一帧位置约 320ms 并做轻微坐标平滑;绘制层仍只在当前帧确认用户右手存在时生效。
8. 为避免左手抢画笔,本关不做动态 handedness 换手纠正;`rightHand` 永远只进入用户左手选色通道,`leftHand` 永远只进入用户右手画笔通道。若硬件侧 handedness 继续抖动,宁可右手画笔短暂停住,也不允许左手驱动画笔。
9. 右手画笔通道增加单帧最大位移门禁;若 camera-left 候选点相对上一帧右手位置出现不合理大跳,判定为不可信帧,只保留上一帧光标并停止绘制。
## 5. Canvas 绘制
画板使用 DOM Canvas。
绘制规则:
1. 右手在画板内且状态为 `grab` 时生效;
2. 工具为 `brush` 时,以当前颜色绘制连续线段;
3. 工具为 `eraser` 时,以 `destination-out` 擦除;
4. 右手状态为 `open_palm` 或离开画板时结束当前笔画;
5. 当前帧没有右手坐标时只结束当前笔画,不把左手坐标用于绘制、擦除或光标定位;
6. 每条笔画记录工具、颜色、点位和时间。
## 6. 绘画魔法
前端 service
```text
createBabyDrawingMagicImage(payload)
```
后端接口:
```text
POST /api/creation/edutainment/baby-love-drawing/magic
```
请求体:
```json
{
"originalImageSrc": "data:image/png;base64,...",
"strokeTrace": []
}
```
响应体:
```json
{
"magicImageSrc": "data:image/png;base64,...",
"generationProvider": "vector-engine-gpt-image-2",
"prompt": "..."
}
```
后端使用 VectorEngine `gpt-image-2-all`,把原始画布图作为参考图,生成绘本风格图片。
本地未配置 VectorEngine 或接口失败时,前端允许提示错误并保留原图保存能力;不得把失败伪装成正式魔法图。
后端接入约束:
1. 接口需要 Bearer 鉴权;
2. 请求体限制为 8MB
3. `originalImageSrc` 只接受图片 Data URL
4. 笔触数量上限为 600 条;
5. 上游参考图字段使用 VectorEngine 统一契约 `image`
6. 关闭入口时,`creation_entry_config` 路由熔断可识别 `baby-love-drawing`
## 7. 本地保存
本地保存使用:
```text
localStorage key = genarrative.edutainmentBabyDrawing.localDrawings.v1
```
保存策略:
1. 魔法生成前保存:`saveMode = "original-only"`,只保存 `originalImageSrc`
2. 未保存原图直接生成魔法后保存:`saveMode = "original-and-magic"`,保存 `originalImageSrc``magicImageSrc`
3. 保存后展示“再画一张”和“返回”。
## 8. 验收命令
```bash
npm run test -- src/components/edutainment-runtime/babyLoveDrawingModel.test.ts src/components/edutainment-runtime/BabyLoveDrawingRuntimeShell.test.tsx src/services/edutainment-baby-drawing/babyDrawingClient.test.ts src/routing/appRoutes.test.ts
cargo test -p api-server edutainment_baby_drawing --manifest-path server-rs/Cargo.toml
cargo test -p api-server resolves_runtime_paths_to_creation_type_ids --manifest-path server-rs/Cargo.toml
npx eslint src/components/edutainment-runtime/BabyLoveDrawingRuntimeShell.tsx src/components/edutainment-runtime/babyLoveDrawingModel.ts src/services/edutainment-baby-drawing/babyDrawingClient.ts src/routing/appRoutes.tsx --ext .ts,.tsx --max-warnings 0
npm run typecheck
npm run check:encoding
```
## 9. 已覆盖测试
1. `src/components/edutainment-runtime/babyLoveDrawingModel.test.ts`:颜色 / 按钮悬停阈值、坐标归一化、笔触追加;
2. `src/components/edutainment-runtime/BabyLoveDrawingRuntimeShell.test.tsx`:画板、七色、画笔 / 橡皮、完成保存、返回按钮、左手位置指示器、mocap 摄像头视角到用户身体视角换算、左手输入不替换画笔光标位置、左手短暂缺帧不闪烁、用户左手不能抢占右手画笔、camera-left 大跳不接入画笔;
3. `src/services/edutainment-baby-drawing/babyDrawingClient.test.ts`:原图保存、原图加魔法图保存、后端魔法接口请求;
4. `src/routing/appRoutes.test.ts``/runtime/baby-love-drawing` 开启可达、关闭回落主应用;
5. `server-rs/crates/api-server/src/edutainment_baby_drawing.rs` 内部单测prompt、Data URL 校验、PNG 输出和轨迹范围摘要;
6. `server-rs/crates/api-server/src/creation_entry_config.rs` 路由映射单测:确认后端熔断可识别 `baby-love-drawing`

View File

@@ -30,13 +30,15 @@ baby-object-match
宝贝识物
```
文件:
工程接入文件:
1. `src/config/newWorkEntryConfig.ts`
1. `server-rs/crates/spacetime-module/src/runtime/creation_entry_config.rs`
2. `src/components/platform-entry/platformEntryCreationTypes.ts`
3. `src/components/platform-entry/PlatformEntryCreationTypeModal.tsx`
4. `src/components/platform-entry/PlatformEntryFlowShellImpl.tsx`
`src/config/newWorkEntryConfig.ts` 已迁移删除,不再作为入口事实源。`baby-object-match` 必须存在于 SpacetimeDB `creation_entry_type_config` 默认种子中,默认展示名为 `宝贝识物``visible=true``open=true``sortOrder=90`;前端只通过 `GET /api/creation-entry/config` 读取后端配置并在 `platformEntryCreationTypes.ts` 做展示派生。
`baby-object-match` 必须复用 `VITE_ENABLE_EDUTAINMENT_ENTRY` 开关;开关关闭时,创作类型弹层不展示 `宝贝识物`,创作页作品架不展示本地宝贝识物草稿或已发布作品卡,公开发现、搜索、详情、作品号和浏览历史也继续完全不可见。
新增阶段:
@@ -62,7 +64,8 @@ packages/shared/src/contracts/edutainmentBabyObject.ts
2. `BabyObjectMatchDraft.templateName = "宝贝识物"`
3. `BabyObjectMatchDraft.themeTags` 必须包含精确 `寓教于乐`
4. `BabyObjectMatchItemAsset.generationProvider` 首版允许为 `vector-engine-gpt-image-2``placeholder`
5. `BabyObjectMatchPublishRequest.draft.themeTags` 发布前必须归一化补齐 `寓教于乐`
5. `BabyObjectMatchDraft.visualPackage` 可选承载背景环境、UI 装饰框、礼物盒、篮子和烟雾弹出特效五类视觉资源;
6. `BabyObjectMatchPublishRequest.draft.themeTags` 发布前必须归一化补齐 `寓教于乐`
## 4. Service 边界
@@ -76,9 +79,64 @@ src/services/edutainment-baby-object/babyObjectMatchClient.ts
1. `createBabyObjectMatchDraft(payload)`
2. `saveBabyObjectMatchDraft(draft)`
3. `publishBabyObjectMatchWork(payload)`
3. `publishBabyObjectMatchWork(payload)`
4. `deleteLocalBabyObjectMatchDraft(profileId)`
5. `regenerateBabyObjectMatchDraftAssets(draft)`
6. `hasBabyObjectMatchPlaceholderAssets(draft)`
当前后端正式接口未在本线程扩表落地,因此 service 先走本地 Demo 存储,并把 asset 结果标记为 `placeholder`。后续后端接入时,应替换为:
当前后端正式作品持久化接口未在本线程扩表落地,因此 service 仍使用本地 Demo 存储草稿和发布状态。由于 image-2 会返回多张 base64 PNG 大图,本地 Demo 草稿必须优先写入 IndexedDB `genarrative-edutainment-baby-object-drafts/drafts`,不得把完整草稿 JSON 写入 `localStorage``localStorage` 仅作为旧版小草稿迁移读取来源,读取后迁移到 IndexedDB 并清理旧 key避免触发浏览器 `Storage` 配额错误。
物品图片生成已接入后端 image-2 接口:
```text
POST /api/creation/edutainment/baby-object-match/assets
```
请求体:
```json
{
"itemNames": ["苹果", "香蕉"]
}
```
响应体:
```json
{
"assets": [
{
"itemId": "baby-object-item-1",
"itemName": "苹果",
"imageSrc": "data:image/png;base64,...",
"assetObjectId": null,
"generationProvider": "vector-engine-gpt-image-2",
"prompt": "..."
}
],
"visualPackage": {
"themePrompt": "...",
"assets": [
{
"assetId": "baby-object-visual-background",
"assetKind": "background",
"imageSrc": "data:image/png;base64,...",
"assetObjectId": null,
"generationProvider": "vector-engine-gpt-image-2",
"prompt": "..."
}
]
}
}
```
该接口返回物品透明 PNG data URL以及同一次创作生成的视觉主题包。本地 Demo 阶段暂不写入 OSS 或 SpacetimeDB `asset_object`。当前创作链路必须真实拿到 `generationProvider = "vector-engine-gpt-image-2"` 的物品图和视觉主题包后才允许进入结果页;若本地未配置 VectorEngine、登录态失效、接口返回 401/5xx、上游生成失败或响应缺少任一资源前端 service 必须抛出错误并停留在生成失败状态,不得静默回退到占位图。
由于一次创作会生成 2 张物品图和 `background``ui-frame``gift-box``basket``smoke-puff` 5 张视觉包装图,该请求属于长耗时 image-2 链路。前端 `babyObjectMatchClient` 对该 POST 使用 10 分钟请求超时,且不做自动重试,避免第一次生成仍在后端执行时又发起第二次重复生成。后端同时启动物品图与视觉主题包生成,并把该路由的 VectorEngine 单图请求等待预算提升到至少 8 分钟,避免某张图 3 分钟附近仍在生成时被后端提前断开。后端日志记录每类资源的开始、完成和耗时,排查时优先按同一次 HTTP 请求查看 `宝贝识物 image-2 物品资源生成完成``宝贝识物 image-2 视觉资源生成完成``VectorEngine 图片生成上游错误`
历史本地草稿中若已保存 `generationProvider = "placeholder"` 的旧占位资源,结果页必须提示“重新生成 image-2 资源”,并禁用试玩和发布。用户点击重新生成、发布或试玩前,前端统一调用 `regenerateBabyObjectMatchDraftAssets(draft)` 补齐资源;补齐失败时保留在结果页并展示错误。
后续正式作品持久化接入时,应补齐:
```text
POST /api/creation/edutainment/baby-object-match/drafts
@@ -88,6 +146,25 @@ POST /api/creation/edutainment/baby-object-match/drafts/{draftId}/publish
图片生成必须在后端调用 VectorEngine `gpt-image-2-all`,不得从前端直接调用外部图片接口。
后端 image-2 prompt 约束:
1. 锁定寓教于乐板块统一的卡通绘本草地舞台插画风;
2. 每张图只能围绕对应关键词生成一个单一物品;
3. 不生成背景、场景、氛围渲染、人物、手、篮子、礼物盒、文字、水印或 UI
4. 优先要求纯白或透明抠图友好的干净背景,服务端再统一转透明 PNG 并执行背景 alpha 清理;
5. 返回 `generationProvider = "vector-engine-gpt-image-2"` 的素材必须已经完成透明抠图。
后端视觉主题包 prompt 约束:
1. 同一次请求根据两个物品关键词生成 `background``ui-frame``gift-box``basket``smoke-puff` 五类资源;
2. 总风格继续锁定寓教于乐明亮卡通绘本插画风;
3. 若关键词偏动漫角色、玩具或公仔,背景环境和 UI 元素匹配动漫、玩具主题;若关键词偏水果,匹配果园、自然主题;其它关键词按语义匹配合适主题;
4. 背景环境图使用非透明 16:9 图,但必须保证中间、中下方和底部左右篮子区域清爽,给放大后的礼物盒、中央物品和左右篮子预留空间,不画入礼物盒、篮子、物品、人物、文字或操作 UI
5. UI 装饰框、礼物盒、篮子和烟雾弹出特效使用透明 PNG 后处理,不生成文字、数字、按钮、人物或待分类物品;
6. `gift-box` 提示词必须面向运行态约 2 倍视觉尺寸生成主体饱满的大号礼物盒,`basket` 提示词必须面向运行态约 1.5 倍视觉尺寸生成可读性高的大号篮子;
7. `smoke-puff` 只生成礼物盒打开瞬间使用的柔和烟雾云朵特效,不生成礼物盒、篮子、物品或文字;
8. 左右篮子的固定选项规则不受主题包影响,运行态只把 `basket` 作为篮子造型包装复用。
## 5. UI 边界
工作台只展示两个必填输入和生成按钮。
@@ -107,27 +184,37 @@ src/components/edutainment-runtime/BabyObjectMatchRuntimeShell.tsx
运行态直接消费 `BabyObjectMatchDraft`,必须使用草稿中的两个物品名称和物品图。
每轮只随机当前从礼物盒跳出的物品;左右篮子不随机交换,左侧固定为草稿 `itemAssets[0]`,右侧固定为草稿 `itemAssets[1]`
若草稿包含 `visualPackage`运行态通过背景图片层、CSS 变量和图片节点消费:
1. `background`:作为舞台最底层 `ResolvedAssetImage` 背景图;存在该资源时必须关闭默认草地兜底层,避免生成场景被 CSS 草地遮住或弱化;
2. `ui-frame`:作为字幕条和计数器装饰背景;
3. `gift-box`:替换 CSS 礼物盒主体,按旧视觉约 2 倍尺寸展示,只在礼盒入场和打开阶段存在;
4. `basket`:替换篮子主体造型,按旧视觉约 1.5 倍尺寸展示,左右两侧复用同一张主题篮子图;
5. `smoke-puff`:作为礼物盒打开和中央物品弹出期间的透明烟雾特效资源。
旧草稿或接口失败时 `visualPackage = null`,运行态继续使用现有 CSS 绘本风兜底。
首关状态机:
1. `waiting`:礼物盒关闭,等待任意手抬起
2. `active`:当前物品停留在屏幕中央
3. `correct`:展示“真棒”反馈,成功次数加 1
4. `wrong`:展示“再想一想吧”反馈,当前物品回到中央
5. `complete`:成功次数达到 20展示“恭喜你小朋友”和按钮。
1. `gift-entering`:礼物盒从上方落下入场动画阶段,不接受动作判定
2. `gift-opening`:礼物盒打开并播放烟雾特效阶段,不接受动作判定
3. `item-appearing`:礼物盒从舞台移除,当前物品从烟雾中出现并停稳,不接受动作判定
4. `active`:物品彻底出现后才开放选篮判定
5. `correct`:展示“真棒”反馈,对应篮筐播放正确特效并停顿,成功次数加 1特效完全结束后重新进入 `gift-entering`,下一轮礼物盒从上方落下;
6. `wrong`:展示“再想一想吧”反馈,物品弹回中央;反馈结束后回到 `active`,不重新随机物品;
7. `complete`:成功次数达到 20展示“恭喜你小朋友”和按钮。
动作输入:
1. 任意手完成一次 `open_palm -> grab` 抓握序列:打开礼物盒并生成当前物品
2. 手连续横向移动达到阈值:将当前物品送入侧篮子
3. 右手连续横向移动达到阈值:将当前物品送入右侧篮子。
1. 左手连续横向移动达到阈值:将当前物品送入左侧篮子
2. 手连续横向移动达到阈值:将当前物品送入侧篮子
运行态直接通过 `useMocapInput` 消费本地 mocap WebSocket `/stream`。选篮只使用明确 `leftHand``rightHand` 的连续横向轨迹阈值,不再通过 `wave_left_hand``wave_right_hand``wave` 等动作名触发;侧别为 `unknown` 的手部轨迹也不参与选篮,以避免多套判定误命中和连续误触发。当前本地 mocap 输出的 handedness 按摄像头视角标记,宝贝识物运行态必须先换算为用户身体视角:`rightHand` 轨迹映射玩家左手并进入左侧篮子,`leftHand` 轨迹映射玩家右手并进入右侧篮子。草稿试玩、发布后正式体验和热身关后的本地 Demo 都复用同一个运行态,因此三条入口都必须具备同一套动作控制能力。
运行态直接通过 `useMocapInput` 消费本地 mocap WebSocket `/stream`。选篮只使用明确 `leftHand``rightHand` 的连续横向轨迹阈值,不再通过 `wave_left_hand``wave_right_hand``wave` 等动作名触发;侧别为 `unknown` 的手部轨迹也不参与选篮,以避免多套判定误命中和连续误触发。动作判定只在 `active` 阶段开放,礼盒入场、礼盒打开、物品出现、正确反馈和错误反馈阶段收到的动作包必须清空轨迹并忽略,不允许跨阶段补判定。当前本地 mocap 输出的 handedness 按摄像头视角标记,宝贝识物运行态必须先换算为用户身体视角:`rightHand` 轨迹映射玩家左手并进入左侧篮子,`leftHand` 轨迹映射玩家右手并进入右侧篮子。草稿试玩、发布后正式体验和热身关后的本地 Demo 都复用同一个运行态,因此三条入口都必须具备同一套动作控制能力。
开发者调试输入:
1. `F`:映射任意手抬起,打开礼物盒并生成当前物品
2. 鼠标键按下并拖动:映射手轨迹,抬起后将当前物品送入侧篮子
3. 鼠标右键按下并拖动:映射右手轨迹,抬起后将当前物品送入右侧篮子。
1. 鼠标左键按下并拖动:映射左手轨迹,抬起后将当前物品送入左侧篮子
2. 鼠标键按下并拖动:映射手轨迹,抬起后将当前物品送入侧篮子
运行态不得新增计时、失败次数、分数、体力或难度递增规则。
@@ -154,6 +241,7 @@ src/components/edutainment-runtime/BabyObjectMatchRuntimeShell.tsx
```bash
npm run test -- src/components/platform-entry/platformEntryCreationTypes.test.ts src/components/edutainment-creation/BabyObjectMatchWorkspace.test.tsx src/components/edutainment-result/BabyObjectMatchResultView.test.tsx src/components/edutainment-runtime/BabyObjectMatchRuntimeShell.test.tsx src/components/child-motion-demo/ChildMotionWarmupDemo.test.tsx src/services/edutainment-baby-object/babyObjectMatchClient.test.ts
cargo test -p api-server edutainment_baby_object --manifest-path server-rs/Cargo.toml
npx vitest run src/components/platform-entry/platformEdutainmentVisibility.test.ts src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/custom-world-home/creationWorkShelf.test.ts src/services/useMocapInput.test.ts src/services/child-motion-demo/childMotionDebugInput.test.ts src/routing/appRoutes.test.ts
npx eslint src/components/platform-entry/platformEntryCreationTypes.ts src/components/platform-entry/platformEntryCreationTypes.test.ts src/components/platform-entry/PlatformEntryFlowShellImpl.tsx --ext .ts,.tsx --max-warnings 0
npm run check:encoding

View File

@@ -170,6 +170,9 @@
3. 位置类状态必须满足“到达绿色圆环并保持 2 秒”。
4. 动作类状态没有最长等待时间。
5. 动作类状态等待 3 秒后可以播放对应引导动画。
6. 每个步骤进入时需要先展示本步骤文字字幕和语音播报入口,约 1 秒后再进入可交互阶段并展示绿色圆环、手势引导等检测提示。
7. 步骤完成后需要先进入完成停顿阶段,当前停顿约 0.8 秒;停顿期间保留完成反馈位置,后续可在该阶段补充完成特效或音效,再切换到下一步骤。
8. 入场等待和完成停顿阶段不消费动作完成判定,避免用户上一步残留动作直接触发下一步。
### 6.3 开发者调试输入
@@ -368,6 +371,17 @@
用户完成挥动左手。
当前本地 mocap 的 handedness 按摄像头视角输出,热身关内需要先换算成用户身体视角再判断:摄像头右侧手对应用户左手。挥动左手不是普通横向轨迹检测,而是用于确认现实环境中用户左侧手臂打开空间足够和安全。
完成条件必须同时满足:
1. 使用用户身体左手轨迹。
2. 手腕在左肩外侧达到最小外展距离。
3. 手腕不能处于自然下垂低位。
4. 最近连续有效帧中,手臂存在足够上下摆动幅度。
5. 最近连续有效帧中,肩膀到手腕向量的角度变化达到阈值。
6. 至少出现一次上下摆动方向变化。
#### 完成反馈
```text
@@ -376,7 +390,7 @@
#### 数据记录
记录用户挥动左手的空间,保存为该用户对应的行为坐标。
记录用户挥动左手的轨迹、空间包络、角度范围和最大外展距离,保存为该用户对应的行为坐标。
---
@@ -398,6 +412,17 @@
用户完成挥动右手。
当前本地 mocap 的 handedness 按摄像头视角输出,热身关内需要先换算成用户身体视角再判断:摄像头左侧手对应用户右手。挥动右手不是普通横向轨迹检测,而是用于确认现实环境中用户右侧手臂打开空间足够和安全。
完成条件必须同时满足:
1. 使用用户身体右手轨迹。
2. 手腕在右肩外侧达到最小外展距离。
3. 手腕不能处于自然下垂低位。
4. 最近连续有效帧中,手臂存在足够上下摆动幅度。
5. 最近连续有效帧中,肩膀到手腕向量的角度变化达到阈值。
6. 至少出现一次上下摆动方向变化。
#### 完成反馈
```text
@@ -406,7 +431,7 @@
#### 数据记录
记录用户挥动右手的空间,保存为该用户对应的行为坐标。
记录用户挥动右手的轨迹、空间包络、角度范围和最大外展距离,保存为该用户对应的行为坐标。
---
@@ -653,18 +678,21 @@
3. 鼠标左键按下并拖动映射左手轨迹。
4. 鼠标右键按下并拖动映射右手轨迹。
5. 空格键映射原地跳跃。
6. 调试输入只在步骤可交互阶段触发步骤完成;步骤入场字幕阶段和完成停顿阶段会忽略完成判定,便于观察节奏和后续补充特效。
当前硬件和动作检测接口接入:
1. 浏览器摄像头视频流已接入舞台背景。
2. 热身关全流程已通过 `src/services/useMocapInput.ts` 接入本地 mocap WebSocket `/stream`;动作数据源状态优先于浏览器背景摄像头状态展示。
3. mocap 包支持从 `general.body.center_norm` 读取身体中心,位置类步骤使用该身体中心更新角色剪影横向位置并完成圆环保持检测。
4. mocap 包支持从 `actions/action/gesture/gestures/event/name/type` 读取动作名,并支持 `hands[]``leftHand/rightHand``left_hand/right_hand` 读取左右手坐标。
5. `hands[].landmarks` 存在时优先用手腕和 MCP 点计算掌心中心;掌心点不足时退回 wrist landmark再退回 hand 直出坐标
6. `wave_greeting` 可由 `wave/wave_greeting/hand_wave/open_palm` 等动作或 open palm 手势完成
7. `wave_left_hand``wave_right_hand` 优先消费对应左右手动作名;当硬件只持续输出手部坐标时,也可以根据连续手部横向轨迹完成挥手检测
8. `jump_once` 消费 `jump/jump_once/hop` 等跳跃动作事件完成
9. 键盘 `A/D/Space` 与鼠标左右键拖拽仍保留为本地 Demo 调试兜底,不代表正式硬件口径
4. 身体中心横向坐标进入角色剪影前必须做输入稳定化处理:先 clamp 到 `0..1`,再使用小幅死区、低通阻尼和单包最大步长限制,避免硬件噪声造成角色左右误判、画面抽搐或视觉上的忽大忽小。当前实现参数为死区 `0.012`、阻尼系数 `0.28`、单包最大步长 `0.035`;位置保持检测使用稳定化后的角色坐标。
5. 角色剪影渲染需要把水平位移和跳跃表现拆开:外层只负责横向定位,内层资源只负责轮廓图和跳跃位移,避免 `left``transform` 同时抢占导致半透明资源重采样抖动
6. mocap 包支持从 `actions/action/gesture/gestures/event/name/type` 读取动作名,并支持 `hands[]``leftHand/rightHand``left_hand/right_hand` 读取左右手坐标
7. `hands[].landmarks` 存在时优先用手腕和 MCP 点计算掌心中心;掌心点不足时退回 wrist landmark再退回 hand 直出坐标
8. `wave_greeting` 消费左手、右手或未知单手的连续横向挥手轨迹,不再使用 `wave``hand_wave``open_palm`、张手状态或动作名直接完成判定;进入轨迹判定前必须先满足抬手有效区:优先使用 `hands[].landmarks.wrist``general.limb_nodes` 的同侧 `*_elbow` / `*_shoulder` 判断,当前阈值为 `wrist.y <= elbow.y + 0.04`,缺少肘部时使用 `wrist.y <= shoulder.y + 0.08`;缺少同侧肘部和肩膀参考时不允许招呼通过,不再使用身体中心兜底判断抬手。轨迹阈值为至少 5 个连续抬手点,横向 `x` 范围差值不小于 `0.075`,且至少出现 1 次横向方向变化,避免“手刚露出画面”或“手自然下垂抖动”被误判为招手
9. `wave_left_hand``wave_right_hand` 只消费用户身体侧对应手的连续坐标轨迹,不再使用动作名、张手状态或 primary hand 兜底完成判定;本地 mocap handedness 当前按摄像头视角输出,因此用户左手使用 camera-right用户右手使用 camera-left。完成判定必须同时满足对应肩肘腕外展、手腕非自然下垂、连续有效帧、横向范围、上下摆动范围、肩腕角度范围和上下方向变化当前阈值为连续外展点不少于 5 个、横向 `x` 范围不小于 `0.055`、垂直 `y` 范围不小于 `0.08`、肩腕角度范围不小于 `28°`、外展距离不小于 `0.12`、手腕相对肩膀外侧距离不小于 `0.1`;后续以真实体验结果继续调参
10. `jump_once` 消费 `jump/jump_once/hop` 等跳跃动作事件完成。
11. 键盘 `A/D/Space` 与鼠标左右键拖拽仍保留为本地 Demo 调试兜底,不代表正式硬件口径。
当前未接入但已保留边界:
@@ -682,14 +710,17 @@
5. 当前已生成并接入以下正式 Demo 资源:
- `public/child-motion-demo/picture-book-grass-stage.png`:默认草地舞台背景。
- `public/child-motion-demo/picture-book-foreground-grass-v2.png`:底部前景草坪条,只覆盖舞台下沿,不作为整块地板拉伸。
- `public/child-motion-demo/picture-book-ground-ring-v2.png`已按透视绘制的地面椭圆指示环CSS 只等比缩放。
- `public/child-motion-demo/picture-book-ground-ring-v3.png`:已按透视绘制的浅蓝与暖黄色地面椭圆指示环,和草地材质做明显区分,CSS 只等比缩放。
- `public/child-motion-demo/picture-book-character-outline-v2.png`:半透明用户角色轮廓,使用独立去背后处理避免内部填充被误删。
- `public/child-motion-demo/picture-book-hud-strip-v2.png`:顶部 HUD 细长软纸条。
- `public/child-motion-demo/picture-book-calibration-strip-v2.png`:右下角五格热身状态条。
- `public/child-motion-demo/picture-book-start-panel-v2.png`:开始按钮背后的轻盈托盘。
- `public/child-motion-demo/picture-book-ui-button-v2.png`:开始按钮绘本风按钮底图。
- `public/child-motion-demo/picture-book-wave-cat-body-guide-v6.png`:招手阶段中央猫咪身体底座资源,按可动纸偶结构只包含猫头、短身体和肩部连接点,不再和旧猫头、胸口或猫爪资源叠加。
- `public/child-motion-demo/picture-book-wave-cat-arm-guide-v6.png`:招手阶段左右独立手臂资源,也用于左右手阶段单手提示;网页用同一拆件镜像复用,并围绕肩部挂点做挥手摆动动画。
6. v2 资源按最终用途拆分CSS 必须按资源原始比例、`aspect-ratio``background-size: contain / auto` 等方式等比使用;禁止把方形面板强行拉伸为 HUD、状态条或地板也禁止把底部草坪扩展成覆盖角色脚下的大色块。
7. 若后续补充或重绘资源,应先运行 `npm run assets:child-motion-demo -- --dry-run` 核对 prompt 和输出路径,再使用 `--live --only <asset-id>` 小批量生成;仅调整透明去背、裁切、画布归一或品红边缘时,可用 `npm run assets:child-motion-demo -- --live --postprocess-only --force --only <asset-id>` 复用 `tmp/child-motion-demo-assets/` 中的源图,不额外请求 image-2不得把 `VECTOR_ENGINE_API_KEY`、源图或中间预览图提交到仓库
7. 猫咪招手引导资源使用 `cat-guide` 透明后处理:先由 image-2 生成品红底源图,再通过边缘背景连通区域去背,避免把浅粉、淡橘和暖棕主体误删。源图只保存在 `tmp/child-motion-demo-assets/`,正式页面只引用 `public/child-motion-demo/` 下的最终 PNG
8. 若后续补充或重绘资源,应先运行 `npm run assets:child-motion-demo -- --dry-run` 核对 prompt 和输出路径,再使用 `--live --only <asset-id>` 小批量生成;仅调整透明去背、裁切、画布归一或品红边缘时,可用 `npm run assets:child-motion-demo -- --live --postprocess-only --force --only <asset-id>` 复用 `tmp/child-motion-demo-assets/` 中的源图,不额外请求 image-2不得把 `VECTOR_ENGINE_API_KEY`、源图或中间预览图提交到仓库。
已执行的定向验证命令:

View File

@@ -32,6 +32,8 @@ process didn't exit successfully: `server-rs\target\debug\api-server.exe`
主站和后台 Vite 也追加 `--strictPort`,避免默认漂移到 `3001``3103` 等端口后让浏览器继续访问旧页面。
`--skip-spacetime` 是复用既有 SpacetimeDB 宿主的模式。该模式下脚本不会再把 SpacetimeDB 端口纳入可用性漂移;如果传入 `--spacetime-port 3101`,后端就会连接 `http://127.0.0.1:3101`。这可以避免 `3101` 已有 SpacetimeDB 在线时,端口工具误把它当作冲突并改到空闲的 `3102`,导致 api-server 连接空端口后 `/api/creation-entry/config`、作品架和公开图库接口同时返回 `502`
## 排障步骤
PowerShell 查看默认端口占用:
@@ -72,3 +74,4 @@ node scripts/run-bash-script.mjs scripts/dev-rust-stack.sh \
1. `bash -n scripts/dev-rust-stack.sh` 通过。
2. 默认端口被占用时重新运行完整栈,脚本应在 publish 前失败并打印占用进程。
3. 清理占用进程或换端口后,重新启动时不再出现 Vite 端口漂移或 `api-server` `AddrInUse`
4. 复用 SpacetimeDB 时执行 `npm run dev -- --skip-spacetime --skip-publish --spacetime-port 3101`,启动日志里的 `[dev:rust] spacetime:` 应保持为 `http://127.0.0.1:3101`,并且 `GET /api/creation-entry/config` 不应因连接 `3102` 这类空端口而失败。

View File

@@ -9,6 +9,7 @@
1. 新建作品入口配置统一存放在 SpacetimeDB 的 `creation_entry_config` / `creation_entry_type_config` 表;默认种子位于 `server-rs/crates/spacetime-module/src/runtime/creation_entry_config.rs`
2. `visible` 控制玩法是否展示在创作 Tab 模板入口、新建作品入口和创作类型弹层中。
3. `open` 控制玩法是否允许点击创建以及对应创作 / runtime API 路由是否放行;`open: false` 时入口保持展示但禁用,并由 `api-server` 熔断对应玩法 API。
- 前端作品架、发现页聚合和预加载只应请求 `open: true` 的玩法接口;`open: false` 的未开放玩法可以展示为敬请期待入口,但不得把对应 API 熔断错误透传到草稿页或发现页。
4. `title``subtitle``badge` 控制玩法卡片文案。
5. `startCard` 控制旧创作中心顶部新建作品模块的标题、辅助文案和移动端角标文案;当前创作 Tab 首屏标题固定在 `PlatformEntryFlowShellImpl.tsx`,不再由 `startCard` 控制。
6. `typeModal` 控制平台创作类型弹层标题和描述。
@@ -28,6 +29,21 @@
| AIRP | 是 | 否 | 保留入口,显示敬请期待 |
| 视觉小说 | 是 | 否 | 保留入口,显示敬请期待,暂不允许创建视觉小说草稿 |
| 智能创作 | 否 | 是 | 入口隐藏,既有 `creative-agent` 链路保留 |
| 宝贝识物 | 是 | 是 | 寓教于乐首关模板,必须由 `creation_entry_type_config` 默认种子或后台入口开关保持存在 |
## 排障约束
`baby-object-match` 是寓教于乐创作模板和发现页宝贝识物作品合流的共同开关。若 `creation_entry_type_config` 缺少该行,前端会同时出现“创作界面没有宝贝识物模板”和“寓教于乐分类下已发布作品消失”的现象。
默认种子必须包含:
- `id = baby-object-match`
- `title = 宝贝识物`
- `visible = true`
- `open = true`
- `sort_order = 90`
入口图首版复用 `/child-motion-demo/picture-book-grass-stage.png`,后续如生成专属 image-2 入口图,可通过后台入口开关更新 `imageSrc`
## 验收

View File

@@ -5,6 +5,7 @@
## 文档列表
- [WECHAT_MINIPROGRAM_WEB_VIEW_SHELL_2026-05-03.md](./WECHAT_MINIPROGRAM_WEB_VIEW_SHELL_2026-05-03.md):记录微信小程序 `web-view` 壳的最小接入范围、需要填写的 H5 业务域名、微信后台配置、`npm run check:wechat-miniprogram-auth` 可重复登录链路 smoke 和后续原生化边界。
- [BABY_LOVE_DRAWING_RUNTIME_DEMO_IMPLEMENTATION_2026-05-13.md](./BABY_LOVE_DRAWING_RUNTIME_DEMO_IMPLEMENTATION_2026-05-13.md):冻结寓教于乐 `宝贝爱画` 独立本地 Demo 运行态实现方案,明确发现页默认卡片、`/runtime/baby-love-drawing` 路由、画板交互、mocap/键鼠调试映射、本地保存和 VectorEngine image-2 绘画魔法后端代理。
- [BARK_BATTLE_BACKEND_DDD_TECHNICAL_PLAN_2026-05-11.md](./BARK_BATTLE_BACKEND_DDD_TECHNICAL_PLAN_2026-05-11.md):冻结“汪汪声浪大作战 / bark-battle”后端 DDD 技术方案,明确 `server-rs + Axum + SpacetimeDB` 分层边界、shared contracts、作品配置、runtime run、派生成绩、排行榜、`work_play_start` 埋点、migration/绑定生成策略,以及不保存原始麦克风音频的隐私与反作弊约束。
- [BARK_BATTLE_2D_RUNTIME_TECHNICAL_PLAN_2026-05-11.md](./BARK_BATTLE_2D_RUNTIME_TECHNICAL_PLAN_2026-05-11.md):冻结“汪汪声浪大作战 / bark-battle”2D 浏览器 runtime 技术方案,明确 Phaser + TypeScript + Vite 选型、纯 TS simulation 与 Phaser renderer/DOM HUD 边界、Web Audio 输入适配、移动端权限降级和后续测试验证命令。
- [PUBLIC_WORK_DETAIL_NOT_FOUND_RECOVERY_2026-05-11.md](./PUBLIC_WORK_DETAIL_NOT_FOUND_RECOVERY_2026-05-11.md):记录直接访问公开作品详情深链时作品不存在或已下架的回首页修复,避免关闭提示后停在 `work-detail` 空状态白屏。

View File

@@ -36,8 +36,9 @@ npm run dev:rust
1. `npm run dev` / `npm run dev:rust` 会先检查 SpacetimeDB、Rust `api-server`、主站 Vite、后台 Vite 需要使用的端口。
2. 如果优先端口不可用,脚本会从该端口开始向后寻找可用端口,并将解析后的端口覆盖到后续 `spacetime start``spacetime publish --server``GENARRATIVE_API_PORT``RUST_SERVER_TARGET``GENARRATIVE_RUNTIME_SERVER_TARGET``ADMIN_API_TARGET` 与 Vite 启动参数。
3. 控制台会打印 `[dev:ports] ... 可用``[dev:ports] ... 不可用,改用 ...`,排查代理错配时以该日志和后续 `[dev:rust] web/admin web/rust api/spacetime` 实际地址为准
4. 单独 `npm run dev:web` 也会检查主站 Vite 端口;`WEB_PORT`默认 `3000` 不可用时,会自动切到后续可用端口并继续严格端口启动
3. 显式传入 `--skip-spacetime` 时,脚本不会对 SpacetimeDB 端口做可用性漂移;此时 `--spacetime-port` 表示要复用的既有 SpacetimeDB 地址。后端会直接使用该地址,避免 `3101` 已有可用宿主时被误改到空闲但未启动的 `3102`
4. 控制台会打印 `[dev:ports] ... 可用``[dev:ports] ... 不可用,改用 ...`,排查代理错配时以该日志和后续 `[dev:rust] web/admin web/rust api/spacetime` 实际地址为准
5. 单独 `npm run dev:web` 也会检查主站 Vite 端口;`WEB_PORT` 或默认 `3000` 不可用时,会自动切到后续可用端口并继续严格端口启动。
默认流程:
@@ -70,7 +71,7 @@ Vite 代理覆盖范围:
本地联调跳过策略:
1. 如果 `3101` 已被当前可复用的 SpacetimeDB standalone 占用,脚本会优先按 `spacetime.pid``dev-rust-spacetime-url` 复用该宿主;如果确认不是可复用宿主,则会先输出占用进程并选择最近可用端口。也可显式使用 `npm run dev -- --skip-spacetime` 跳过 SpacetimeDB 宿主启动,或`--spacetime-port` 指定起始探测端口。
1. 如果 `3101` 已被当前可复用的 SpacetimeDB standalone 占用,脚本会优先按 `spacetime.pid``dev-rust-spacetime-url` 复用该宿主;如果确认不是可复用宿主,则会先输出占用进程并选择最近可用端口。也可显式使用 `npm run dev -- --skip-spacetime --spacetime-port 3101` 跳过 SpacetimeDB 宿主启动并复`http://127.0.0.1:3101`。在 `--skip-spacetime` 模式下,`--spacetime-port` 不是起始探测端口,而是必须已经在线的目标端口
2. 如果当前没有修改 `server-rs/crates/spacetime-module`,可使用 `npm run dev -- --skip-publish` 跳过数据库发布,降低本地启动时的 SpacetimeDB wasm 编译耗时。
3. 如果当前阶段只需要检查 `spacetime-module` 语法,不需要重新发布本地数据库,可执行 `cargo check -p spacetime-module --manifest-path server-rs/Cargo.toml`。该命令只做 Rust 编译检查,不生成新数据库,也不刷新 bindings。