feat: add bark battle browser prototype

This commit is contained in:
2026-05-11 18:01:55 +08:00
parent bf72c2e48d
commit 2b046656dc
32 changed files with 2244 additions and 18 deletions

View File

@@ -0,0 +1,709 @@
# 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 文档做数据库、发布、成绩和追踪闭环。