Merge branch 'master' of https://git.genarrative.world/GenarrativeAI/Genarrative
This commit is contained in:
@@ -49,3 +49,7 @@ AI 文字游戏模板接入以 [AI_NATIVE_TEXT_GAME_TEMPLATE_MOKU_REFERENCE_PRD_
|
||||
- `reference/`:偏目录、速查、检索辅助。
|
||||
- `tracking/`:偏埋点原始事实和聚合投影查询,不放任务进度或钱包对账。
|
||||
- `operations/`:偏后台运营核查、对账和排障查询。
|
||||
|
||||
## 文档命名规则
|
||||
|
||||
后续新增的 Markdown 文档文件名必须以分类标签开头,格式为 `【标签名】中文标题-日期.md`。标签用于跨目录检索,不替代上面的目录分类;历史文档不要求批量重命名,除非本次任务明确涉及该文档。
|
||||
|
||||
@@ -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 式创作工具与结构化工作台方案的优缺点对比,以及转型设计。
|
||||
|
||||
423
docs/design/TAONIER_BRAND_LOGO_CONCEPTS_2026-05-13.md
Normal file
423
docs/design/TAONIER_BRAND_LOGO_CONCEPTS_2026-05-13.md
Normal file
@@ -0,0 +1,423 @@
|
||||
# 陶泥儿品牌 Logo 概念稿
|
||||
|
||||
> 本稿是围绕候选产品名“陶泥儿”的品牌视觉探索,不替代当前已冻结的“百梦”正式命名口径。若后续确认更名,需要另起产品命名、前后端文案和商标检索落地方案。
|
||||
|
||||
## 1. 品牌定位归纳
|
||||
|
||||
“陶泥儿”适合承接的不是传统陶艺或儿童黏土,而是“把灵感塑形成可玩内容”的 AI 创作平台隐喻。
|
||||
|
||||
核心关键词:
|
||||
|
||||
- 精品:作品不是随手糊出来,而是经过 AI 辅助打磨、可被消费和传播的轻精品内容。
|
||||
- UGC:用户是主要造物者,平台降低创作门槛。
|
||||
- 创作:从一句脑洞、一个梗、一张图,生成小游戏、互动作品或可分享内容。
|
||||
- 裂变与梗:名字要支持“开捏”“捏个梗”“捏个小游戏”这类用户语言。
|
||||
- 轻度休闲:体验应松弛、即时、好玩,不走硬核生产工具气质。
|
||||
- AI:AI 是塑形能力,不是冷冰冰的技术标签。
|
||||
|
||||
推荐品牌主张:
|
||||
|
||||
```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 “一捏成型”继续打磨。目标是保留“两个软形触点 + 中央作品核”的成型瞬间,同时降低括号感、碰撞特效感和功能按钮感。
|
||||
|
||||

|
||||
|
||||
### 3.1 捏合星核
|
||||
|
||||

|
||||
|
||||
定位:一捏成型方向的主标首选。
|
||||
|
||||
这个方向最稳地保留了“左右合拢、中央成型”的核心动作,中心青绿色星核形成了明确焦点,整体比原 V3-03 更完整,也没有明显播放器、聊天或表情联想。
|
||||
|
||||
优点:
|
||||
|
||||
- 结构清楚,第一眼能看出“合拢生成”。
|
||||
- 元素少,小尺寸适配潜力好。
|
||||
- 中央星核可以做加载、生成成功、发布完成等动效延展。
|
||||
|
||||
风险:
|
||||
|
||||
- 左右软形仍有一点括号感,后续矢量化可把外轮廓做得更不对称、更像被捏塑的软泥。
|
||||
|
||||
建议用途:主 Logo 备选首选、AI 生成按钮、启动动效核心符号。
|
||||
|
||||
### 3.2 成型印记
|
||||
|
||||

|
||||
|
||||
定位:完整主标感最强的延展方向。
|
||||
|
||||
这个方向把左右触点收成一个更完整的软形图腾,减少了“两个括号”的割裂感。视觉上更像独立品牌符号,但也因此少了一点“捏合动作”的即时感。
|
||||
|
||||
建议用途:主 Logo 强备选;若选择它,后续应去掉背景底色并强化中心负形星点。
|
||||
|
||||
### 3.3 软泥合拍
|
||||
|
||||

|
||||
|
||||
定位:轻松、年轻、动效友好。
|
||||
|
||||
这个方向的上下软形更活泼,适合表达“啪嗒一下成型”。但静态 Logo 中的黄色星点和短线略像特效贴纸,主标使用前需要继续简化。
|
||||
|
||||
建议用途:生成中动效、运营图、互动反馈,不建议直接定为主 Logo。
|
||||
|
||||
### 3.4 灵感模口
|
||||
|
||||

|
||||
|
||||
定位:最有“模口 / 造物容器”意味。
|
||||
|
||||
这个方向图形独特,和“从软泥模口里生成作品”的隐喻贴合。但外形复杂度比 01、02 更高,边缘细节在小尺寸下可能损失。
|
||||
|
||||
建议用途:主 Logo 备选探索,适合继续做专业矢量简化。
|
||||
|
||||
### 3.5 捏开灵感
|
||||
|
||||

|
||||
|
||||
定位:温和、包裹、生成容器。
|
||||
|
||||
这个方向亲和、平衡,但整体像眼睛 / 容器 / 开合结构,陶泥儿的“捏”动作弱一些。
|
||||
|
||||
建议用途:AI 生成入口、等待态、创作容器辅助图形。
|
||||
|
||||
## 4. V3 抽象主标候选
|
||||
|
||||
V3 根据评审反馈重新避开了五个问题:播放三角、褐色陶土主色、聊天气泡 / 表情包、循环符号,以及过多碎元素。方向转为更抽象、更亮眼、更像长期主 Logo 的符号。
|
||||
|
||||

|
||||
|
||||
### 4.1 灵感捏痕
|
||||
|
||||

|
||||
|
||||
定位:主 Logo 首选。
|
||||
|
||||
这个方向用醒目的珊瑚红软形、指纹捏痕和星点负形建立记忆点。它不再依赖“陶泥的褐色”,而是用“被捏过的痕迹”表达陶泥儿的核心动作:用户把脑洞捏成作品。
|
||||
|
||||
优点:
|
||||
|
||||
- 第一眼足够醒目,远离旧版褐色和播放器感。
|
||||
- 指纹捏痕有独特性,能承接“人人创作”和“亲手塑形”。
|
||||
- 元素少,适合继续矢量化和小尺寸适配。
|
||||
|
||||
风险:
|
||||
|
||||
- 指纹弧线后续需要进一步简化,避免在 24px 以下变糊。
|
||||
- 星点比例要克制,避免变成普通灵感图标。
|
||||
|
||||
建议用途:主 Logo、App icon、平台顶栏、启动页、生成按钮。
|
||||
|
||||
### 4.2 脑洞种子
|
||||
|
||||

|
||||
|
||||
定位:创意生长与新手友好。
|
||||
|
||||
这个方向从“灵感发芽”切入,比陶泥更偏创造生命力。它亲和、可爱,但容易让用户联想到教育、植物、儿童启蒙或种植类产品。
|
||||
|
||||
建议用途:新手引导、创作孵化、儿童 / 寓教于乐支线,不建议作为主 Logo。
|
||||
|
||||
### 4.3 一捏成型
|
||||
|
||||

|
||||
|
||||
定位:AI 把灵感合成为作品的瞬间。
|
||||
|
||||
这个方向很简洁,用左右两个软形触点和中心星点表达“捏合”。它避开了播放器和聊天气泡,也能做动效,但静态图形目前稍像碰撞特效或括号,需要继续重绘增强独特轮廓。
|
||||
|
||||
建议用途:生成按钮、AI 施法动效、主 Logo 备选微调方向。
|
||||
|
||||
### 4.4 作品胶囊
|
||||
|
||||

|
||||
|
||||
定位:精品内容和作品沉淀。
|
||||
|
||||
这个方向更稳、更精品,青绿色也比褐色更吸睛。但整体像水滴、宝石或通用内容图标,和“捏”这个动作的关系弱。
|
||||
|
||||
建议用途:精选作品、作品库、创作者中心,不建议优先做主 Logo。
|
||||
|
||||
### 4.5 软体 T 形
|
||||
|
||||

|
||||
|
||||
定位:英文辅助名 / Taonier 的抽象首字母。
|
||||
|
||||
这个方向试图做更品牌化的抽象符号,但当前形体还不够自然,也未形成足够强的“陶泥儿”心智。若未来英文名确定为 `Taonier` 或类似形式,可以继续沿这个方向做专业字母标重绘。
|
||||
|
||||
建议用途:英文标识探索,不作为当前主 Logo 首选。
|
||||
|
||||
## 5. V2 扁平矢量候选
|
||||
|
||||
第一批图形偏 3D 和拟物,更适合作为吉祥物、运营图或启动页气氛图,不适合作为长期主 Logo。V2 已把约束收紧为扁平、矢量、少元素、强轮廓和小尺寸可识别。
|
||||
|
||||

|
||||
|
||||
### 5.1 扁平开捏
|
||||
|
||||

|
||||
|
||||
定位:最直接的主 Logo 候选。
|
||||
|
||||
这个方向用一团柔软陶泥承载播放符号,用户一眼能理解“点开玩 / 马上玩”,同时外形保留“捏出来”的不规则软泥感。
|
||||
|
||||
优点:
|
||||
|
||||
- 识别速度最快,移动端小尺寸也成立。
|
||||
- 符合主流 App Logo 语言,亲和、不重、不技术冷。
|
||||
- 和“把脑洞捏成小游戏”的主张绑定最强。
|
||||
|
||||
风险:
|
||||
|
||||
- 播放符号是常见母题,后续矢量化时要通过不规则软泥外轮廓、颜色和字标形成独特资产。
|
||||
|
||||
建议用途:主 Logo 首选、App icon、平台顶栏、分享卡片角标。
|
||||
|
||||
### 5.2 灵感泥星
|
||||
|
||||

|
||||
|
||||
定位:AI 创作与灵感生成。
|
||||
|
||||
这个方向比“扁平开捏”更品牌化,中心负形星点表达灵感、AI 生成和创意爆发。它没有播放符号那么直白,但更容易和“陶泥儿”的创作平台气质绑定。
|
||||
|
||||
优点:
|
||||
|
||||
- 图形更简洁,品牌记忆点强。
|
||||
- 陶泥心智、AI 灵感和精品感比较平衡。
|
||||
- 适合未来扩成字标、启动页和生成态动效。
|
||||
|
||||
风险:
|
||||
|
||||
- 对“小游戏/马上玩”的表达弱于播放符号。
|
||||
|
||||
建议用途:主 Logo 强备选、创作首页、AI 生成按钮和品牌主视觉。
|
||||
|
||||
### 5.3 造梗笑泥
|
||||
|
||||

|
||||
|
||||
定位:社交传播和玩梗亲和力。
|
||||
|
||||
这个方向的气泡与笑脸非常亲和,适合表达“分享快乐”和“造梗”。但它和聊天、社区类产品的通用图形过近,作为主 Logo 可能会让用户误判产品品类。
|
||||
|
||||
建议用途:社区、评论、分享、活动贴纸,不建议做主 Logo。
|
||||
|
||||
### 5.4 共创泥环
|
||||
|
||||

|
||||
|
||||
定位:AI 与用户共创闭环。
|
||||
|
||||
这个方向表达共创与循环,但生成结果带有偏柔和彩虹渐变的视觉倾向,与“陶泥儿”的软泥名称关联不够直观,也不如 01/02 容易记住。
|
||||
|
||||
建议用途:创作流程、共创能力、生成进度辅助图形。
|
||||
|
||||
### 5.5 精品泥印
|
||||
|
||||

|
||||
|
||||
定位:精品作品和内容集合。
|
||||
|
||||
这个方向像内容平台或作品库入口,能表达图片、用户、游戏等多形态内容。但图形元素较多,主标识别不如 01/02 凝练。
|
||||
|
||||
建议用途:精选作品、作品集、创作者中心、内容品质标识。
|
||||
|
||||
## 6. V1 立体探索
|
||||
|
||||
### 6.1 灵感陶团
|
||||
|
||||

|
||||
|
||||
定位:AI 共创与灵感造物。
|
||||
|
||||
这个方向把“陶泥”作为主视觉,内部用发光火花和节点表达 AI 赋能。它最贴“陶泥儿”名字本身,也能说明平台不是普通小游戏集合,而是从灵感生成作品的创作容器。
|
||||
|
||||
优点:
|
||||
|
||||
- 与“陶泥儿”的名称绑定最强。
|
||||
- 有 AI、创作、造物的综合含义。
|
||||
- 适合启动页、品牌介绍、创作首页空状态。
|
||||
|
||||
风险:
|
||||
|
||||
- 小尺寸下细节偏多,需要后续矢量化时压缩节点和纹理。
|
||||
- 如果色彩处理不当,会回到手工陶艺联想。
|
||||
|
||||
建议用途:品牌主视觉备选、官网/启动页、创作入口图形。
|
||||
|
||||
### 6.2 开玩模具
|
||||
|
||||

|
||||
|
||||
定位:把脑洞捏成小游戏。
|
||||
|
||||
这个方向用软陶捏出播放符号,最直接地连接“创作”和“马上玩”。它比单纯陶泥团更有产品动作,也更适合轻休闲、小游戏、短内容传播。
|
||||
|
||||
优点:
|
||||
|
||||
- 识别强,小尺寸也清楚。
|
||||
- 与轻度休闲小游戏的关系最直接。
|
||||
- 适合作为 App icon 和主 Logo 图形。
|
||||
|
||||
风险:
|
||||
|
||||
- 播放符号相对常见,需要后续在外轮廓、捏痕和色彩上做独特性。
|
||||
- 如果三角形过硬,会削弱“陶泥儿”的柔软感。
|
||||
|
||||
建议用途:主 Logo 首选、App icon、分享卡片角标、加载态图形。
|
||||
|
||||
### 6.3 造梗气泡
|
||||
|
||||

|
||||
|
||||
定位:社交传播、玩梗、裂变。
|
||||
|
||||
这个方向把陶泥变形成聊天气泡和表情,强调“梗”和“传播”。它最有社交平台感,也适合表情包、活动贴纸和运营视觉。
|
||||
|
||||
优点:
|
||||
|
||||
- 传播感强,年轻、轻松、容易做 IP 化。
|
||||
- 能承接社区、评论、分享和玩梗场景。
|
||||
- 比较容易延展成贴纸和表情包。
|
||||
|
||||
风险:
|
||||
|
||||
- 偏软萌,可能削弱“精品 AI 创作平台”的质感。
|
||||
- 作为主 Logo 容易显得像聊天或表情产品。
|
||||
|
||||
建议用途:社区模块、活动运营、IP 辅助形象,不建议作为唯一主 Logo。
|
||||
|
||||
### 6.4 共创回路
|
||||
|
||||

|
||||
|
||||
定位:AI 与用户共同迭代生成。
|
||||
|
||||
这个方向用软陶带形成循环和造物轨迹,表达“灵感 -> AI 塑形 -> 用户修改 -> 作品传播”的闭环。它比其他方向更抽象,也更有平台级和工具级气质。
|
||||
|
||||
优点:
|
||||
|
||||
- 高级、简洁,避免儿童化。
|
||||
- 适合表达 AI 共创、迭代和作品循环。
|
||||
- 可用于创作者工作台或生成进度标识。
|
||||
|
||||
风险:
|
||||
|
||||
- 与“陶泥儿”名称的直观关联较弱。
|
||||
- 缺少小游戏和玩梗的即时识别。
|
||||
|
||||
建议用途:创作流程标识、AI 共创能力图标、品牌辅助图形。
|
||||
|
||||
### 6.5 精品泥印
|
||||
|
||||

|
||||
|
||||
定位:精品内容、作品认证、创作者成果。
|
||||
|
||||
这个方向像一个被压印的软陶徽章,中间有方块和火花,比较适合表达“作品被打磨成型”。它的内容平台感强于游戏入口感。
|
||||
|
||||
优点:
|
||||
|
||||
- 精品感和作品库气质较强。
|
||||
- 适合作品认证、精选、创作者徽章。
|
||||
- 与“陶泥压印”隐喻相对自然。
|
||||
|
||||
风险:
|
||||
|
||||
- 细节较多,主 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、后台和后端默认文案。
|
||||
101
docs/prd/BABY_LOVE_DRAWING_EDUTAINMENT_LEVEL_PRD_2026-05-13.md
Normal file
101
docs/prd/BABY_LOVE_DRAWING_EDUTAINMENT_LEVEL_PRD_2026-05-13.md
Normal 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. 保存后可再画一张或返回。
|
||||
@@ -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 次后出现“再来一次”和“下一关”按钮。
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
- 需求来源:用户提供的视频 `C:\Users\DSK\Videos\一款双方比狗叫的游戏 - 1.一款双方比狗叫的游戏(Av116504192360177,P1).mp4`,并已在 `.hermes/plans/2026-05-11_144229-bark-battle-2d-game-bdd-ddd-tdd-plan.md` 中完成抽帧分析和玩法方案整理。
|
||||
- 玩法定位:浏览器 2D 声控狗叫对战小游戏,暂定中文名 `汪汪声浪大作战`,英文代号与 play type ID 建议为 `bark-battle`。
|
||||
- 核心玩法:双方狗狗在 30 秒限时内通过麦克风输入“狗叫声”进行声浪拔河;系统依据声音强度、有效叫声次数和叫声节奏计算推动力,实时推动顶部红蓝能量条;倒计时结束后按能量条位置判定胜负或平局。
|
||||
- 核心玩法:双方狗狗在 30 秒限时内通过麦克风输入“狗叫声”进行声浪拔河;系统依据声音强度、有效声浪触发次数和声浪节奏计算推动力,实时推动顶部红蓝能量条;倒计时结束后按能量条位置判定胜负或平局。
|
||||
- 文档目的:为产品、测试、前端、后端在编码前统一可验证验收口径;本文只定义 PRD/BDD 级行为与测试映射,不实现工程代码。
|
||||
|
||||
## 角色与目标
|
||||
@@ -20,14 +20,14 @@
|
||||
### 用户目标
|
||||
|
||||
- 玩家可以在开局前完成麦克风授权和环境噪音校准。
|
||||
- 玩家发出有效狗叫时,能看到叫声计数、狗狗动画、拟声词/冲击波以及能量条变化。
|
||||
- 低于阈值的背景噪音不会被误计为有效叫声。
|
||||
- 玩家产生有效声浪触发时,能看到声浪计数、狗狗动画、拟声词/冲击波以及能量条变化。
|
||||
- 低于阈值的背景噪音不会被误计为有效声浪触发。
|
||||
- 单局在 30 秒后给出明确胜负、平局和关键数据。
|
||||
- 移动端和不支持麦克风的环境不会进入不可操作状态。
|
||||
|
||||
### 非目标
|
||||
|
||||
- MVP 不要求识别“是否真实狗叫”,不引入机器学习声纹/物种分类;有效输入以音量阈值、峰值间隔、持续时间和校准结果为准。
|
||||
- MVP 不要求识别“是否真实狗叫”,不引入机器学习声纹/物种分类;有效输入以音量阈值、峰值冷却间隔和校准结果为准。
|
||||
- MVP 不要求实时联机对战;可先按“玩家 vs AI 对手”完成单机浏览器 runtime。
|
||||
- MVP 不要求成绩持久化、作品发布、作品架、广场和排行榜;若后续接入 Genarrative 作品闭环,需要另补玩法类型集成 PRD/技术文档。
|
||||
- MVP 不要求在 UI 中长期展示大段规则说明;游戏界面应保持倒计时、能量条、狗狗、麦克风状态和结算信息为主。
|
||||
@@ -38,10 +38,10 @@
|
||||
- 单局时长:默认 30 秒,从正式进入 `playing` 阶段开始计时。
|
||||
- 能量条:使用 `-100` 到 `100` 的连续值表示,负数偏对手侧,正数偏玩家侧,`0` 为中线。
|
||||
- 平局阈值:倒计时结束时,若能量条绝对值小于或等于 `drawThreshold`,判定平局;具体数值由实现配置,但测试需可注入固定阈值。
|
||||
- 有效叫声:一次有效叫声至少满足:音量超过校准后的有效阈值、与上一次有效峰值间隔不小于 `minBarkGapMs`、持续时长在 `minBarkDurationMs` 到 `maxBarkDurationMs` 之间。
|
||||
- 背景噪音:校准阶段采集到的环境声用于计算动态阈值;低于阈值的输入不得增加叫声次数,也不得让能量条出现可见推进。
|
||||
- 推动力:玩家推动力由音量分数、有效叫声频率和连击加成组成;能量条按玩家推动力与对手推动力差值移动,并被限制在 `-100` 到 `100`。
|
||||
- UI 反馈:有效叫声应触发可观察反馈,包括玩家侧狗狗张嘴/吠叫动画、拟声词或冲击波;反馈不应遮挡倒计时和顶部能量条。
|
||||
- 有效声浪触发:一次有效声浪触发满足:当前麦克风采样点的归一化响度达到或超过校准后的有效阈值,且与上一次有效声浪触发间隔不小于 `minBarkGapMs`;不再要求持续高响度时长达标,也不等待响度回落。
|
||||
- 背景噪音:校准阶段采集到的环境声用于计算动态阈值;低于阈值的输入不得增加声浪触发次数,也不得让能量条出现可见推进。
|
||||
- 推动力:玩家推动力由音量分数、有效声浪触发频率和连击加成组成;能量条按玩家推动力与对手推动力差值移动,并被限制在 `-100` 到 `100`。
|
||||
- UI 反馈:有效声浪触发应触发可观察反馈,包括玩家侧狗狗张嘴/吠叫动画、拟声词或冲击波;反馈不应遮挡倒计时和顶部能量条。
|
||||
|
||||
## 中文 Gherkin 场景
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
场景: 校准完成后进入开局倒计时
|
||||
假如玩家已允许麦克风权限
|
||||
而且系统已采集足够的环境噪音样本
|
||||
当校准计算出有效叫声阈值
|
||||
当校准计算出有效声浪阈值
|
||||
那么系统应进入开局倒计时阶段
|
||||
而且倒计时结束后应进入 30 秒对战阶段
|
||||
而且初始能量条应位于中线
|
||||
@@ -84,19 +84,19 @@
|
||||
功能: 环境噪音校准
|
||||
为了减少背景噪音误触发
|
||||
作为浏览器玩家
|
||||
我希望游戏在开局前根据当前环境设置有效叫声阈值
|
||||
我希望游戏在开局前根据当前环境设置有效声浪阈值
|
||||
|
||||
场景: 安静环境生成低但非零的有效阈值
|
||||
假如校准阶段采集到的环境噪音 RMS 稳定低于默认噪音基线
|
||||
当系统完成校准
|
||||
那么有效叫声阈值应高于环境噪音平均值
|
||||
那么有效声浪阈值应高于环境噪音平均值
|
||||
而且阈值不应低于系统配置的最小阈值
|
||||
|
||||
场景: 嘈杂环境生成更高的有效阈值
|
||||
假如校准阶段采集到的环境噪音 RMS 高于默认噪音基线
|
||||
当系统完成校准
|
||||
那么有效叫声阈值应随环境噪音上调
|
||||
而且低于该阈值的后续输入不应计为有效叫声
|
||||
那么有效声浪阈值应随环境噪音上调
|
||||
而且低于该阈值的后续输入不应计为有效声浪触发
|
||||
|
||||
场景: 校准期间无法获得有效音频样本
|
||||
假如麦克风授权成功但音频样本持续为空或不可读
|
||||
@@ -106,36 +106,36 @@
|
||||
而且不应直接开始对战
|
||||
```
|
||||
|
||||
### 功能: 有效叫声计数
|
||||
### 功能: 有效声浪触发计数
|
||||
|
||||
```gherkin
|
||||
功能: 有效叫声计数
|
||||
为了把玩家的狗叫行为转换为可计分输入
|
||||
功能: 有效声浪触发计数
|
||||
为了把玩家的声控行为转换为可计分输入
|
||||
作为玩家
|
||||
我希望每次符合规则的短促叫声只被计数一次
|
||||
我希望每次超过阈值且满足冷却的声浪触发只被计数一次
|
||||
|
||||
背景:
|
||||
假如游戏处于 30 秒 playing 阶段
|
||||
而且系统已完成环境噪音校准
|
||||
|
||||
场景: 单次超过阈值且间隔足够的叫声计数加一
|
||||
假如玩家当前叫声次数为 0
|
||||
而且上一次有效叫声时间早于 minBarkGapMs
|
||||
当麦克风输入出现一次超过有效阈值且持续时长合规的峰值
|
||||
那么玩家叫声次数应变为 1
|
||||
场景: 单次超过阈值且间隔足够的声浪触发计数加一
|
||||
假如玩家当前声浪触发次数为 0
|
||||
而且上一次有效声浪触发时间早于 minBarkGapMs
|
||||
当某个麦克风采样点达到或超过有效阈值且满足声浪冷却
|
||||
那么玩家声浪触发次数应变为 1
|
||||
而且玩家侧应出现一次吠叫动画反馈
|
||||
而且画面应出现一次拟声词或冲击波反馈
|
||||
|
||||
场景: 持续噪音不会被无限计数
|
||||
假如玩家当前叫声次数为 1
|
||||
当麦克风输入持续超过阈值但没有新的峰值间隔
|
||||
那么玩家叫声次数不应在每个 tick 中持续增加
|
||||
而且系统最多只应记录当前连续声音段内的一次有效叫声
|
||||
场景: 持续高响度输入只按冷却节奏计数
|
||||
假如玩家当前声浪触发次数为 1
|
||||
当麦克风输入持续超过阈值但仍处于声浪冷却内
|
||||
那么玩家声浪触发次数不应在每个 tick 中持续增加
|
||||
而且系统只应在冷却结束后的采样点再次达阈值时记录下一次有效声浪触发
|
||||
|
||||
场景: 间隔过短的连续峰值不重复计数
|
||||
假如玩家刚刚产生一次有效叫声
|
||||
当麦克风输入在 minBarkGapMs 内再次出现峰值
|
||||
那么玩家叫声次数不应增加
|
||||
假如玩家刚刚产生一次有效声浪触发
|
||||
当麦克风输入在 minBarkGapMs 内再次达到有效阈值
|
||||
那么玩家声浪触发次数不应增加
|
||||
而且连击或推动力不应因该峰值重复加成
|
||||
```
|
||||
|
||||
@@ -145,23 +145,23 @@
|
||||
功能: 声浪推动能量条
|
||||
为了复刻双方比狗叫的核心体验
|
||||
作为玩家
|
||||
我希望更响、更连续的有效叫声能把顶部能量条推向自己一侧
|
||||
我希望更响、更高频的有效声浪触发能把顶部能量条推向自己一侧
|
||||
|
||||
背景:
|
||||
假如游戏处于 30 秒 playing 阶段
|
||||
而且能量条当前位于中线
|
||||
|
||||
场景: 玩家推动力高于对手时能量条向玩家侧移动
|
||||
假如玩家在短时间窗口内产生多次有效叫声
|
||||
假如玩家在短时间窗口内产生多次有效声浪触发
|
||||
而且玩家推动力高于对手推动力
|
||||
当系统推进一个 simulation tick
|
||||
那么能量条数值应向玩家侧增加
|
||||
而且顶部红蓝能量条的玩家侧占比应变大
|
||||
|
||||
场景: 连续大声叫声触发更强反馈
|
||||
假如玩家连续产生多次高于强叫声阈值的有效叫声
|
||||
场景: 连续强声浪触发触发更强反馈
|
||||
假如玩家连续产生多次高于强声浪阈值的有效声浪触发
|
||||
当系统计算玩家连击加成
|
||||
那么玩家侧推动力应高于单次普通叫声推动力
|
||||
那么玩家侧推动力应高于单次普通声浪触发推动力
|
||||
而且玩家侧声浪或冲击波反馈应比普通叫声更明显
|
||||
但是反馈不应遮挡倒计时和能量条
|
||||
|
||||
@@ -185,31 +185,30 @@
|
||||
功能: 背景噪音过滤
|
||||
为了避免环境声替玩家自动得分
|
||||
作为玩家
|
||||
我希望低于阈值或不合规的声音不会被当作有效狗叫
|
||||
我希望低于阈值或处于冷却内的声音不会被当作有效声浪触发
|
||||
|
||||
背景:
|
||||
假如游戏处于 30 秒 playing 阶段
|
||||
而且系统已完成环境噪音校准
|
||||
|
||||
场景: 低于阈值的背景噪音不计数
|
||||
当麦克风只接收到低于有效叫声阈值的背景噪音
|
||||
那么玩家叫声次数不应增加
|
||||
当麦克风只接收到低于有效声浪阈值的背景噪音
|
||||
那么玩家声浪触发次数不应增加
|
||||
而且玩家侧不应播放吠叫动画
|
||||
而且能量条不应因为该背景噪音出现可见推进
|
||||
|
||||
场景: 过短脉冲不计为有效叫声
|
||||
假如麦克风输入峰值超过有效阈值
|
||||
但是持续时长短于 minBarkDurationMs
|
||||
当系统完成该声音段判定
|
||||
那么玩家叫声次数不应增加
|
||||
场景: 冷却内重复达阈值不计数
|
||||
假如玩家刚刚产生一次有效声浪触发
|
||||
当麦克风输入在 minBarkGapMs 内再次达到有效声浪阈值
|
||||
那么玩家声浪触发次数不应增加
|
||||
而且不应触发连击加成
|
||||
|
||||
场景: 过长持续声被削弱为单段输入
|
||||
假如麦克风输入持续超过有效阈值
|
||||
但是持续时长长于 maxBarkDurationMs
|
||||
当系统完成该声音段判定
|
||||
那么系统不应按多个叫声重复计数
|
||||
而且该声音段的推动力应按持续噪音削弱规则处理
|
||||
场景: 持续高响度输入只按冷却节奏产生触发
|
||||
假如麦克风输入持续达到或超过有效声浪阈值
|
||||
当声浪冷却尚未结束
|
||||
那么系统不应在每个 tick 中重复计数
|
||||
当声浪冷却结束且当前采样仍达到有效声浪阈值
|
||||
那么系统可以记录下一次有效声浪触发
|
||||
```
|
||||
|
||||
### 功能: 倒计时与胜负结算
|
||||
@@ -227,20 +226,20 @@
|
||||
当系统时间从 30 秒推进到 0 秒
|
||||
那么界面应显示倒计时归零
|
||||
而且系统应进入 finished 结算阶段
|
||||
而且归零后的麦克风输入不应再改变本局能量条和叫声次数
|
||||
而且归零后的麦克风输入不应再改变本局能量条和声浪触发次数
|
||||
|
||||
场景: 玩家侧占优时判定玩家胜利
|
||||
假如倒计时归零时能量条数值大于 drawThreshold
|
||||
当系统进入结算阶段
|
||||
那么系统应判定玩家胜利
|
||||
而且结算面板应展示玩家叫声次数、最大音量和声浪评分
|
||||
而且结算面板应展示玩家声浪触发次数、最大音量和声浪评分
|
||||
而且应提供再来一局入口
|
||||
|
||||
场景: 对手侧占优时判定玩家失败
|
||||
假如倒计时归零时能量条数值小于 -drawThreshold
|
||||
当系统进入结算阶段
|
||||
那么系统应判定对手胜利
|
||||
而且结算面板应展示玩家叫声次数、最大音量和声浪评分
|
||||
而且结算面板应展示玩家声浪触发次数、最大音量和声浪评分
|
||||
而且应提供再来一局入口
|
||||
|
||||
场景: 能量条接近平衡时判定平局
|
||||
@@ -265,7 +264,7 @@
|
||||
当玩家选择再来一局
|
||||
那么系统应重置剩余时间为 30 秒
|
||||
而且能量条应回到中线
|
||||
而且玩家叫声次数、最大音量、连击和胜负结果应清零
|
||||
而且玩家声浪触发次数、最大音量、连击和胜负结果应清零
|
||||
而且系统应重新进入校准或开局倒计时流程
|
||||
|
||||
场景: 结算后返回玩法入口
|
||||
@@ -353,7 +352,7 @@
|
||||
假如玩家在 playing 阶段刷新页面
|
||||
当页面重新加载 bark-battle
|
||||
那么系统应重新进入权限检查或授权准备状态
|
||||
而且不应沿用刷新前的剩余时间、能量条和叫声次数作为新局结果
|
||||
而且不应沿用刷新前的剩余时间、能量条和声浪触发次数作为新局结果
|
||||
```
|
||||
|
||||
## 测试映射
|
||||
@@ -367,15 +366,15 @@
|
||||
| 嘈杂环境生成更高的有效阈值 | unit | `src/games/bark-battle/domain/BarkNoiseCalibration.test.ts` | planned |
|
||||
| 校准期间无法获得有效音频样本 | application/component | `src/games/bark-battle/application/BarkBattleController.test.ts`, `src/games/bark-battle/ui/BarkBattlePermissionPanel.test.tsx` | planned |
|
||||
| 单次超过阈值且间隔足够的叫声计数加一 | unit | `src/games/bark-battle/domain/BarkDetector.test.ts` | planned |
|
||||
| 持续噪音不会被无限计数 | unit | `src/games/bark-battle/domain/BarkDetector.test.ts` | planned |
|
||||
| 持续高响度输入只按冷却节奏计数 | unit | `src/games/bark-battle/domain/BarkDetector.test.ts` | planned |
|
||||
| 间隔过短的连续峰值不重复计数 | unit | `src/games/bark-battle/domain/BarkDetector.test.ts` | planned |
|
||||
| 玩家推动力高于对手时能量条向玩家侧移动 | unit | `src/games/bark-battle/domain/EnergyTugOfWar.test.ts` | planned |
|
||||
| 连续大声叫声触发更强反馈 | unit/integration/component | `src/games/bark-battle/domain/BarkBattleScoring.test.ts`, `src/games/bark-battle/ui/BarkBattleHud.test.tsx` | planned |
|
||||
| 连续强声浪触发触发更强反馈 | unit/integration/component | `src/games/bark-battle/domain/BarkBattleScoring.test.ts`, `src/games/bark-battle/ui/BarkBattleHud.test.tsx` | planned |
|
||||
| 能量条到达边界后不会越界 | unit | `src/games/bark-battle/domain/EnergyTugOfWar.test.ts` | planned |
|
||||
| 对手推动力高于玩家时能量条向对手侧移动 | unit | `src/games/bark-battle/domain/EnergyTugOfWar.test.ts` | planned |
|
||||
| 低于阈值的背景噪音不计数 | unit | `src/games/bark-battle/domain/BarkDetector.test.ts` | planned |
|
||||
| 过短脉冲不计为有效叫声 | unit | `src/games/bark-battle/domain/BarkDetector.test.ts` | planned |
|
||||
| 过长持续声被削弱为单段输入 | unit | `src/games/bark-battle/domain/BarkDetector.test.ts` | planned |
|
||||
| 冷却内重复达阈值不计数 | unit | `src/games/bark-battle/domain/BarkDetector.test.ts` | planned |
|
||||
| 持续高响度输入只按冷却节奏产生触发 | unit | `src/games/bark-battle/domain/BarkDetector.test.ts` | planned |
|
||||
| 倒计时每秒递减并在归零时停止对战输入 | unit/application | `src/games/bark-battle/domain/BarkBattleSession.test.ts`, `src/games/bark-battle/application/BarkBattleController.test.ts` | planned |
|
||||
| 玩家侧占优时判定玩家胜利 | unit/component | `src/games/bark-battle/domain/BarkBattleSession.test.ts`, `src/games/bark-battle/ui/BarkBattleResultPanel.test.tsx` | planned |
|
||||
| 对手侧占优时判定玩家失败 | unit/component | `src/games/bark-battle/domain/BarkBattleSession.test.ts`, `src/games/bark-battle/ui/BarkBattleResultPanel.test.tsx` | planned |
|
||||
@@ -394,8 +393,8 @@
|
||||
## 验收清单
|
||||
|
||||
- [ ] 权限允许、拒绝、非安全上下文、API 不支持、麦克风未找到/不可读、AudioContext 被拦截、校准超时或样本不可读均有明确状态,且不会误进入 playing。
|
||||
- [ ] 校准阶段会影响有效叫声阈值,低噪音不会增加叫声计数。
|
||||
- [ ] 有效叫声计数具备阈值、峰值间隔、持续时长约束。
|
||||
- [ ] 校准阶段会影响有效声浪阈值,低噪音不会增加叫声计数。
|
||||
- [ ] 有效声浪触发计数具备阈值与声浪冷却约束。
|
||||
- [ ] 能量条根据双方推动力差值双向移动,并限制在 `-100` 到 `100`。
|
||||
- [ ] 30 秒归零后停止本局输入影响,并按玩家胜利、对手胜利、平局三类结果结算。
|
||||
- [ ] 移动端核心元素可见,非关键设置收起,不在主画面堆叠长规则说明。
|
||||
@@ -405,8 +404,8 @@
|
||||
## 开放问题
|
||||
|
||||
1. MVP 是否确认只做“玩家 vs AI”,还是第一版需要双人同屏或联机对战?
|
||||
2. `drawThreshold`、`minBarkGapMs`、`minBarkDurationMs`、`maxBarkDurationMs` 的首版默认值由产品/调参阶段确认,还是先采用开发可配置默认值?
|
||||
2. `drawThreshold`、`minBarkGapMs`、有效声浪阈值 的首版默认值由产品/调参阶段确认,还是先采用开发可配置默认值?
|
||||
3. 是否允许无麦克风设备提供键盘/点击备用输入?若允许,需要另补非声控模式场景;若不允许,当前降级只提供返回入口。
|
||||
4. 是否需要在结算中记录或上报成绩、最高音量、叫声次数和声浪评分?若需要,需补埋点/后端持久化场景。
|
||||
4. 是否需要在结算中记录或上报成绩、最高音量、声浪触发次数和声浪评分?若需要,需补埋点/后端持久化场景。
|
||||
5. bark-battle 是否作为 Genarrative 正式 play type 接入创作入口、作品发布和广场,还是先作为独立 runtime 原型验证?
|
||||
6. 狗狗、背景、拟声词和冲击波素材来源是临时占位、AI 生成,还是复用项目现有素材管线?
|
||||
|
||||
@@ -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 原生视觉小说模板 PRD:TXT 玩法平台化接入](./AI_NATIVE_VISUAL_NOVEL_TEMPLATE_PRD_2026-05-05.md):参考 `Interactive-fiction-backend` / `Interactive-fiction-frontend` 的 TXT 玩法经验,但只保留视觉小说模板创作与运行闭环,完全使用 Genarrative 平台接口,并明确删除回放和外部平台功能。
|
||||
|
||||
@@ -70,7 +70,7 @@ Query:
|
||||
- SQL 固定为 `SELECT * FROM {tableName} LIMIT {limit}`;SpacetimeDB 2.2 HTTP SQL 不拼 `ORDER BY`。
|
||||
- 用户输入不直接拼入 SQL;关键词和条件在 API Server 内存中过滤。
|
||||
- private 表或 token 不可见时返回后台可读错误信息。
|
||||
- SpacetimeDB SQL 行和 SATS 值统一转成人可读 JSON:Option None 为 null,Some 展开为内部值,Timestamp 单元素数组展开为内部值,enum 可保留 tag/name 或原始数组文本。
|
||||
- SpacetimeDB SQL 行和 SATS 值统一转成人可读 JSON:Option None 为 null,Some 展开为内部值,Timestamp 单元素数组展开为内部值;已知业务枚举列应在 API Server 按表名和列名转换为业务字符串,例如 `profile_recharge_order.kind` 转为 `points` / `membership`,`profile_recharge_order.status` 转为 `pending` / `paid` / `failed` / `closed` / `refunded`。
|
||||
|
||||
## 前端页面
|
||||
|
||||
|
||||
@@ -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`。
|
||||
@@ -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
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
### 1.1 背景
|
||||
|
||||
`bark-battle` / “汪汪声浪大作战”是一个浏览器 2D 声控狗叫对战玩法。玩家通过麦克风发出狗叫声,浏览器 runtime 根据音量峰值、有效叫声次数与节奏推动顶部红蓝能量条;每局默认 30 秒;结束后按能量条偏向判定胜负或平局。
|
||||
`bark-battle` / “汪汪声浪大作战”是一个浏览器 2D 声控狗叫对战玩法。玩家通过麦克风发出狗叫声,浏览器 runtime 根据音量峰值、有效声浪触发次数与节奏推动顶部红蓝能量条;每局默认 30 秒;结束后按能量条偏向判定胜负或平局。
|
||||
|
||||
现有前端方案 `docs/technical/BARK_BATTLE_2D_RUNTIME_TECHNICAL_PLAN_2026-05-11.md` 已覆盖 Phaser / TypeScript / Vite / Web Audio / DOM HUD 的 runtime 落地方式,并明确不覆盖后端表结构、成绩持久化、作品发布、广场接入与实时多人协议。因此需要单独补充后端 DDD 技术方案,避免前端 runtime 在接入平台作品、正式游玩埋点、成绩、排行榜和发布闭环时承接不属于表现层的业务真相。
|
||||
|
||||
@@ -44,26 +44,80 @@ MVP 明确不做:
|
||||
|
||||
## 2. 玩法接入级别建议
|
||||
|
||||
### 2.1 推荐首版闭环
|
||||
### 2.1 第二阶段范围:平台作品闭环
|
||||
|
||||
建议先支持“本地 runtime + 可发布配置化作品 + 单局结果记录 / 可选排行榜”的闭环:
|
||||
第二阶段已明确为“Bark Battle 平台作品闭环”,不是单纯玩法表现深化。目标是让 bark-battle 成为 Genarrative 的正式 play type,并完成从轻创作配置、发布、正式 runtime、run start / finish、单局结果持久化、个人历史成绩、作品统计到最小排行榜的闭环。
|
||||
|
||||
1. 创作者创建 bark-battle 草稿,配置标题、描述、狗狗主题、背景、难度、单局时长、音量阈值、AI 对手参数和排行榜开关。
|
||||
Phase 2 的作品配置边界是“轻创作配置作品”:创作者可以配置标题、描述、主题/背景预设、狗狗皮肤预设、难度预设和排行榜开关;不得直接配置单局时长、有效声浪阈值、`minBarkGapMs`、AI 对手细粒度参数、分数公式或反作弊阈值。难度预设只影响 AI 对手行为强度,不影响有效阈值、声浪冷却、单局时长或分数公式;排行榜必须按 `workId + difficultyPreset + rulesetVersion` 分榜,避免不同难度和不同规则版本混排。
|
||||
|
||||
建议先支持“本地 runtime + 可发布配置化作品 + 单局结果记录 + 个人历史成绩 / 作品统计 / 最小排行榜”的闭环:
|
||||
|
||||
1. 创作者从玩法选择进入 bark-battle 后创建草稿,通过单页轻配置表单 + 预览卡片配置标题、描述、主题/背景预设、狗狗皮肤预设、难度预设和排行榜开关。
|
||||
2. 发布为稳定作品 ID,`playTypeId = "bark-battle"`。
|
||||
3. 玩家从作品页或广场进入 runtime,前端获取发布态 runtime config。
|
||||
3. 玩家可从作品详情页 CTA、广场/作品卡片、我的作品/个人作品架进入正式 runtime,前端使用稳定作品 ID 获取发布态 runtime config。
|
||||
4. 玩家授权麦克风后在本地完成 30 秒声控对战。
|
||||
5. 前端提交单局 finish 请求,只上传派生指标,例如峰值、有效叫声次数、节奏命中、最终能量、客户端结果摘要等。
|
||||
6. 后端校验 work、config version、run token、时长、分数范围和权限后,生成服务端认可的 run result / score summary。
|
||||
7. 若作品开启排行榜,则写入可投影的 leaderboard 记录。
|
||||
8. 正式作品级游玩埋点统一写 `work_play_start`,其中 `scope_kind=work`,`scope_id=稳定作品 ID`,metadata 包含 `playType`、`workId`、`sourceRoute`、`userId`。
|
||||
5. 前端提交单局 finish 请求,只上传派生指标,例如峰值、有效声浪触发次数、节奏命中、最终能量、客户端结果摘要等。
|
||||
6. 后端校验 work、config version、ruleset version、difficulty preset、run token、时长、派生指标范围和权限后,生成服务端裁决的 run result / score summary。
|
||||
7. 写入个人历史成绩与最小作品统计投影。
|
||||
8. 若作品开启排行榜且后端裁决 `serverResult = player_win`,则写入可投影的 leaderboard 记录;排行榜首版只做最小排序与展示,不引入赛季、段位或复杂反作弊,并按 `workId + difficultyPreset + rulesetVersion` 分榜。
|
||||
9. 正式作品级游玩埋点统一写 `work_play_start`,其中 `scope_kind=work`,`scope_id=稳定作品 ID`,metadata 包含 `playType`、`workId`、`sourceRoute`、`userId`。
|
||||
|
||||
|
||||
### 2.2.1 难度预设与排行榜分榜
|
||||
|
||||
Phase 2 只允许三个难度预设:`easy`、`normal`、`hard`。难度预设只能影响 AI 对手推动力曲线和 AI 声浪节奏;不得影响单局时长、有效声浪阈值、`minBarkGapMs`、分数公式或反作弊阈值。排行榜记录和查询必须带上 `difficultyPreset` 与 `rulesetVersion`,以 `workId + difficultyPreset + rulesetVersion` 作为分榜维度。
|
||||
|
||||
### 2.2.2 单局结果后端裁决
|
||||
|
||||
Phase 2 不信任前端提交的最终胜负和正式分数。前端 `finish` 只提交不可还原原始音频的派生指标:`runId`、`workId`、`configVersion`、`rulesetVersion`、`difficultyPreset`、`clientStartedAt`、`clientFinishedAt`、`durationMs`、`triggerCount`、`maxVolume`、`averageVolume`、`finalEnergy`、`comboMax`、`clientResult`,以及可选的 `sampleDigest`。其中 `clientResult` 只用于 debug/对账,不进入正式结果或排行榜。
|
||||
|
||||
后端必须校验 run 由 start 创建且未 finish、run token 匹配、work/config/ruleset/difficulty 与 start 时一致、duration 处于合理窗口、triggerCount 不超过 `durationMs / minBarkGapMs + tolerance`、音量/能量/连击字段在合法范围内。后端生成 `serverResult`、`scoreSummary`、`leaderboardScore` 和 `antiCheatFlags`,排行榜只使用后端裁决后的胜利局成绩。
|
||||
|
||||
### 2.2.3 排行榜排序口径
|
||||
|
||||
Phase 2 排行榜只收录 `serverResult = player_win` 且未被反作弊规则拒绝的单局结果;平局和失败仍进入个人历史成绩与作品统计,但不进入排行榜。`leaderboardScore` 由后端规则集生成,排序优先级为:`finalEnergy` 降序、`triggerCount` 降序、`maxVolume` 降序、`durationMs` 越接近标准局时长越优、`finishedAt` 越早越优。
|
||||
|
||||
### 2.2.4 作品统计投影口径
|
||||
|
||||
Phase 2 的作品统计是最小后端投影,不从排行榜反推。`playStartCount` 在 start run 成功时计入一次,并对齐 `work_play_start` 埋点;`finishCount` 在 finish 被后端接受时计入一次,包含胜利、平局和失败。`accepted_with_flags` 可以计入 `finishCount`,但必须同时计入 `flaggedCount`;未 start 成功、run token 不合法、重复 finish、被后端 rejected 的结果不计入 `finishCount`。
|
||||
|
||||
作品统计字段首版包含:`playStartCount`、`finishCount`、`winCount`、`drawCount`、`lossCount`、`flaggedCount`、`leaderboardEntryCount`、`bestLeaderboardScore`、`bestFinalEnergy`、`averageFinalEnergy`、`updatedAt`。Phase 2 不做 DAU/留存、按小时曲线、原始音频分析或每玩家每天聚合统计。
|
||||
|
||||
### 2.2.5 个人历史成绩口径
|
||||
|
||||
Phase 2 的个人历史成绩由“最近记录列表 + 个人最佳摘要”组成,并且只允许本人查询。后端可以保存每次被接受的 finish 记录,但首版查询接口只暴露默认最近 20 条记录,可按 `workId` 和 `difficultyPreset` 过滤;最近记录包含胜利、平局、失败和是否 flagged,但不展示详细反作弊原因。
|
||||
|
||||
个人最佳摘要按 `userId + workId + difficultyPreset + rulesetVersion` 聚合,字段包含 `bestLeaderboardScore`、`bestFinalEnergy`、`bestTriggerCount`、`bestMaxVolume`、`winCount`、`finishCount`、`lastPlayedAt`。失败、平局和 flagged 历史不对其他玩家公开;排行榜只展示公开入榜的胜利成绩。Phase 2 不做无限滚动完整历史、每日/每周曲线、好友对比或普通玩家可见的详细反作弊说明。
|
||||
|
||||
### 2.2.6 正式作品入口闭环
|
||||
|
||||
Phase 2 必须接入 Bark Battle 正式作品入口闭环,但不新增独立专区、活动页、挑战分享页、好友邀请或多人房间入口。入口范围包括:创作入口/玩法选择中出现 `bark-battle`,进入单页轻配置表单 + 预览卡片;作品详情页 CTA 点击“开始游玩”进入正式 runtime;广场/作品卡片可以展示、打开详情并开始游玩;我的作品/个人作品架能看到作者发布的 Bark Battle 作品;runtime 路由使用稳定作品 ID 并从后端发布态 config 拉取配置。
|
||||
|
||||
正式 run start 成功后必须写 `work_play_start`,其中 `scope_kind=work`、`scope_id=稳定作品 ID`,metadata 至少包含 `playType=bark-battle`、`workId`、`sourceRoute`、`userId`。内部试玩入口可以作为开发调试保留,但不得作为 Phase 2 正式入口。
|
||||
|
||||
### 2.2.7 轻配置编辑流程
|
||||
|
||||
Phase 2 的创作编辑形态是“单页轻配置表单 + 预览卡片”,不是多步骤向导、拖拽编辑器或完整规则编辑器。表单字段包含:标题(必填)、简介(选填)、主题/背景预设(必填枚举)、狗狗皮肤预设(必填枚举)、难度预设(必填,默认 `normal`)、排行榜开关(默认开启)。
|
||||
|
||||
交互流程:创作者从玩法选择进入后生成草稿;在同一页编辑轻配置并查看预览卡片;支持保存草稿和发布;发布成功后跳转作品详情;可从我的作品再次编辑草稿或基于已发布作品创建新版本。Phase 2 不做 AI 生成配置、多步骤 wizard、规则参数编辑、复杂封面编辑、runtime 内嵌预览或大段玩法说明文案。
|
||||
|
||||
### 2.2 后续增强路径
|
||||
|
||||
后续再考虑多人实时:
|
||||
第二阶段之后再考虑:
|
||||
|
||||
- Phase 2:排行榜、挑战分享、个人历史成绩、作品统计面板。
|
||||
- Phase 2.1:挑战分享、作品统计面板细化、排行榜体验优化。
|
||||
- Phase 3:异步影子对手 / ghost replay,但仍不保存原始音频,只保存低维派生曲线或聚合指标。
|
||||
- Phase 4:实时多人对战协议,需要独立同步模型、房间服务、延迟补偿、断线恢复与更严格反作弊;不应混入 MVP。
|
||||
- Phase 4:实时多人对战协议,需要独立同步模型、房间服务、延迟补偿、断线恢复与更严格反作弊;不应混入第二阶段平台作品闭环。
|
||||
|
||||
## 2.3 Phase 2 技术实施顺序
|
||||
|
||||
Phase 2 按“契约和领域规则先行,然后最小纵切,再扩展投影”的顺序实施,避免前端 mock 堆积、后端孤岛或排行榜 UI 先行。
|
||||
|
||||
1. 契约与领域规则:补 `shared-contracts` DTO、`module-bark-battle` 纯领域规则、`rulesetVersion` / `difficultyPreset` / score adjudication,并先写单测。
|
||||
2. SpacetimeDB 表与 reducer + api-server BFF:落草稿/config/发布态 config、runtime run start / finish、score record、leaderboard entry、work stats projection、personal summary projection、`migration.rs` 与绑定生成。
|
||||
3. 最小前端纵切:接创作入口、单页轻配置表单、发布到稳定 workId、作品详情 CTA、runtime 拉 config、start / finish 串通、结算展示 `serverResult`。
|
||||
4. 投影与列表体验:接排行榜、个人历史最近记录 + 最佳摘要、作品统计、我的作品/广场卡片适配。
|
||||
5. 收口验证:把 BDD 场景落到测试,执行编码检查、后端 `/healthz` + API smoke、前端人工验收路径,并更新 README/文档。
|
||||
|
||||
## 3. DDD 分层设计
|
||||
|
||||
@@ -90,7 +144,7 @@ frontend/runtime
|
||||
- 定义配置版本兼容规则。
|
||||
- 计算提交结果的派生分数区间与胜负判定是否自洽。
|
||||
- 计算 `ScoreSummary`、排行榜排序分数、统计指标。
|
||||
- 定义反作弊基础规则:时长范围、有效叫声次数上限、峰值范围、能量范围、提交窗口、run 状态机。
|
||||
- 定义反作弊基础规则:时长范围、有效声浪触发次数上限、峰值范围、能量范围、提交窗口、run 状态机。
|
||||
|
||||
不职责:
|
||||
|
||||
|
||||
@@ -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`、源图或中间预览图提交到仓库。
|
||||
|
||||
已执行的定向验证命令:
|
||||
|
||||
|
||||
@@ -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` 这类空端口而失败。
|
||||
|
||||
@@ -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,22 @@
|
||||
| AIRP | 是 | 否 | 保留入口,显示敬请期待 |
|
||||
| 视觉小说 | 是 | 否 | 保留入口,显示敬请期待,暂不允许创建视觉小说草稿 |
|
||||
| 智能创作 | 否 | 是 | 入口隐藏,既有 `creative-agent` 链路保留 |
|
||||
| 汪汪声浪 | 是 | 是 | `bark-battle` 正式轻创作入口,进入单页配置表单并发布后启动声控对战 runtime |
|
||||
| 宝贝识物 | 是 | 是 | 寓教于乐首关模板,必须由 `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`。
|
||||
|
||||
## 验收
|
||||
|
||||
|
||||
@@ -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` 空状态白屏。
|
||||
|
||||
@@ -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。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user