Files
xsl ee5d4d2544 feat(playbook): 26 号交互手册全量落地——剩余 12 款深度重构 + 语音全量重制
storyline/escape/simon 首批之后的推广收官:15 款全部按 26 号模式运行
(发言权/回执/三档提示/迷茫接管/手势阶梯/断点复述),旧「双击重听/格挡/
菜单确认」等反模式口径全线废除,开场零规则念白(首句即动手)。

游戏层(12 款):rpg(格挡=前摇窗口内再单击)/ rhythm / space / radio /
dungeon / abyss / detective / cipher / teahouse / keeper / bridge /
hunt(联机切片):
- 每款 game.js 接引擎六模块 + makeInputPipeline(doubleTapWindow:0);
  四向玩法类 swipeCore + 长按帮助;双击是玩法的(space 护盾 / hunt
  旋风斩)按手势阶梯阶段 3 分档恢复双击窗口(doubletapCore)
- 每款 playtest 重写:玩法断言 + §6.2 乱点机器人(无声操作 / 被动
  原句重复 / 打断失败 = 0);15 款 3900+ 断言全绿
- 12 份 docs/design/26-apply-*.md 施工单 + tools/voice_lines_26/
  台词清单 + voice-ids 文档同步 + 转写会话剧本按新口径重写

引擎层(web/engine/,6 处修复):pipeline 增 doubletapCore;novice
teachLine 带 voice/ 前缀(此前教学句被静默丢弃);confusion.record
前置到新手门(锁定手势的乱点也计信号);InvalidHints 播完恢复解释前
状态(根治孤儿 BUSY);WaitPoint takeover(2) 台账去重;台账只在
speak 真正播出时登记。遗留引擎债登记 roadmap §3.1。

语音资产:台词表合并(新增 ~250 系统句 / 改 ~50 旧口径 / 删 ~110
废止句;合并器 tools/merge_voice_lines_26.py + 引用校验器
tools/validate_voice_refs.py),GPU 重录 1536 wav → 4204 ogg/m4a
落地,check_all_assets + validate_voice_refs 双绿;键盘变体同步扩表。

大厅/文档:15 款统一新交互口径(「新交互」徽标退役);README /
HANDOVER / rpg README 旧口径修正;roadmap P0-P3 置完成。
2026-10-02 12:33:20 +08:00

141 lines
11 KiB
Markdown
Raw Permalink 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.
# 26-apply · 《围猎》重构施工单(26 号文档落地)
> **设计单正文见 [23-hunt.md](23-hunt.md) 附录 C**(状态×手势矩阵、等待点表、
> 首 3 分钟逐秒脚本、失败表、台词类别)。本文不重复正文,只记录实现接线、
> 偏差、台词类别映射与测试结果。交互规则权威来源:
> [26-audio-interaction-playbook.md](26-audio-interaction-playbook.md)。
> 台词增量清单:`tools/voice_lines_26/hunt.md`;登记副本 [23-hunt-voice-ids.md](23-hunt-voice-ids.md)。
## 1. 实现接线(web/hunt/)
**引擎六模块**(`web/engine/`,未改动):`HuntGame` 构造并暴露 `receipts / floor /
confusion / invalidHints / ladder`;`invalidHints.bind(floor)`;`confusion.onConfused
→ _onConfused`:有等待点走 `wp.takeover(level)`,WAVE 对局走本作三级(见 §3)。
`audio.setRateBoostEnabled(false)`(长按=帮助,不触发旁白快进)。
**发言权**(§4.1):
| 场景 | Floor 状态 |
|---|---|
| TITLE / WAVE / TEACH 战斗 | `enterAction()`(BGM/怪 loop 即状态声) |
| 波次播报 wave_bandN | `floor.speak`(可被出击打断:打断并执行),播完回 ACTION |
| LOBBY / 波间休整 / END / LOST / 菜单 | `floor.speak(...)` 后 `yieldTurn(wp)` |
| MATCHING | BUSY(等 joined;二周目填 intro_1/2,可跳句) |
**管道**(index.html 与 playtest 同一接线):`makeInputPipeline({ floor, confusion,
receipts, invalidHints, game, ladder, opts })`,`opts = { swipeCore: true,
longpressCore: true }`。**双击窗口分档**:`game.DT_CORE = ladder.stage() >= 3` 快照
——stage < 3 时 `attachGestures(..., { doubleTapWindow: 0 })`(双击不存在,键盘回车
折算 tap);stage ≥ 3 用默认窗口 + `doubletapCore: true`(游戏内分发:阶段 3 双击
= 重听威胁档 threat_*;skillUnlocked(阶段 4)= 旋风斩,冷却中仍回威胁档)。阶段 4
解锁:首次以 stage≥3 进入大厅播 `skill_teach` 一句并落盘 `progress.skillUnlocked`
(「大厅全部解锁/专属教学」双口径中的专属教学路径;全项目大厅按钮走
novice.js 既有 unlockAll)。
**onGesture 收口**:`'ok' | 'hold' | 'invalid'`(本作不用 silent-ok:出击/呼喊的内容
音走 R4 队列可能延迟 >100ms,统一 ok 回执保「禁止静默」红线)。`stateName()`:
title/matching/lobby/teach/wave/rest/end/lost/menu。`invalidHint(state,g)` 映射见
game.js `INVALID_LINES`。
**教学波**(§4.10):joined(teach) → T0 `sys_first_tap`(critical,首句动手)→
tap → T1 `tut_hit_full`(critical「朝叫声,滑。」+ 服务器放教学狼)→ 滑砍(错向
miss → atk_swish + `miss_side`「在另一边。」)→ 首杀(`tut_kill_ok` + ladder.onGoal
= 阶段 1)→ T2 `tut_call_full` → 呼喊 → bot help_ack → `tut_callout_ok` → T3
`tut_help_full`(长按=我在哪,阶段 1 教学)→ `tut_done` → 等 ev wave 1。教学步进链
全部 critical(<3s,警报经 `_alertVoice` 排队到链尾冲刷,R1 教学不可顶)。
旧 intro_1/2/tut_rule 规则总述废除(反模式 6);无手动跳过(每步 L3 演示兜底)。
**等待点**(§4.4 三档;配置见 game.js `_introWp/_hitWp/_callWp/_helpWp/_restWp/
_endWp`):intro(tap, 6s/15s, L3 替点)、teach_hit(四向, 8s/15s, L3 替出刀)、
teach_call(tap, 8s/15s, L3 替喊)、teach_help(longpress, 8s/15s, L3 替播帮助)、
lobby(tap, 8s/12s 服务器自动开局, L3 替发 start)、rest(无 full/short——静默只给
提示音)、end(tap, 20s/45s)。**wave 等待点无 WaitPoint**:本波未出手 8s 一次 earcon
(`_startWaveIdleFeed`),出手即停(「本波已出手则永不语音催」);静默信号照喂
迷茫检测(权重 1,单独不触发接管)。
**WAVE 接管**(附录 C §7 迷茫行):L1 `gd_idle`「朝最响的滑。」→ L2 只放行最近怪
弧(`_restrictArc`,其余 invalid 回执)+ `wave_only` → L3 `_demoKillNearest` 替玩家
出刀(服务端裁决;教学狼 ≤2 挡自动放过契约保留)。
**手势语义**(附录 C §3/§4 全表落地,文件头有矩阵注释):
四向滑恒出击(90° 弧;WAVE 内下滑=出击南弧不弹菜单);单击=呼喊(5s 节流,节流内
invalid + `call_cd` 一次解释);长按=我在哪(hp 档 + 波次档 + `lp_act` ≤20 字;重复
问更短,全说过则「再说一遍:」+ lp_act);菜单仅 TITLE/LOBBY/波间休整/END(左右滑
换项、单击确认、长按重听、下滑关闭、回大厅二次确认 `sys_home_check`——原则 6);
结算尾句 end_again critical(800ms 死窗由 critical 承担:ghost tap 得 busy/跳句,
不重开)。
**断点复述**(§4.12,联机豁免口径):联机局不按单机节点存档——①断线 30s 内 resume
回槽播 `net_back`「你回来了。朝叫声滑。」;②一局内被迫退出(房灭/断线超时→LOST、
菜单回大厅、对局中 stop)→ `progress.unfinished` 标记,下次进 TITLE 播 `sys_recap`
一句复述,summary 保留(`_markUnfinished` 在改 phase 前判定)。
**手势阶梯上报**:第一次击杀 `ladder.onGoal()`(阶段 1;**不播 sys_unlock_up**——
hunt 上滑=出击北弧,「我在哪」教学由 T3 tut_help_full 承担);一局 END
`ladder.onGameDone()`(第 1 局 sys_unlock_down / 第 3 局 sys_unlock_dt 追加在结算
尾句后)。
**协议/拥挤/渲染全保留**:join/act/leave + joined/ev/snap/err、服务端权威怪表
对账、三源声像(loop pan + 后半平面低通、生成呼啸、bot 喊话防区 pan)、R2 bot
喊话调度、R4 one-shot 账目、断线 30s 回槽、评级双轴、进度 PUT——playtest Block
0/6/7 与 23 号 §10 验收口径逐条复测通过。
## 2. 偏差记录(对照 23-hunt.md 附录 C)
| # | 偏差 | 理由 |
|---|---|---|
| 1 | critical 落在 T0 `sys_first_tap` 与 T1 `tut_hit_full` 等教学指令句,而非附录 C §8 单指的开场「朝叫声,滑。」 | §8 原意「开场关键句 <3s 不可打断」;T0/T1 指令句均 <3s,critical 期间点按/滑动给 busy 回执(不打断指令),狼逼近期 ≤1.8s,代价可忽略;换来教学链不被警报/乱点打碎的确定性 |
| 2 | 结算链头(end_win→grade→kill_band→end_rank)可跳句可打断;只尾句 end_again critical | §4.6「critical 必 <3s」;800ms 手势死窗由尾句 critical 承担(ghost tap 跳句/回执,不重开) |
| 3 | 冷却内连滑「其后静默」→ 每下都给 invalid 回执(软「咚」),震动仍仅每窗首拦 | 「呼喊节流拒绝/挥空必须出声,禁止静默」红线 + §6.2 无声操作=0;v2 S2 要消灭的是连环 error 震,回执是 120ms 轻音不构成噪声 |
| 4 | 「乱滑计入迷茫但不放技能」保真;阶段 3 双击在非 WAVE = 重听当前等待点(lobby/end),WAVE = 重听威胁档 | §4.3 阶段 3「双击=重听」通用语义与附录 C §3「重听威胁档」战斗语义并存,按语境分发 |
| 5 | 死窗/吞手势一律给回执(busy/invalid),不物理静默 | 同偏差 3 红线 |
| 6 | 状态链旧 4 段(hp/波次/人数/击杀)压缩为长按 3 段(hp+波次+动作);人数移 LOBBY 长按、击杀档留结算 | 附录 C §3 阶段 1 原文「耐久档。波次。一个动作」≤20 字;人数/击杀不属「我在哪」 |
| 7 | 危险状态身份 = danger_low 语音 + danger 震(不再有 guide danger 签名 earcon) | Guide 层整体退役(floor/receipts/hints/confusion 接管);每局一次的语音句自带状态身份,避免新增资产 |
| 8 | WAVE 期一次击杀奖励句不播(kill_wolf 音效 + pickup 震即反馈);教学首杀播 tut_kill_ok | 原则 11 肯定 ≤4 字只用于教学;对局击杀高频,内容音即回报(R5 非语音信息 <1s) |
| 9 | 「冷却中双击=重听威胁」在阶段 4 之前不存在:阶段 3 双击恒重听(含就绪态),不放技能 | 附录 C §3:阶段 3「仍不放技能」;阶段 4 才有就绪/冷却分叉 |
| 10 | 菜单开着时 waveclear 只延长休整窗、不播 wave_clear | E3 菜单链不可被波间播报顶掉;wave_clear 下一波照常播 |
| 11 | `sys_turn_teach` 不使用 | 交接提示音(floor 风铃)+ 等待声已承担「轮到你了」教学;不额外占一句 |
## 3. 台词类别映射(§4.6;全表见 23-hunt-voice-ids.md 与 tools/voice_lines_26/hunt.md)
- `critical`:sys_first_tap(T0 首句)、tut_hit_full / tut_call_full / tut_help_full
(教学指令,均 <3s)、tut_kill_ok 后的步进链、tut_done、结算尾句 end_again
- `content`:intro_1/2、room_wait、room_start、wave_band1-5、wave_clear、end_win/
end_lose/grade_*/end_rank、net_*(回槽/断线复述)、sys_recap、skill_teach、
sys_unlock_down/dt、sys_home_check、sys_menu
- `hint`:tut_*_short、room_wait_short、sys_menu_short、end_again_short、lp_act/
lp_title、threat_*(重听威胁档)、st_wave_*/team_*(长按查询段)、wave_only、
gd_idle、skill_ready
- `feedback`:atk_cd、call_cd、inv_swipe、inv_rest、miss_side、gd_invalid
- 停用/删除:tut_rule、tut_attack、tut_callout、tut_skill、tut_skill_cd、
tut_status、tut_breach、tut_skip、settings_hint(详见台词清单 §3)
## 4. 测试记录
- 无头 playtest:`tools/node/bin/node web/hunt/test/playtest.mjs` —— **255 断言全绿
(退出码 0)**,覆盖:引擎 opts.pan 回归(Block 0)、教学波 §4.10(首句动手 +
首杀 ≤10s + critical 不打断 + 零规则总述)、WAVE 战斗全表(裁剪/冷却/节流/呼喊/
突入/危险/长按状态/休整窗/wave 等待点 earcon 纪律)、双击分档(阶段 3 重听威胁、
阶段 4 旋风斩 + skill_teach)、菜单 E3 + 二次确认、结算 + ladder.onGameDone 解锁
教学 + PUT summary 双轴、断线 resume/net_back/房灭/sys_recap 断点复述、snap 收敛、
R2/R4 拥挤、设置边界、座 3 哨音、资产缺失 Floor 看门狗兜底、静态 id 审计。
- **§6.2 乱点机器人**(Block 10,157 手势跑完 lobby→两波→终局→再来一局):
无声操作 **0**、被动原句重复 **0**、打断失败 **0**(口径注记:①防连点 400ms 内
吸收的快速重点(busy 回执)算一次逻辑交互,豁免;②警报类按事件计重复——每次
突入是新信息,机器人编排按真实节奏注入)。
- 节奏检查(§4.10):教学 T0 第一句即动手(critical ≤1.8s);首杀路径实测 9.6s ≤
10s;每 30s 有可听进展(呼啸/loop 档变化/波次播报/结算)。
- 真人冷启动:待测(§6.3,3-5 人)。
## 5. 已知限制 / 引擎缺口
- 引擎 `InvalidHints.explainOnce` 的 onDone 只恢复等待点:ACTION 语境(无等待点)
的解释句若被打断,floor 会漏在 BUSY。本作以**实例级包装 `floor.handleInput`**
自愈(TITLE/WAVE 无合法长驻 BUSY,输入前回 ACTION),未改引擎;若后续游戏同样
需要,建议把「反馈句播完回调用语境」收进 InvalidHints(引擎侧小改)。
- `Floor.speak` 的 id 必须带 `voice/` 层前缀(裸 id 被引擎静默丢弃,靠 Floor 看门狗
3s 后推进,表现为丢句)——本作在 `_enterEnd` 踩过一次(tail 尾句),已修;静态
审计不覆盖此类问题,值得加一条「speak 前缀 lint」进 harness。
- 联机局断点复述是「一句话 + 重进匹配」口径(23 号 §9 原文),不回填对局中段;
单机式存档恢复与联机豁免冲突,维持不改。