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

11 KiB
Raw Permalink Blame History

26-apply · 《围猎》重构施工单(26 号文档落地)

设计单正文见 23-hunt.md 附录 C(状态×手势矩阵、等待点表、 首 3 分钟逐秒脚本、失败表、台词类别)。本文不重复正文,只记录实现接线、 偏差、台词类别映射与测试结果。交互规则权威来源: 26-audio-interaction-playbook.md。 台词增量清单:tools/voice_lines_26/hunt.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 原文),不回填对局中段; 单机式存档恢复与联机豁免冲突,维持不改。