# R3/R4 落地一致性审查报告(策划,最终轮)
> **档案带(26 号之后)**:谱面直转、保护期、断点恢复等工程教训仍有效。附裁 A「玩法手势优先的菜单折中」、结算双击语义等 **让位于 26 号**(演奏期 ACTION、菜单阶段 2 才开放、新手无双击)。
审查对象:`web/rhythm/game.js`(R3 重构)、`web/space/game.js`(R4 重构)。
对照基准:`docs/design/03-rhythm-rebuild.md`(+03-rhythm-voice-ids.md)、`docs/design/04-space-rebuild.md`(+04-space-voice-ids.md)、`00-global-ux.md`。
**总体结论:两款游戏落实度均约 95%+。谱面三首逐音直转零偏差;盲航的演练/保护期/分批引入全部落地且健壮性超设计(`_rearmRunTimers` 断点恢复)。开发上报的 4 个问题裁定见 §3——无推翻性意见,仅 1 处需要一行代码修正(问题①)。**
---
## 1. 《节拍行者》落实度核查(对照 03 文档)
| 设计条目 | 落实 | 结论 |
|---|---|---|
| 谱面三首(90/105/120 BPM,逐乐句拍点) | 逐音核对一致(含 restAfter 休止:曲一前 4 句、曲二前 2 句、曲三不休) | ✅ 零偏差 |
| 判定契约 PERFECT 0.12 / GOOD 0.25 / TAP_DELAY 0.30 / LOOKAHEAD 0.6 / 泵 40ms | 常量一致,Miss 放宽逻辑保留 | ✅ |
| tap 限 1/3 拍、doubletap 曲三前不上反拍 | 谱面核对无违规 | ✅ |
| 教学 T1-T3(做错纠正分"手势错/早/晚/没出手"、2 次失败跳过) | 实现且纠正优先级正确(手势错 > 过早 > 过晚 > 未出手) | ✅ |
| 首次 welcome+BGM 第 6s 起;二周目 welcome_back → 选曲 | 实现(tutorialDone 分支) | ✅ |
| 选曲界面(非模态:左右滑+单击,未解锁播 song_locked) | 实现 | ✅ |
| 计分/评级 S≥0.95 A≥0.85 B≥0.70、解锁规则 B 级解锁下一首 | 实现 | ✅ |
| Miss=不播乐器音(错过=没出声)+ error 震动;Perfect 叠 accent | 实现 | ✅ |
| mid_song 过半播报 | 实现(`_timed` 定时动作) | ✅ |
| 模态菜单(裁决②约定)+ 计时玩法暂停 | 实现且超出设计:BGM 断点续播 + 全部绝对时刻平移暂停时长,节拍网格不漂 | ✅ 超设计 |
| **下滑=菜单 vs 下滑=低音 tom 冲突** | **开发自拟折中**:仅当无悬置/临近(1s 内)的 down 音符时下滑才呼出菜单(`_downNotePending`) | **偏差 1:采纳**(见 §3 附裁 A) |
| 结算单击=再来一遍/右滑=下一首/下滑=回大厅 | 实现,但曲目三右滑播 song_locked 语义错位 | **问题①,见 §3 裁定①** |
| 进度 data 带 summary 同步服务器 | 实现(格式"曲目2 评级A / 已解锁 2/3 首",与设计"《追风》A级 · 已解锁2/3首"措辞略异) | 以实现为准(summary 自由文本) |
| 乐器音 6 + accent 1、BGM 3 首(track90/105/120) | 资产 id 与实现一致 | ✅ |
## 2. 《盲航》落实度核查(对照 04 文档)
| 设计条目 | 落实 | 结论 |
|---|---|---|
| 同向闪避(`s.dir === ob.dir` 判定,窗口/宽限结构不变) | 实现 | ✅ |
| D0-D5 演练:语音先播完再 spawn(不叠放)、做错当场重教、2 次失败 moveon、下滑跳过 | 实现(跳过仅限无演练陨石悬置时,防误触) | ✅ 超设计 |
| 二周目 second_run_ask(上滑重听/单击出发) | 实现 | ✅ |
| 保护期 60s:逼近 4.0s/刷怪 4.0s 恒定、撞击不掉血(训练护盾+protect_
归因)、protect_end 宣告 | 实现(含菜单/分批引入打断后 `_rearmRunTimers` 补播,过期立即补播) | ✅ 超设计 |
| 单击/双击 20s/45s 分批引入(暂停刷怪、8s 不等待) | 实现(feature 阶段完整,引入前对应手势锁定不可用) | ✅ |
| 死亡即教学:hit_ + 第 2 次 hit_last | 实现 | ✅ |
| 里程碑 10/25/50/100(ms_* 整句) | 实现(confirm 震动,设计未指定震型,合理) | ✅ |
| 结算 time_/dodge_ 各 4 档 + new_record + restart_hint | 实现(区间与设计一致:<30/30-60/60-120/≥120;<5/5-14/15-49/≥50) | ✅ |
| 菜单新约定 + paused 播报 + menu_help 项 | 实现 | ✅ |
| **下滑=闪避 vs 下滑=菜单冲突** | **开发自拟折中**:有下方陨石悬置时下滑永远是闪避,否则呼出菜单 | **偏差 2:采纳**(同附裁 A) |
| 警报两档渐强 + danger 震动同步 | 实现 | ✅ |
| 护盾:格挡 success 震动、shield_ready 充能播报 + pickup | 实现 | ✅ |
| 难度参数(保护期后) | **实现 3.2→1.2s 刷怪 / 2.8→1.8s 逼近,比设计 3.2→1.4 / 3.2→2.0 更陡** | **问题③,见 §3 裁定③** |
| 进度 summary 同步 | 实现("最长存活 M:SS / 躲避 N 颗") | ✅ |
## 3. 开发上报问题的裁定
### 裁定①:rhythm 结算页曲目三右滑播 song_locked —— **确认是语义错位,一行修正 + 低优先补录**
- 设计(03 §8.7):结算"右滑=下一首(若已解锁)"。
- 实现(game.js:429-431):曲目三已是最后一首,`songIdx+1 < unlocked` 恒 false → 播 `song_locked`("这首还没解锁。上一首拿到 B 级以上就能解锁。")——玩家会误以为存在曲目四,**语义错误**。
- **裁定(定论)**:曲目三右滑**不得**播 `song_locked`。修正方案(一行代码,零新资产):曲目三右滑时改播 `restart`("单击再来一遍,右滑下一首,下滑回大厅"——虽提到"右滑下一首"仍不完美,但不误导)。**同时**把 `no_more_song`("这已经是最后一首了。单击再来一遍,下滑回大厅。"×2 性别)列入打磨补录清单,录好后替换临时方案。同类问题通查:所有"下一段/下一首"导航语音都要做末位语境检查(教训写入 round5-notes)。
### 裁定②:space `menu_main` 重录文案"单击切换,双击确认" —— **确认 OK,以重录版为准**
- 我的 04-space-voice-ids.md 原文案是"菜单。左右滑选择,单击确认。"——那是 round2 裁决②**之前**的旧菜单约定,是设计文档过时,不是音频错。
- 重录版与全球菜单约定(00 §5.2)一致,**批准**。已对 03/04 两份台词表做勘误注记。rhythm 的 `menu_main` 同理以重录版为准。
- 附带要求:后续所有台词表在"菜单/系统"组的文案以 00 §5.2 最新约定为唯一来源(RPG ch1 台词表已核对:sys_menu "菜单。左右滑选择,单击确认。"——**RPG 属豁免游戏(探索态菜单=左右滑+单击),该句正确,无需改**。)
### 裁定③:space 难度 3.2→1.2s(比设计 1.4s 陡)—— **定论:不回调,以实现为准**
- 设计(04 §3.2):保护期后刷怪 3.2→1.4s、逼近 3.2→2.0s(我在旧版基础上各抬 0.4s/0.2s)。
- 实现:沿用旧版 3.2→1.2s / 2.8→1.8s,更陡。
- **定论:接受实现,不回调。** 理由:
1. 反馈⑨"没搞懂就死"的病灶在前 60 秒,已由演练+保护期+同向闪避三道防线解决;满级难度影响的是 90 秒后的高手区,不是新手区。
2. 满级 1.2s/1.8s 是"传奇段"的挑战上限,老玩家留存需要它;120s 爬升过程本身是平缓的。
3. 真机听测兜底:把"满级段(存活 90s+)密度手感"列入真机 checklist(roadmap §4);若普遍反映过密,把 spawn 下限 1.2→1.35s 作为唯一旋钮(approach 不动)。
- 04 文档参数表以此裁定为最终值(文档不再改,本审查报告即修订记录)。
### 裁定④:rhythm 震动总量 —— **批准,不算过多;两条收紧项**
对照 00 §2 逐条审:
| 震动点 | 合规性 |
|---|---|
| 领奏每音 `beat`(8ms) | ✅ 00 §2.4.2 明确豁免:BEAT 是节拍信息通道,不是反馈。曲三最快处间隔 250ms(120BPM 八分),不违反 200ms 去抖规则 |
| 玩家出手(gesture.js 内置 swipe/confirm) | ✅ 游戏层未重复调用 |
| Miss `error` | ✅ 语义正确(错过=没出声时的唯一反馈) |
| 16 连击 `success` / 全 Perfect 乐句 [20,40,20] | ✅ 语义正确,频率低 |
| 结算 S/A `success`、解锁 success+[20,40,20] | ✅ 在语音链开始前触发,不违反"长对白播放中不震动" |
**收紧项(打磨级,非阻塞)**:
1. 全 Perfect 乐句 [20,40,20] 与 16 连击 success 同刻触发时会双震——按 00 §2.4.3 的 200ms 去抖规则应只震一次,建议游戏层补一个最小去抖(记录上次震动时刻)。
2. 解锁处 success + [20,40,20] 连震两次同理合并为 [20,40,20] 一次。
## 4. 附裁(开发自拟折中的追认)
**附裁 A:玩法手势与"下滑=菜单"冲突的折中模式 —— 采纳为全球惯例。** rhythm(无临近 down 音符才开菜单)与 space(无下方陨石才开菜单)各自实现了同一思想:**玩法手势优先,菜单让位到"当前语境下该手势无玩法含义"时**。这符合 00 §5 豁免精神且比"固定豁免"更顺滑。写入 00 文档精神(不另改文):后续游戏遇同类冲突按此模式处理;RPG 战斗态"下滑=逃跑"本身就是语境判定,天然兼容。
## 5. 遗留事项汇总(转达)
1. rhythm 结算右滑末位修正(裁定①,一行 + 补录 `no_more_song`)。
2. rhythm 震动去抖两处(裁定④收紧项)。
3. 03/04 台词表 menu_main 勘误已落(本论附带完成)。
4. 真机听测:rhythm 的 Perfect 窗口 ±120ms 蓝牙耳机实测、space 满级段密度(裁定③旋钮)、两者 BGM/sfx 响度平衡——进 roadmap §4 checklist。