19 KiB
Bark Battle Phase 2 Platform Work Loop Implementation Plan
For Hermes: Use subagent-driven-development skill to implement this plan task-by-task.
Goal: 将 bark-battle 从内部试玩 demo 升级为 Genarrative 正式 play type,打通轻创作配置、发布态作品、正式 runtime、run start / finish、后端裁决、个人历史、作品统计和最小排行榜闭环。
Architecture: 先冻结 shared contracts 与 module-bark-battle 纯领域规则,再落 SpacetimeDB 表/reducer、spacetime-client facade 和 api-server BFF,随后接前端最小纵切,最后补排行榜/个人历史/作品统计投影体验。前端只承接表现、交互和临时 UI 状态,正式业务真相由后端裁决。
Tech Stack: React + TypeScript + Vite, server-rs + Axum, SpacetimeDB Rust module, shared-contracts, Vitest, Cargo tests, npm scripts.
0. 已确认决策
- “有效叫声”统一为 有效声浪触发:当前采样响度达到有效阈值且满足
minBarkGapMs冷却即触发;不再要求minBarkDurationMs/maxBarkDurationMs,也不等待响度回落。 - Phase 2 范围是 Bark Battle 平台作品闭环,不是单纯玩法表现深化。
- 作品形态是 轻创作配置作品:标题、描述、主题/背景预设、狗狗皮肤预设、难度预设、排行榜开关。
- 难度预设只影响 AI 对手行为;不影响有效阈值、冷却、时长、分数公式或反作弊阈值。
- 排行榜按
workId + difficultyPreset + rulesetVersion分榜。 - 后端裁决正式单局结果;前端只提交派生指标,
clientResult只用于 debug/对账。 - 排行榜只收录
serverResult = player_win且未被反作弊拒绝的单局结果,排序以finalEnergy优先。 - 作品统计使用最小后端投影:start、finish、win/draw/loss、flagged、leaderboard、best/avg energy。
- 个人历史成绩 = 最近记录列表 + 个人最佳摘要;仅本人可见。
- 正式入口闭环覆盖创作入口、作品详情 CTA、广场/作品卡片、我的作品、稳定作品 ID runtime 路由和
work_play_start。 - 创作编辑形态是单页轻配置表单 + 预览卡片。
- 实施顺序固定为:契约与领域规则 → SpacetimeDB 表/reducer 与 api-server BFF → 最小前端纵切 → 投影与列表体验 → 收口验证。
1. 必读文档与约束
实施前先读:
AGENTS.mdCONTEXT.mddocs/prd/BARK_BATTLE_BDD_2026-05-11.mddocs/technical/BARK_BATTLE_BACKEND_DDD_TECHNICAL_PLAN_2026-05-11.mddocs/technical/BARK_BATTLE_2D_RUNTIME_TECHNICAL_PLAN_2026-05-11.mddocs/technical/SPACETIMEDB_SCHEMA_CHANGE_CONSTRAINTS.mddocs/technical/SERVER_RS_DDD_FULL_REFACTOR_2026-04-28.md.codex/skills/spacetimedb-cli/SKILL.md.codex/skills/spacetimedb-rust/SKILL.md.codex/skills/spacetimedb-concepts/SKILL.md.codex/skills/spacetimedb-typescript/SKILL.md
关键约束:
- 后端路线固定
server-rs + Axum + SpacetimeDB。 - 领域规则进
module-bark-battle,SpacetimeDB 表和事务编排进spacetime-module。 - HTTP/SSE/BFF 留在
api-server。 - 前后端 DTO 留在
shared-contracts。 - 数据库表结构更改必须同步
migration.rs和生成绑定。 - 人工命令/文档示例禁止继续使用
spacetime --root-dir。 - 修改中文文件后必须跑
npm run check:encoding。
2. 阶段一:契约与领域规则
Task 1.1: 新增 Rust shared-contracts 模块
Objective: 定义 Bark Battle Phase 2 的 Rust DTO 边界。
Files:
- Create:
server-rs/crates/shared-contracts/src/bark_battle.rs - Modify:
server-rs/crates/shared-contracts/src/lib.rs - Test:
server-rs/crates/shared-contracts/src/bark_battle.rs
Steps:
- 新增枚举:
BarkBattleDifficultyPreset { Easy, Normal, Hard }、BarkBattleServerResult { PlayerWin, OpponentWin, Draw }、BarkBattleFinishStatus { Accepted, AcceptedWithFlags, Rejected }。 - 新增配置 DTO:
BarkBattleDraftConfig、BarkBattlePublishedConfig、BarkBattleRuntimeConfig。 - 新增 run DTO:
BarkBattleRunStartRequest/Response、BarkBattleRunFinishRequest/Response。 - 新增派生指标 DTO:
BarkBattleDerivedMetrics,字段包含trigger_count、max_volume、average_volume、final_energy、combo_max。 - 新增排行榜/历史/统计 DTO:
BarkBattleLeaderboardEntry、BarkBattlePersonalHistoryItem、BarkBattlePersonalBestSummary、BarkBattleWorkStats。 - 在
lib.rs导出pub mod bark_battle;。
Verification:
cargo test -p shared-contracts bark_battle
Expected: contracts tests pass.
Task 1.2: 新增 TypeScript shared contracts mirror
Objective: 让前端获得与 Rust DTO 对齐的类型。
Files:
- Create:
packages/shared/src/contracts/barkBattle.ts - Modify:
packages/shared/src/contracts/index.ts - Test:
packages/shared/src/contracts/barkBattle.test.ts
Steps:
- 定义
BarkBattleDifficultyPreset = 'easy' | 'normal' | 'hard'。 - 定义
BarkBattleServerResult = 'player_win' | 'opponent_win' | 'draw'。 - 定义 draft / published / runtime config 类型。
- 定义 start / finish request response 类型。
- 定义 leaderboard / personal history / work stats 类型。
- 写最小序列化/fixture 测试,确保字段命名采用前端约定 camelCase,并在 API client 层做必要映射。
Verification:
npm test -- --run packages/shared/src/contracts/barkBattle.test.ts
npx tsc -p tsconfig.typecheck-guardrails.json --noEmit --pretty false
Task 1.3: 新建 module-bark-battle crate
Objective: 将正式裁决规则放入纯领域 crate。
Files:
- Create:
server-rs/crates/module-bark-battle/Cargo.toml - Create:
server-rs/crates/module-bark-battle/src/lib.rs - Create:
server-rs/crates/module-bark-battle/src/domain.rs - Create:
server-rs/crates/module-bark-battle/src/scoring.rs - Modify:
server-rs/Cargo.toml
Steps:
- 在 workspace 中注册
module-bark-battle。 - 定义
RulesetVersion,首版固定如bark-battle-ruleset-v1。 - 定义
BarkBattleRuleset,包含标准局时长 30s、min_bark_gap_ms、合法音量/能量/连击范围、duration tolerance。 - 实现
validate_finish_metrics()。 - 实现
adjudicate_result():以后端final_energy和 draw threshold 生成serverResult。 - 实现
compute_leaderboard_score():只允许胜利局入榜,排序因子为finalEnergy、triggerCount、maxVolume、duration 接近度、finishedAt。
Verification:
cargo test -p module-bark-battle
Task 1.4: 领域规则单测覆盖作弊边界
Objective: 防止前端伪造 finish 直接刷榜。
Files:
- Modify:
server-rs/crates/module-bark-battle/src/scoring.rs
Test cases:
- 28s-35s 合法窗口内可接受。
- 1s / 300s 应 rejected 或 flagged。
triggerCount > durationMs / minBarkGapMs + tolerance应 flagged。finalEnergy越界应 rejected。- 平/负不生成 leaderboard entry。
- easy/normal/hard 不改变阈值、冷却、分数公式,只改变 AI preset key。
Verification:
cargo test -p module-bark-battle -- --nocapture
3. 阶段二:SpacetimeDB 表/reducer 与 api-server BFF
Task 2.1: 设计 SpacetimeDB 表目录
Objective: 新增 Bark Battle 表并与 migration 对齐。
Files:
- Create:
server-rs/crates/spacetime-module/src/bark_battle/mod.rs - Create:
server-rs/crates/spacetime-module/src/bark_battle/types.rs - Create:
server-rs/crates/spacetime-module/src/bark_battle/tables.rs - Modify:
server-rs/crates/spacetime-module/src/lib.rs - Modify:
server-rs/crates/spacetime-module/src/migration.rs
Tables:
bark_battle_draft_configbark_battle_published_configbark_battle_runtime_runbark_battle_score_recordbark_battle_leaderboard_entrybark_battle_work_stats_projectionbark_battle_personal_best_projection
Pitfalls:
- 表结构不要 derive
SpacetimeType。 - reducer 使用
&ReducerContext。 - 授权身份来自
ctx.sender()。 - 需要公开订阅的表才加
public。
Verification:
cargo test -p spacetime-module
Task 2.2: 实现草稿/发布 reducer
Objective: 支持轻配置草稿保存和发布态 config 固化。
Reducers:
create_bark_battle_draftupdate_bark_battle_draft_configpublish_bark_battle_workget_bark_battle_runtime_config如仓库约定使用 reducer/procedure 查询则按现有 pattern 实现。
Rules:
- 草稿配置只允许标题、描述、主题/背景预设、狗狗皮肤预设、难度预设、排行榜开关。
- 发布生成稳定作品 ID / config version。
- 发布态 config 包含
rulesetVersion。
Verification:
cargo test -p spacetime-module bark_battle
Task 2.3: 实现 run start / finish reducer
Objective: 打通正式运行态后端事务。
Reducers:
start_bark_battle_runfinish_bark_battle_runget_bark_battle_run
Rules:
- start 创建
run_id和一次性run_token。 - start 记录 work/config/ruleset/difficulty 快照。
- finish 必须校验 run token、未 finish、work/config/ruleset/difficulty 一致。
- finish 调用
module-bark-battle裁决结果。 - accepted 写 score record。
serverResult = player_win且排行榜开启且未 rejected 时写 leaderboard entry。- accepted / accepted_with_flags 更新 work stats 和 personal best projection。
Verification:
cargo test -p spacetime-module bark_battle_run
Task 2.4: 更新 migration 与生成绑定
Objective: 让 SpacetimeDB 表结构变更可发布。
Files:
- Modify:
server-rs/crates/spacetime-module/src/migration.rs - Generated:
server-rs/crates/spacetime-client/src/module_bindings/*bark*
Commands: 按仓库现有脚本优先;不要手改 generated bindings。
npm run spacetime:build
npm run spacetime:generate
若脚本名不同,先查 package.json 和 server-rs README。
Task 2.5: 实现 spacetime-client facade
Objective: api-server 不直接操作 generated bindings。
Files:
- Create:
server-rs/crates/spacetime-client/src/bark_battle.rs - Modify:
server-rs/crates/spacetime-client/src/lib.rs
Methods:
create_bark_battle_draftsave_bark_battle_draft_configpublish_bark_battle_workget_bark_battle_runtime_configstart_bark_battle_runfinish_bark_battle_runlist_bark_battle_leaderboardlist_my_bark_battle_historyget_my_bark_battle_best_summaryget_bark_battle_work_stats
Verification:
cargo test -p spacetime-client bark_battle
Task 2.6: 实现 api-server BFF 路由
Objective: 暴露前端需要的 HTTP API。
Files:
- Create:
server-rs/crates/api-server/src/bark_battle.rs - Modify:
server-rs/crates/api-server/src/app.rs
Routes:
POST /api/bark-battle/draftsPATCH /api/bark-battle/drafts/:draftIdPOST /api/bark-battle/drafts/:draftId/publishGET /api/bark-battle/works/:workId/runtime-configPOST /api/bark-battle/runs/startPOST /api/bark-battle/runs/:runId/finishGET /api/bark-battle/works/:workId/leaderboardGET /api/bark-battle/me/historyGET /api/bark-battle/me/best-summaryGET /api/bark-battle/works/:workId/stats
Verification:
cargo test -p api-server bark_battle
npm run api-server
curl -f http://127.0.0.1:<api-port>/healthz
4. 阶段三:最小前端纵切
Task 3.1: 新增前端 service client
Files:
- Create:
src/services/bark-battle/barkBattleClient.ts - Test:
src/services/bark-battle/barkBattleClient.test.ts
Methods: 与 BFF routes 一一对应。
Verification:
npm test -- --run src/services/bark-battle/barkBattleClient.test.ts
Task 3.2: 接入创作入口与 SelectionStage
Files:
- Modify:
src/config/newWorkEntryConfig.ts - Modify:
src/components/platform-entry/platformEntryCreationTypes.ts - Modify:
src/components/platform-entry/platformEntryTypes.ts - Modify:
src/components/platform-entry/PlatformEntryFlowShellImpl.tsx
Rules:
- 新增
bark-battleplay type。 - 入口打开单页轻配置表单,不走复杂 agent workspace。
- 移动端入口布局不能溢出。
Task 3.3: 实现单页轻配置表单 + 预览卡片
Files:
- Create:
src/components/bark-battle-creation/BarkBattleConfigEditor.tsx - Create:
src/components/bark-battle-creation/BarkBattlePreviewCard.tsx - Test:
src/components/bark-battle-creation/BarkBattleConfigEditor.test.tsx
UI fields:
- 标题必填
- 简介选填
- 主题/背景预设
- 狗狗皮肤预设
- 难度预设,默认
normal - 排行榜开关,默认开启
UI constraints:
- 不堆大段玩法说明。
- 按现有游戏 UI 风格设计。
- 移动端优先。
Task 3.4: 发布后进入作品详情
Files:
- Modify:
src/components/platform-entry/PlatformEntryFlowShellImpl.tsx - Modify:
src/components/platform-entry/PlatformWorkDetailView.tsx - Modify:
src/components/custom-world-home/CustomWorldCreationHub.tsx - Modify:
src/components/custom-world-home/creationWorkShelf.ts
Rules:
- 发布成功刷新 works/gallery/shelf。
- 跳作品详情。
- 详情 CTA 可以进入正式 runtime。
Task 3.5: runtime 拉发布态 config 并 start / finish
Files:
- Modify:
src/games/bark-battle/* - Modify:
src/games/bark-battle/ui/BarkBattleRuntimeShell.tsx - Create/Modify:
src/components/bark-battle-runtime/BarkBattleRuntimeRoute.tsx如需要
Rules:
- runtime 通过稳定
workId拉BarkBattleRuntimeConfig。 - 开始正式局时调用 start run。
- 结束时提交 finish 派生指标。
- 结算展示
serverResult、scoreSummary、antiCheatFlags、leaderboard entry。 - 麦克风原始音频不上传。
Verification:
npm test -- --run src/games/bark-battle/domain/__tests__/BarkDetector.test.ts src/games/bark-battle/application/__tests__/BarkBattleController.test.ts src/games/bark-battle/ui/__tests__/BarkBattleRuntimeShell.test.tsx
5. 阶段四:投影与列表体验
Task 4.1: 排行榜 UI
Files:
- Create:
src/components/bark-battle-leaderboard/BarkBattleLeaderboardPanel.tsx - Test:
src/components/bark-battle-leaderboard/BarkBattleLeaderboardPanel.test.tsx - Modify:
src/components/platform-entry/PlatformWorkDetailView.tsx
Rules:
- 查询维度
workId + difficultyPreset + rulesetVersion。 - 只展示胜利入榜成绩。
- 不展示平/负/flagged 历史。
Task 4.2: 个人历史最近记录 + 最佳摘要 UI
Files:
- Create:
src/components/bark-battle-history/BarkBattlePersonalHistoryPanel.tsx - Test:
src/components/bark-battle-history/BarkBattlePersonalHistoryPanel.test.tsx
Rules:
- 默认最近 20 条。
- 仅本人可见。
- 可按 workId / difficultyPreset 过滤。
- flagged 只做轻提示,不展示详细反作弊原因。
Task 4.3: 作品统计展示
Files:
- Create:
src/components/bark-battle-stats/BarkBattleWorkStatsPanel.tsx - Test:
src/components/bark-battle-stats/BarkBattleWorkStatsPanel.test.tsx
Fields:
playStartCountfinishCountwinCountdrawCountlossCountflaggedCountleaderboardEntryCountbestLeaderboardScorebestFinalEnergyaverageFinalEnergyupdatedAt
Task 4.4: 广场卡片/我的作品适配
Files:
- Modify:
src/components/custom-world-home/creationWorkShelf.ts - Modify:
src/components/custom-world-home/CustomWorldCreationHub.tsx - Modify:
src/components/rpg-entry/rpgEntryWorldPresentation.ts - Modify:
src/services/publicWorkCode.ts如分享码需要支持
Rules:
- Bark Battle 作品能展示、打开详情、开始游玩。
- 不新增独立 Bark Battle 专区。
6. 阶段五:收口验证
Task 5.1: 自动测试清单
cargo test -p shared-contracts bark_battle
cargo test -p module-bark-battle
cargo test -p spacetime-module bark_battle
cargo test -p spacetime-client bark_battle
cargo test -p api-server bark_battle
npm test -- --run packages/shared/src/contracts/barkBattle.test.ts
npm test -- --run src/services/bark-battle/barkBattleClient.test.ts
npm test -- --run src/components/bark-battle-creation/BarkBattleConfigEditor.test.tsx
npm test -- --run src/games/bark-battle/domain/__tests__/BarkDetector.test.ts src/games/bark-battle/application/__tests__/BarkBattleController.test.ts src/games/bark-battle/ui/__tests__/BarkBattleRuntimeShell.test.tsx
npx tsc -p tsconfig.typecheck-guardrails.json --noEmit --pretty false
npm run check:encoding
git diff --check
Task 5.2: 后端 smoke
- 按项目脚本启动 SpacetimeDB + api-server,优先使用
npm run api-server,不要使用旧命令。 - 确认
/healthz。 - smoke 流程:创建草稿 → 保存配置 → 发布 → 拉 runtime config → start run → finish run → 查询 leaderboard/history/stats。
Task 5.3: 人工验收路径
- 进入创作入口/玩法选择,选择 Bark Battle。
- 在单页轻配置表单中填写标题,选择主题、狗狗皮肤、难度,保持排行榜开启。
- 保存草稿。
- 发布作品。
- 发布后自动进入作品详情。
- 点击开始游玩进入正式 runtime。
- 授权麦克风,完成 30 秒单局。
- 结算页显示后端
serverResult和 score summary。 - 若胜利,排行榜出现本局成绩。
- 我的记录显示最近记录和个人最佳摘要。
- 作品详情/作者视角能看到作品统计。
- 广场/作品卡片和我的作品入口都能再次进入详情和 runtime。
7. 不做范围
- 不做实时多人。
- 不做 ghost replay。
- 不做 AI 狗叫识别。
- 不保存原始音频、PCM、waveform 或可还原语音内容。
- 不做独立 Bark Battle 专区/活动页。
- 不做挑战分享、好友邀请、多人数房间。
- 不做复杂编辑器、多步骤向导、规则参数编辑、AI 生成配置。
- 不做 DAU/留存、按小时统计曲线、好友对比。
8. 三人并行建议
开发者 A:后端契约与领域规则
负责 Task 1.1、1.3、1.4。先提交 contracts 与 module-bark-battle,为后续后端/前端提供稳定类型和裁决规则。
开发者 B:SpacetimeDB + api-server
负责 Task 2.1 到 2.6。必须等开发者 A 的 DTO/领域规则基本稳定后开始,或先基于计划字段开分支实现表结构。
开发者 C:前端纵切与 UI
负责 Task 3.x 与 4.x。开始时可先做组件空态和 service client 类型,真正联调等 B 的 BFF ready。
9. 推荐提交节奏
feat: add bark battle contracts and domain rulesfeat: add bark battle spacetime tables and reducersfeat: add bark battle api server routesfeat: add bark battle creation editorfeat: connect bark battle runtime to server resultsfeat: add bark battle leaderboard history statsdocs: finalize bark battle phase2 verification guide
10. 完成定义
Phase 2 完成必须同时满足:
- Bark Battle 可以从正式创作入口创建轻配置作品。
- 作品可以发布为稳定 workId。
- 作品详情/广场/我的作品可以发现并进入正式 runtime。
- runtime 从后端发布态 config 拉配置。
- start run 写
work_play_start。 - finish 只上传派生指标。
- 后端裁决
serverResult/scoreSummary/leaderboardScore/antiCheatFlags。 - 胜利局进入按
workId + difficultyPreset + rulesetVersion分榜的排行榜。 - 个人历史和作品统计可查询。
- 自动测试、encoding、typecheck、diff check 和人工验收路径通过。