Files
Genarrative/.hermes/plans/2026-05-11_170028-bark-battle-three-phase-browser-ai-db-plan.md

710 lines
28 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# bark-battle 三阶段实施计划:浏览器原型 → AI 创作入口 → 数据库落地
> **For Hermes:** Use subagent-driven-development skill to implement this plan task-by-task.
**Goal:** 按“三阶段”推进 `bark-battle / 汪汪声浪大作战`:第一阶段先做纯浏览器可运行游戏原型并验证玩法跑通;第二阶段接入 Genarrative 创作入口,用 AI 生成可试玩内容;第三阶段再打通后端数据库、发布、成绩和作品闭环。
**Architecture:** 第一阶段只在前端 runtime 内闭环,优先落 `src/games/bark-battle/` 与直达路由,不依赖后端和 SpacetimeDB。第二阶段在已有创作入口、Agent flow controller、结果页和 runtime shell 上接入 `bark-battle`AI 只生成配置化草稿,不承接正式业务真相。第三阶段按 `server-rs + Axum + SpacetimeDB` DDD 分层落库,前端只展示后端投影和调用后端 API。
**Tech Stack:** React 19、TypeScript、Vite、Vitest、Testing Library第一阶段优先 DOM/Canvas 原型,可在验证玩法后再引入 Phaser 3后端阶段使用 `server-rs`、Axum、SpacetimeDB、shared-contracts。
---
## 0. 当前上下文 / 假设
- 现有需求与技术文档:
- `docs/prd/BARK_BATTLE_BDD_2026-05-11.md`
- `docs/technical/BARK_BATTLE_2D_RUNTIME_TECHNICAL_PLAN_2026-05-11.md`
- `docs/technical/BARK_BATTLE_BACKEND_DDD_TECHNICAL_PLAN_2026-05-11.md`
- 用户明确要求阶段顺序:
1. 第一阶段:先制作纯浏览器运行的游戏原型,需要测试游戏功能是否能跑通。
2. 第二阶段:打通创作入口,使用 AI 赋能游戏内容创作。
3. 第三阶段:最后打通数据库落地。
- 因此本计划调整原技术方案中的落地优先级:
- 第一阶段不新增后端表、不接发布、不接作品架。
- 第一阶段可以用 mock / local draft 配置与直达路由 `/bark-battle` 完成 playable prototype。
- 第一阶段若 Phaser 依赖尚未安装,优先用 React DOM + Canvas/CSS 2D 原型跑通功能;待核心规则验证后再决定是否引入 Phaser避免第一阶段被依赖安装和素材管线阻塞。
- 当前仓库 `package.json` 还没有 `phaser` 依赖;如实现者选择 Phaser需要单独评估依赖引入、包体和测试影响。
- 本计划只写计划,不直接实现代码。
## 1. 总体分阶段验收口径
### Phase 1纯浏览器游戏原型
目标:打开本地前端路由即可玩到一局 `bark-battle`,并通过自动测试确认核心规则跑通。
必须满足:
- 可从 `/bark-battle` 进入独立原型页面。
- 不登录、不请求后端、不依赖数据库。
- 支持开发 mock input点击/按键/按钮可模拟音量峰值;有真实麦克风时可走 Web Audio。
- 能完成:权限/开始 → 校准或 mock 准备 → 倒计时 → 30 秒 playing → 结算 → 再来一局。
- 低于阈值输入不计数;有效叫声计数;能量条向玩家或对手移动;结算胜/负/平。
- 移动端至少能看到能量条、倒计时、双方狗狗、主要按钮和结算。
### Phase 2AI 创作入口
目标:创作者能从创作中心选择 `bark-battle`,用 AI 生成玩法配置草稿,并进入结果页试玩。
必须满足:
- 后端入口配置中出现 `bark-battle`,按开关展示/可点击。
- 前端类型分流、SelectionStage、工作台、结果页、runtime 入口齐全。
- AI 生成内容仅限配置化草稿标题、主题、狗狗外观描述、背景风格、难度、局长、AI 对手参数、提示文案 key 等。
- 生成结果可在本地 runtime 中试玩。
- 未落库前可先用 session/local state 保存草稿,但要清楚标识为“未发布草稿”。
### Phase 3数据库落地与正式作品闭环
目标:`bark-battle` 草稿、发布态配置、runtime start/finish、成绩和作品级游玩埋点都进入后端 DDD / SpacetimeDB 链路。
必须满足:
- `shared-contracts``module-bark-battle``spacetime-module``spacetime-client``api-server` 分层清晰。
- 发布为稳定作品 IDruntime 从后端读取发布态 config。
- start 成功写 `work_play_start``scope_kind=work``scope_id=稳定作品 ID`、metadata 包含 `playType/workId/sourceRoute/userId`
- finish 只上传派生指标,不保存原始麦克风音频、波形或可还原语音内容。
- 作品架/广场/分享/排行榜如启用,均来自后端投影。
---
## 2. Phase 1纯浏览器运行游戏原型
### Task 1.1:补齐阶段边界文档
**Objective:** 在现有技术方案中明确“先浏览器原型,后 AI 创作,最后数据库”的落地顺序,避免实现时过早接后端。
**Files:**
- Modify: `docs/technical/BARK_BATTLE_2D_RUNTIME_TECHNICAL_PLAN_2026-05-11.md`
- Modify: `docs/prd/BARK_BATTLE_BDD_2026-05-11.md`
**Steps:**
1. 在 runtime 技术方案中新增“三阶段落地顺序”小节。
2. 明确 Phase 1 不接后端、不接数据库、不接创作入口事实源。
3. 在 BDD 中补充“浏览器原型 smoke”验收场景。
4. 运行:
```bash
npm run check:encoding -- docs/prd/BARK_BATTLE_BDD_2026-05-11.md docs/technical/BARK_BATTLE_2D_RUNTIME_TECHNICAL_PLAN_2026-05-11.md
git diff --check
```
**Expected:** 编码检查和 diff 空白检查通过。
### Task 1.2:建立 Phase 1 目录骨架和类型
**Objective:** 建立不依赖 React/DOM/Web Audio 的核心类型,后续所有测试和 UI 都围绕这些类型。
**Files:**
- Create: `src/games/bark-battle/domain/BarkBattleTypes.ts`
- Create: `src/games/bark-battle/application/BarkBattleConfig.ts`
**Key design:**
- `BarkBattlePhase = 'permission' | 'calibration' | 'countdown' | 'playing' | 'finished' | 'unavailable'`
- `MicrophoneFailureReason` 覆盖已有文档中的 9 类失败原因。
- `BarkBattleSnapshot` 包含 `phase/uiState/errorReason/statusMessageKey/remainingMs/energy/player/opponent/winner/result/lastEvents`。
- `BarkBattleConfig` 包含 `roundDurationMs/drawThreshold/minBarkGapMs/minBarkDurationMs/maxBarkDurationMs/balanceFactor/calibrationMaxWaitMs`。
**Tests:**
- 本任务可先不写运行时逻辑,但需要让 typecheck 能引用这些类型。
**Validation:**
```bash
npm run typecheck
npm run check:encoding -- src/games/bark-battle/domain/BarkBattleTypes.ts src/games/bark-battle/application/BarkBattleConfig.ts
```
### Task 1.3TDD 实现叫声检测 BarkDetector
**Objective:** 用纯函数/纯类把音频样本转换为有效叫声事件。
**Files:**
- Create: `src/games/bark-battle/domain/BarkDetector.ts`
- Create: `src/games/bark-battle/domain/__tests__/BarkDetector.test.ts`
**Test cases:**
1. 超过阈值、持续时长合规、间隔足够时计为一次有效叫声。
2. 持续噪音不在每个 tick 无限计数。
3. 低于阈值的背景噪音不计数。
4. `minBarkGapMs` 内连续峰值不重复计数。
5. 过短脉冲不计数;过长持续声削弱为单段输入。
**Validation:**
```bash
npm run test -- --run src/games/bark-battle/domain/__tests__/BarkDetector.test.ts
npm run typecheck
```
### Task 1.4TDD 实现能量条 EnergyTugOfWar
**Objective:** 验证玩家/对手推动力能稳定改变 `energy`,并 clamp 到 `-100..100`。
**Files:**
- Create: `src/games/bark-battle/domain/EnergyTugOfWar.ts`
- Create: `src/games/bark-battle/domain/__tests__/EnergyTugOfWar.test.ts`
**Test cases:**
1. 玩家 power 高于对手时 `energy` 增加。
2. 对手 power 高于玩家时 `energy` 减少。
3. energy 不超过 `100`。
4. energy 不低于 `-100`。
5. power 相等时变化不超过浮点误差。
**Validation:**
```bash
npm run test -- --run src/games/bark-battle/domain/__tests__/EnergyTugOfWar.test.ts
npm run typecheck
```
### Task 1.5TDD 实现单局状态机 BarkBattleSession
**Objective:** 跑通 permission/calibration/countdown/playing/finished/unavailable 状态流转和结算。
**Files:**
- Create: `src/games/bark-battle/domain/BarkBattleSession.ts`
- Create: `src/games/bark-battle/domain/BarkBattleScoring.ts`
- Create: `src/games/bark-battle/domain/OpponentStrategy.ts`
- Create: `src/games/bark-battle/domain/__tests__/BarkBattleSession.test.ts`
- Create: `src/games/bark-battle/domain/__tests__/BarkBattleScoring.test.ts`
**Test cases:**
1. 校准完成后进入 countdown。
2. countdown 结束后进入 playing。
3. playing 中 `remainingMs` 随 tick 递减。
4. `remainingMs <= 0` 后进入 finished。
5. `energy > drawThreshold` 判定玩家胜。
6. `energy < -drawThreshold` 判定对手胜。
7. `abs(energy) <= drawThreshold` 判定平局。
8. finished 后新输入不再改变本局计数和能量。
**Validation:**
```bash
npm run test -- --run src/games/bark-battle/domain/__tests__/BarkBattleSession.test.ts src/games/bark-battle/domain/__tests__/BarkBattleScoring.test.ts
npm run typecheck
```
### Task 1.6:实现 mock-first Application Controller
**Objective:** 不依赖真实麦克风,先用 mock audio sample 驱动完整 snapshot。
**Files:**
- Create: `src/games/bark-battle/application/BarkBattleController.ts`
- Create: `src/games/bark-battle/application/BarkBattleSnapshotStore.ts`
- Create: `src/games/bark-battle/application/__tests__/BarkBattleController.test.ts`
**Behavior:**
- `startWithMockInput()` 进入校准完成或直接 countdown。
- `submitMockSample(sample)` 更新玩家输入。
- `tick(deltaMs)` 推进对手、能量条、倒计时。
- `restart()` 重置状态。
- `failMicrophone(reason)` 进入 `phase: 'unavailable'`,并设置 `errorReason/statusMessageKey`。
**Test cases:**
1. mock start 后能进入 countdown/playing。
2. 提交 mock 峰值后 bark count 增加。
3. tick 后 energy 可变化。
4. finish 后生成 result。
5. `failMicrophone('permission-denied')` 不进入 playing。
**Validation:**
```bash
npm run test -- --run src/games/bark-battle/application/__tests__/BarkBattleController.test.ts
npm run typecheck
```
### Task 1.7:实现浏览器原型 UI Shell不接平台
**Objective:** 提供 `/bark-battle` 可访问的 playable prototype。
**Files:**
- Create: `src/BarkBattlePlaygroundApp.tsx`
- Create: `src/games/bark-battle/ui/BarkBattleRuntimeShell.tsx`
- Create: `src/games/bark-battle/ui/BarkBattleHud.tsx`
- Create: `src/games/bark-battle/ui/BarkBattleResultPanel.tsx`
- Create: `src/games/bark-battle/ui/BarkBattleHud.css`
- Modify: `src/routing/appRoutes.tsx`
**Behavior:**
- 新增路由匹配:`/bark-battle`。
- 首屏只有清爽开始面板,不常驻大段规则。
- 提供开发原型按钮:开始、模拟叫声、模拟对手增强、再来一局。
- playing 画面展示:顶部能量条、倒计时、玩家/对手狗狗、叫声次数、麦克风/mock 状态。
- 结算面板独立居中,不追加在当前面板下方。
**UI constraints:**
- 移动端优先。
- 正常 playing 阶段不在 playfield 常驻规则说明。
- 大动效不遮挡顶部能量条和倒计时。
**Validation:**
```bash
npm run test -- --run src/games/bark-battle/ui/**/*.test.tsx
npm run typecheck
npm run dev:web
# 手动 smoke: 访问 /bark-battle → 开始 → 模拟叫声 → energy 变化 → 结算 → 再来一局
```
### Task 1.8:实现 HUD 组件测试
**Objective:** 自动验证核心 UI 状态,不只依赖人工试玩。
**Files:**
- Create: `src/games/bark-battle/ui/__tests__/BarkBattleHud.test.tsx`
- Create: `src/games/bark-battle/ui/__tests__/BarkBattleResultPanel.test.tsx`
**Test cases:**
1. playing 阶段展示倒计时和能量条。
2. energy 正值时玩家侧占比更大。
3. energy 负值时对手侧占比更大。
4. permission-denied 展示重试授权入口。
5. unsupported 不展示开始声控按钮。
6. finished 展示胜负、叫声次数、再来一局。
**Validation:**
```bash
npm run test -- --run src/games/bark-battle/ui/__tests__/BarkBattleHud.test.tsx src/games/bark-battle/ui/__tests__/BarkBattleResultPanel.test.tsx
npm run typecheck
```
### Task 1.9:接入真实 Web Audio可晚于 mock 原型)
**Objective:** 在支持麦克风的浏览器中真实采样并驱动 controller同时保留 mock fallback 便于测试。
**Files:**
- Create: `src/games/bark-battle/infrastructure/BrowserMicrophoneInput.ts`
- Create: `src/games/bark-battle/infrastructure/AudioAnalyserSampler.ts`
- Create: `src/games/bark-battle/infrastructure/MicrophonePermission.ts`
- Create: `src/games/bark-battle/infrastructure/__tests__/BrowserMicrophoneInput.test.ts`
- Create: `src/games/bark-battle/infrastructure/__tests__/AudioAnalyserSampler.test.ts`
**Behavior:**
- 用户点击开始后才请求麦克风。
- 用户手势后创建/resume `AudioContext`。
- 输出归一化 `BarkAudioSample`。
- 捕获并映射unsupported、permission-denied、non-secure-context、not-found、not-readable、audio-context-blocked、unknown。
- stop/restart/page unload 时停止 tracks。
**Validation:**
```bash
npm run test -- --run src/games/bark-battle/infrastructure/__tests__/BrowserMicrophoneInput.test.ts src/games/bark-battle/infrastructure/__tests__/AudioAnalyserSampler.test.ts
npm run typecheck
npm run dev:web
# 手动 smoke: 真实麦克风授权 → 校准 → 发声 → 结算
```
### Task 1.10Phase 1 收口验证
**Objective:** 确认“纯浏览器原型”已经可以交给产品/测试试玩。
**Commands:**
```bash
npm run test -- --run src/games/bark-battle/domain/**/*.test.ts src/games/bark-battle/application/**/*.test.ts src/games/bark-battle/infrastructure/**/*.test.ts src/games/bark-battle/ui/**/*.test.tsx
npm run typecheck
npm run lint:eslint
npm run check:encoding
npm run dev:web
```
**Manual smoke checklist:**
- [ ] `/bark-battle` 能打开。
- [ ] mock 模式可完整完成一局。
- [ ] 真实麦克风模式可授权、校准、发声、结算。
- [ ] 拒绝权限后不会进入 playing。
- [ ] 移动端窄屏能看到核心信息并能点击主要按钮。
- [ ] 再来一局不会继承上一局 energy/barkCount/result。
---
## 3. Phase 2打通创作入口用 AI 赋能内容创作
### Task 2.1:定义 `bark-battle` 草稿契约(前端本地版)
**Objective:** 在接后端前,先定义 AI 可生成的 runtime draft shape。
**Files:**
- Create: `packages/shared/src/contracts/barkBattle.ts`(临时前端共享类型,后端阶段再对齐 Rust shared-contracts
- Create: `src/services/bark-battle-creation/barkBattleDraftDefaults.ts`
- Create: `src/services/bark-battle-creation/barkBattleDraftValidation.ts`
**Draft fields:**
- `title`
- `description`
- `themePrompt`
- `playerDogName`
- `opponentDogName`
- `backgroundStyle`
- `difficulty`
- `roundDurationMs`
- `drawThreshold`
- `opponentConfig`
- `audioSensitivityPreset`
- `visualStyle`
**Validation:**
```bash
npm run test -- --run src/services/bark-battle-creation/**/*.test.ts
npm run typecheck
```
### Task 2.2:新增创作入口配置
**Objective:** 让 `bark-battle` 出现在创作中心入口中,但可通过后端入口配置开关控制。
**Files likely to change:**
- `server-rs/crates/spacetime-module/src/runtime/creation_entry_config.rs`
- `server-rs/crates/module-runtime/src/domain.rs`
- `server-rs/crates/module-runtime/src/application.rs`
- `server-rs/crates/shared-contracts/src/creation_entry_config.rs`
- `src/components/platform-entry/platformEntryCreationTypes.ts`
- `src/components/platform-entry/platformEntryCreationTypes.test.ts`
**Plan:**
1. 在入口 seed 中新增 `bark-battle`,首轮可设:`visible: true`、`open: true`(若需要灰度则 `open: false`)。
2. 前端展示派生只消费 API 返回,不恢复旧静态入口事实源。
3. 更新排序和锁定态测试。
**Validation:**
```bash
npm run test -- src/components/platform-entry/platformEntryCreationTypes.test.ts
npm run typecheck
cd server-rs && cargo check -p api-server -p spacetime-module --no-default-features
```
### Task 2.3:扩展 SelectionStage 与流程分流
**Objective:** 点击 `bark-battle` 入口后进入对应创作工作台。
**Files likely to change:**
- `src/components/platform-entry/platformEntryTypes.ts`
- `src/components/platform-entry/PlatformEntryFlowShellImpl.tsx`
- `src/components/platform-entry/usePlatformCreationAgentFlowController.ts`(如复用通用 agent flow
**Stages:**
- `bark-battle-agent-workspace`
- `bark-battle-generating`(可选)
- `bark-battle-result`
- `bark-battle-runtime`
**Validation:**
```bash
npm run test -- src/components/platform-entry/**/*.test.tsx src/components/platform-entry/**/*.test.ts
npm run typecheck
```
### Task 2.4:实现 AI 创作工作台
**Objective:** 用对话式或表单式输入生成 `BarkBattleDraft`。
**Files:**
- Create: `src/components/bark-battle-creation/BarkBattleAgentWorkspace.tsx`
- Create: `src/services/bark-battle-creation/barkBattleCreationClient.ts`
- Create: `src/services/bark-battle-creation/barkBattlePromptBuilder.ts`
- Create: `src/services/bark-battle-creation/__tests__/barkBattlePromptBuilder.test.ts`
**Behavior:**
- 用户输入一句主题,例如“柴犬在赛博公园比谁叫得响”。
- AI 返回结构化草稿。
- 前端校验并填默认值,不让非法 roundDuration/difficulty 进入 runtime。
- 错误时保留用户输入和已生成草稿。
**Validation:**
```bash
npm run test -- --run src/services/bark-battle-creation/**/*.test.ts
npm run typecheck
```
### Task 2.5:实现结果页与试玩入口
**Objective:** AI 草稿生成后可查看、返回编辑、进入 Phase 1 runtime 试玩。
**Files:**
- Create: `src/components/bark-battle-result/BarkBattleResultView.tsx`
- Create: `src/components/bark-battle-result/BarkBattleResultView.test.tsx`
- Modify: `src/games/bark-battle/ui/BarkBattleRuntimeShell.tsx`(允许传入 draft config
**Behavior:**
- 展示标题、主题、狗狗名、背景风格、难度、局长。
- 提供“返回编辑”“试玩”按钮。
- 暂不展示发布按钮,或发布按钮显示为后端阶段能力。
**Validation:**
```bash
npm run test -- --run src/components/bark-battle-result/BarkBattleResultView.test.tsx
npm run typecheck
npm run dev:web
# 手动 smoke: 创作入口 → AI 草稿 → 结果页 → 试玩 → 返回编辑
```
### Task 2.6Phase 2 收口验证
**Commands:**
```bash
npm run test -- src/components/platform-entry/platformEntryCreationTypes.test.ts src/components/bark-battle-result/BarkBattleResultView.test.tsx src/services/bark-battle-creation/**/*.test.ts src/games/bark-battle/**/*.test.ts src/games/bark-battle/**/*.test.tsx
npm run typecheck
npm run lint:eslint
npm run check:encoding
```
**Manual smoke checklist:**
- [ ] 创作中心展示 `bark-battle`。
- [ ] 点击入口进入工作台。
- [ ] AI 可生成草稿。
- [ ] 草稿结果页可展示并返回编辑。
- [ ] 试玩使用草稿配置影响 runtime 表现。
- [ ] 未接数据库前不会假装发布成功。
---
## 4. Phase 3数据库落地与正式作品闭环
### Task 3.1:补齐 shared contracts
**Objective:** 前后端共享 bark-battle DTO避免前端手写正式契约漂移。
**Files likely to change:**
- `server-rs/crates/shared-contracts/src/bark_battle.rs`
- `server-rs/crates/shared-contracts/src/lib.rs`
- `packages/shared/src/contracts/barkBattle.ts`
**DTO:**
- `BarkBattleDraft`
- `BarkBattlePublishedConfig`
- `CreateBarkBattleSessionRequest/Response`
- `BarkBattleRuntimeStartRequest/Response`
- `BarkBattleRuntimeFinishRequest/Response`
- `BarkBattleRunResult`
- `BarkBattleScoreSummary`
- `BarkBattleLeaderboardEntry`
**Validation:**
```bash
npm run typecheck
cd server-rs && cargo check -p shared-contracts --no-default-features
```
### Task 3.2:新增 `module-bark-battle` 纯领域模块
**Objective:** 后端正式分数、配置校验、提交合法性不写在 api-server handler 里。
**Files:**
- Create: `server-rs/crates/module-bark-battle/`
- Modify: `server-rs/Cargo.toml`
**Responsibilities:**
- 配置合法性校验。
- run start/finish 状态约束。
- 派生指标范围校验。
- 分数与排行榜排序分计算。
- 不接 Axum、不接 SpacetimeDB、不接 HTTP。
**Validation:**
```bash
cd server-rs && cargo test -p module-bark-battle --no-default-features
cd server-rs && cargo check -p module-bark-battle --no-default-features
```
### Task 3.3SpacetimeDB 表、reducer、migration
**Objective:** 保存草稿、发布态配置、run、result、leaderboard 投影。
**Files likely to change:**
- `server-rs/crates/spacetime-module/src/runtime/bark_battle.rs`(或按现有模块目录命名)
- `server-rs/crates/spacetime-module/src/migration.rs`
- `server-rs/crates/spacetime-module/src/lib.rs`
- 生成绑定目录(通过命令生成,不手改生成物)
**Tables draft:**
- `bark_battle_draft`
- `bark_battle_published_config`
- `bark_battle_run`
- `bark_battle_run_result`
- `bark_battle_leaderboard_entry`
**Reducers/procedures:**
- `create_bark_battle_draft`
- `publish_bark_battle_config`
- `start_bark_battle_run`
- `finish_bark_battle_run`
- `list_bark_battle_leaderboard`
**Validation:**
```bash
npm run spacetime:generate
cd server-rs && cargo check -p spacetime-module --no-default-features
npm run check:server-rs-ddd
```
### Task 3.4spacetime-client facade
**Objective:** api-server 通过 facade 调用 SpacetimeDB不直接散落 reducer 细节。
**Files likely to change:**
- `server-rs/crates/spacetime-client/src/runtime.rs`
- `server-rs/crates/spacetime-client/src/mapper.rs`
- `server-rs/crates/spacetime-client/src/lib.rs`
**Validation:**
```bash
cd server-rs && cargo check -p spacetime-client --no-default-features
```
### Task 3.5api-server BFF 路由
**Objective:** 提供创作、发布态 runtime start/finish、leaderboard API。
**Files likely to change:**
- `server-rs/crates/api-server/src/bark_battle.rs`
- `server-rs/crates/api-server/src/main.rs` 或路由注册文件
**Routes draft:**
- `POST /api/bark-battle/sessions`
- `GET /api/bark-battle/sessions/:sessionId`
- `POST /api/bark-battle/runtime/start`
- `POST /api/bark-battle/runtime/finish`
- `GET /api/bark-battle/works/:workId/runtime-config`
- `GET /api/bark-battle/works/:workId/leaderboard`
**Tracking:**
- runtime start 成功后主动写 `work_play_start`。
- `scope_kind=work`。
- `scope_id=稳定作品 ID`。
- metadata 包含 `playType=bark-battle`、`workId`、`sourceRoute`、`userId`。
**Validation:**
```bash
npm run api-server
# 另一个终端检查 /healthz并执行对应 API smoke
cd server-rs && cargo check -p api-server --no-default-features
```
### Task 3.6:前端正式 client 与 runtime 切换
**Objective:** runtime 从本地草稿模式升级为可读取后端发布态 config并提交正式派生结果。
**Files likely to change:**
- Create: `src/services/bark-battle-runtime/barkBattleRuntimeClient.ts`
- Create: `src/services/bark-battle-works/barkBattleWorksClient.ts`
- Modify: `src/games/bark-battle/ui/BarkBattleRuntimeShell.tsx`
- Modify: `src/components/bark-battle-result/BarkBattleResultView.tsx`
- Modify: `src/components/custom-world-home/creationWorkShelf.ts`
- Modify: `src/components/custom-world-home/CustomWorldCreationHub.tsx`
- Modify: `src/services/publicWorkCode.ts`
**Behavior:**
- 本地 preview 仍可使用 draft config。
- 正式作品 runtime 必须先调用 start API拿 run token/session。
- finish 只提交派生 metrics。
- 发布后刷新作品架/广场。
**Validation:**
```bash
npm run test -- src/services/bark-battle-runtime/**/*.test.ts src/games/bark-battle/**/*.test.ts src/games/bark-battle/**/*.test.tsx
npm run typecheck
npm run check:encoding
```
### Task 3.7Phase 3 收口验证
**Commands:**
```bash
npm run test -- src/games/bark-battle/**/*.test.ts src/games/bark-battle/**/*.test.tsx src/services/bark-battle-runtime/**/*.test.ts src/services/bark-battle-creation/**/*.test.ts
npm run typecheck
npm run lint:eslint
npm run check:encoding
npm run check:server-rs-ddd
cd server-rs && cargo test -p module-bark-battle --no-default-features
cd server-rs && cargo check -p api-server -p spacetime-module -p spacetime-client -p shared-contracts --no-default-features
npm run api-server
```
**Manual smoke checklist:**
- [ ] 创作者生成并发布 bark-battle 作品。
- [ ] 玩家从作品页进入 runtime。
- [ ] start API 成功并写 `work_play_start`。
- [ ] 浏览器本地完成一局。
- [ ] finish API 只上传派生指标。
- [ ] 成绩/排行榜/作品架刷新来自后端投影。
- [ ] 拒绝麦克风权限时不会创建非法 finished result。
---
## 5. 文件清单总览
### Phase 1 likely files
- `src/routing/appRoutes.tsx`
- `src/BarkBattlePlaygroundApp.tsx`
- `src/games/bark-battle/domain/BarkBattleTypes.ts`
- `src/games/bark-battle/domain/BarkDetector.ts`
- `src/games/bark-battle/domain/EnergyTugOfWar.ts`
- `src/games/bark-battle/domain/BarkBattleSession.ts`
- `src/games/bark-battle/domain/BarkBattleScoring.ts`
- `src/games/bark-battle/domain/OpponentStrategy.ts`
- `src/games/bark-battle/application/BarkBattleConfig.ts`
- `src/games/bark-battle/application/BarkBattleController.ts`
- `src/games/bark-battle/application/BarkBattleSnapshotStore.ts`
- `src/games/bark-battle/infrastructure/BrowserMicrophoneInput.ts`
- `src/games/bark-battle/infrastructure/AudioAnalyserSampler.ts`
- `src/games/bark-battle/infrastructure/MicrophonePermission.ts`
- `src/games/bark-battle/ui/BarkBattleRuntimeShell.tsx`
- `src/games/bark-battle/ui/BarkBattleHud.tsx`
- `src/games/bark-battle/ui/BarkBattleResultPanel.tsx`
- `src/games/bark-battle/ui/BarkBattleHud.css`
### Phase 2 likely files
- `packages/shared/src/contracts/barkBattle.ts`
- `src/components/platform-entry/platformEntryTypes.ts`
- `src/components/platform-entry/PlatformEntryFlowShellImpl.tsx`
- `src/components/platform-entry/platformEntryCreationTypes.ts`
- `src/components/bark-battle-creation/BarkBattleAgentWorkspace.tsx`
- `src/components/bark-battle-result/BarkBattleResultView.tsx`
- `src/services/bark-battle-creation/*`
### Phase 3 likely files
- `server-rs/crates/shared-contracts/src/bark_battle.rs`
- `server-rs/crates/module-bark-battle/*`
- `server-rs/crates/spacetime-module/src/runtime/bark_battle.rs`
- `server-rs/crates/spacetime-module/src/migration.rs`
- `server-rs/crates/spacetime-client/src/runtime.rs`
- `server-rs/crates/spacetime-client/src/mapper.rs`
- `server-rs/crates/api-server/src/bark_battle.rs`
- `src/services/bark-battle-runtime/*`
- `src/services/bark-battle-works/*`
- `src/components/custom-world-home/creationWorkShelf.ts`
- `src/services/publicWorkCode.ts`
---
## 6. 风险、取舍与开放问题
### 风险
1. **麦克风权限和移动端 AudioContext 差异大。** 需要 mock input 保底,否则自动化和本地开发会被真实设备阻塞。
2. **第一阶段过早引入 Phaser 可能拖慢验证。** 当前仓库没有 `phaser` 依赖;建议先用 DOM/Canvas 跑通玩法,再决定是否引入 Phaser。
3. **AI 草稿和正式发布配置容易漂移。** Phase 2 临时 TS 类型必须在 Phase 3 与 Rust shared-contracts 对齐。
4. **不能保存原始音频。** 后端阶段只能保存派生指标,任何音频片段、波形、频谱明细都不应落库。
5. **入口配置事实源在后端/SpacetimeDB。** Phase 2 接入口时不要恢复旧前端静态入口配置。
### 取舍
- Phase 1 先把“游戏是否好玩、功能是否跑通”作为第一目标,不追求正式作品闭环。
- Phase 2 让 AI 生成内容配置,而不是让 AI 直接生成任意代码或不受控规则。
- Phase 3 再把正式业务真相交给后端,避免前端 runtime 先背上发布、成绩、排行榜的复杂度。
### 开放问题
1. Phase 1 是否必须使用 Phaser如果只是验证玩法可先使用 DOM/CSS/Canvas 原型,后续再替换 renderer。
2. `bark-battle` 的正式中文名是否固定为“汪汪声浪大作战”?如果名称要改,需先统一文档、入口配置和分享标题。
3. AI 创作阶段是否需要生成图片/狗狗视觉资产,还是只生成风格描述和使用占位素材?
4. 是否需要排行榜作为 Phase 3 必选,还是作为数据库落地后的增强项?
5. 真实麦克风 smoke 需要哪些目标设备Chrome 桌面、Android Chrome、iOS Safari 是否都纳入首批验收?
---
## 7. 建议执行方式
1. 先按 Phase 1 执行,且每个 domain/application task 坚持 TDD先失败测试再实现。
2. Phase 1 合并前不要接数据库,不要新增后端表,不要把入口配置切到 open。
3. Phase 1 验证通过后,让产品/团队试玩 `/bark-battle`,确认玩法数值和 UI 方向。
4. 再进入 Phase 2把 AI 创作工作台接到同一个 runtime draft config。
5. 最后进入 Phase 3按后端 DDD 文档做数据库、发布、成绩和追踪闭环。