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 置完成。
117 lines
9.4 KiB
Markdown
117 lines
9.4 KiB
Markdown
# 26-apply · 《雨夜专案》重构设计单(26 号文档落地)
|
||
|
||
> **设计单正文见 [18-detective.md](18-detective.md) 附录 C**(一句话核心动作、三态
|
||
> 声音身份、新手手势表、状态×手势矩阵、等待点配置、首 3 分钟脚本、失败表均以那份
|
||
> 为准,本文不重复)。本文只记四件事:**实现接线、偏差记录、台词类别映射、测试记录**。
|
||
> 台词登记见 [18-detective-voice-ids.md](18-detective-voice-ids.md)(R3 增量节);清单见
|
||
> `tools/voice_lines_26/detective.md`。交互权威:[26-audio-interaction-playbook.md](26-audio-interaction-playbook.md)、
|
||
> [00-global-ux.md](00-global-ux.md)。范式对齐 [26-apply-storyline.md](26-apply-storyline.md)
|
||
> 与 [26-apply-radio.md](26-apply-radio.md)(叙事型主参考)。
|
||
|
||
## 1. 实现接线
|
||
|
||
**引擎六模块(构造并暴露,`web/detective/game.js` 构造函数)**:
|
||
`receipts`(回执三件套)/ `floor`(发言权)/ `confusion`(`onConfused → floor.waitPoint.takeover(lvl)`)/
|
||
`invalidHints`(`.bind(floor)`)/ `ladder`(手势阶梯)——`index.html` 用
|
||
`makeInputPipeline({ floor, confusion, receipts, invalidHints, game, ladder })` +
|
||
`attachGestures(root, pipe, { doubleTapWindow: 0 })` 接线(照 storyline/index.html)。
|
||
本作无核心长按/四向滑动/双击玩法,不传 `opts`(`longpressCore` 等全 false),
|
||
并 `setRateBoostEnabled(false)`(长按=新手 invalid,不快进)。
|
||
|
||
**状态机 → Floor 态映射**(18 号 §2 状态机不动):
|
||
|
||
| 游戏态 | Floor 态 | 说明 |
|
||
|---|---|---|
|
||
| TITLE/BOARD 空闲/CONFRONT/FINISH/SETTLE/MENU 的播报链 | SPEAKING → yieldTurn(等待点) | `floor.speak` 链级压低,句间不掉回「轮到你」 |
|
||
| BOARD 听取中(`_play` 非空) | **ACTION** | 证词链由游戏层逐句推进(0.8s 句间 + 15s 单句兜底),`holdDuck` 自管;tap=停、左右滑=打断切条目直达游戏层(§4.1 裁定滑动有明确意图) |
|
||
| VERDICT / 判定链 / 错指链 / 结算链 | SPEAKING(**critical 全链**) | 链锁:手势只给 busy 回执,链尾驱动相位推进 |
|
||
|
||
**等待点实现**(`_wp(conf)` 工厂 → `engine/hints.js` WaitPoint,对应 18 号附录 C §5):
|
||
`title(12/30s)`、`board(18/40s)`、`caseGate(12/30s)`、`cf_item(15/30s)`、`cf_line(15/30s)`、
|
||
`cf_confirm(15/30s)`、`finish(20/45s,full=当前问句)`、`settle(20/45s)`、`menu(20/45s)`。
|
||
L3 演示:board=替滑下一份、cf_item=选第一份、cf_line/confirm=替确认/替定下、
|
||
finish=滑到正确项**不代答**(保底必结不代答裁定)、其余=提示音。
|
||
|
||
**无进展轨(必结案保底,18 号 §5)**:45s `sfx/turn_tick`(earcon 层,证词播中也发)→
|
||
90s 短句(hint_a/hint_b)→ 150s 直接给可指证矛盾对(hint_c1/c2、b_hint_c1/c2 按
|
||
seed 定序轮询,每句全局限 2 次);只由进展事件(听完新条目/判定/结案推进)重置,
|
||
任何手势都不重置,菜单挂起时长剔除(`_progAdjustMenuPause`)。
|
||
|
||
**存档(§4.12)**:进展即写 `soundgame.progress.detective`(seed/pack/layout/heard/
|
||
heardLines/lastLine/doubts/cfMiss/wrongWho/zHits/hintsGiven/hintFinShown/weaponAns/
|
||
motiveAns + meta;summary 必带:「雨夜·聚宝斋 · 已问n/6 · 疑点m/4」/「已结案N起 · 最佳X」)。
|
||
回来 sys_continue_ask → 单击续玩(先播状态复述链=上滑链同构)→ 右滑换新案。
|
||
VERDICT/SETTLE 链期间不落「进行中」快照(`run=null` 后才写)。
|
||
|
||
**开场(§4.10)**:第一句 = critical「点一下屏幕。」→ 砍掉旧 intro_1..3 规则链与
|
||
DRILL 七步教学;教学嵌真实案卷(`_ob`:listen1 → nav → cf):新案一句 + intro_1 →
|
||
签名+「老葛的证词」+「单击,听取。」+「轮到你」状态教学 → 听完第一份 →「向右滑,
|
||
下一份。」+ 上滑解锁句 → 听完第二份 →「滑到指证,点一下。」→ 首次指证=练习
|
||
(判定截获 tut_cf_ok,零账目污染,`meta.drillDone` 收官)。TITLE 上滑重听案情
|
||
简介链(intro_1..3 不占开场)。
|
||
|
||
## 2. 偏差记录(相对 26 号手册/18 号附录 C 的落地裁定)
|
||
|
||
1. **听取 = ACTION 而非 SPEAKING**:证词是「玩法本身的声音」(§4.1 ACTION 定义),
|
||
tap=停/左右滑=切条目直达游戏层、句粒度可停;游戏层自管 `holdDuck` 与 15s 单句
|
||
兜底(引擎 Floor 哨兵只管自己的链)。矩阵「证词在播」行据此独立于「游戏在说」。
|
||
2. **VERDICT 800ms 死窗被 critical 全链覆盖**:原显式死窗语义(18 号 §7.4)由
|
||
critical 链锁结构性涵盖且更强(整条认罪+结算链手势全吞),`VERDICT_GRACE_MS`
|
||
常量留档不另起计时器。
|
||
3. **板上单击防抖在游戏层**:ACTION 态管道不设防(§4.2 只管 tap=继续/跳过),
|
||
起停 400ms 防抖由 `_lastBoardTapAt` 自管(连点不把刚起的播掐死、闸不误进)。
|
||
4. **入口句登 30s 台账(原则 9 补强)**:fin_pre(结案闸)、fin_start/fin_ask_weapon/
|
||
fin_ask_motive(问句入口)、settle_hook(结算链)、title 句、sys_menu+首项(菜单)、
|
||
cf_confirm(确认句)、FINISH 首选项名——播出即 `markHintSaid`,对应等待点静默
|
||
提示自动降 short/提示音,**被动原句重复清零**(§6.2 指标;条目/选项报名本就走台账)。
|
||
5. **关菜单签名 lead 的 450ms 为 BUSY 演出窗**:`_announceItem` 签名→条目名之间
|
||
手势给 busy 回执(§4.1 BUSY 语义);真人听到条目名落声再动手,playtest 同律。
|
||
6. **`sys_help` 保留但改词**(radio 路线是删除):本作菜单上滑=重听帮助+设置提示
|
||
是附录 C 矩阵行,句子保留、旧「双击重新听/长按指证」口径整句重写。
|
||
7. **结案三问上滑=重听问句**(矩阵行):不与「我在哪」争用——探长的「在哪」由
|
||
板上状态链承担,问答态问句即位置。
|
||
8. **矩阵外防御**:`_judge` 对矩阵外同轴异值对兜底 cf_diff(生成期矩阵不变式断言
|
||
已排除,防御不崩);`_ensureTurn/_orphanTurnHeal` 保证任何打断不留 BUSY 悬空
|
||
软锁(§4.1 不允许安静态)。
|
||
|
||
## 3. 台词类别映射(§4.6;完整清单见 `tools/voice_lines_26/detective.md`)
|
||
|
||
- `critical`:sys_first_tap(开场 ≤3s 唯一一次指令)、fin_pre(结案闸句)、判定链
|
||
(cf_hit+react / 三档 miss)、错指链(acc+fin_clear+st_wrong)、cf_second(第二份
|
||
定下自动重播,误触不打断)、VERDICT→SETTLE 全链(fin_right→break→gavel→结算)
|
||
- `content`:intro_1..3、证词 NPC(N1-N7 平铺)、sc_*、z_break/b_shun_break、rate_*、
|
||
settle_open/settle_hook、item_*/item_who_*/wp_*/mv_*、tut_next_full、tut_cf_try/ok、
|
||
sys_turn_teach、sys_unlock_*、sys_menu*/sys_help/settings_hint、st_asked/st_doubt/st_miss
|
||
- `hint`:hint_board_full/short、hint_cf_item_full、hint_fin_short、hint_tap_short、
|
||
hint_a/b、hint_c1/c2、b_hint_c1/c2、hint_fin、recap_go/recap_cf、st_confront、
|
||
sys_first_tap_short、sys_say_again(重听前缀)、sys_continue_ask
|
||
- `feedback`:cf_self/cf_same/cf_diff(三档真话归因)、fin_wp_wrong/fin_mv_wrong、
|
||
inv_up_locked/inv_down_locked/inv_longpress
|
||
- 新增 18 / 修改 4 / 删除 11(含 KEY_LINES 变体:新增 15、重录 4、停用 5);
|
||
双性别 104→111 句(≤176 上限),NPC 53 平铺不动。
|
||
|
||
## 4. 测试记录
|
||
|
||
- **无头 playtest**:`web/detective/test/playtest.mjs` **283 断言全绿**(`tools/node/bin/node
|
||
web/detective/test/playtest.mjs` 退出码 0,三连跑稳定)。覆盖:开场 §4.10(3s 动手/
|
||
首成功/教右滑/解锁上滑/滑到指证/练习零账目)、seed 复现与矩阵不变式(pack A/B
|
||
同轴异值对 ≡ 矛盾表)、听取 ACTION 态手势矩阵(句序/续听/tap 停/连点 busy/
|
||
滑动打断切条目/上滑状态链/15s 兜底)、M1-M4 指证(hit 按轴/共用 z_4/自动重播/
|
||
4-4 hint_fin/选句位置记忆)、miss 三档真话+无序、结案闸/错指不在场证明/三问/
|
||
VERDICT 死窗+链锁/接新案翻包、评级六变量 12 组注入矩阵、三档提示 18s/40s、
|
||
迷茫接管 L1/L2、无进展轨 45/90/150、断点复述+上滑同链、pack B 变体、
|
||
settings.input 键盘路由(游戏代码零 `_k` 硬编码)、模态菜单/重启二次确认/
|
||
保存 PUT summary。
|
||
- **§6.2 乱点机器人**(场景 15,140 步急躁新手模拟):**无声操作 0 / 被动原句重复 0 /
|
||
打断失败 0**、第一次操作 ≤10s、第一次成功 ≤20s、结束态健康(零死锁)。被动重复
|
||
的「玩家触发」豁免窗口 = 手势后 12s 内的响应链(含 onDone 续播与多句反馈链,
|
||
恰低于最早等待点静默阈值 12s——看门狗句仍全计被动)。
|
||
- **玩家感知转写**:`web/harness/sessions/detective.mjs` 已同步 26 号口径(开场第一下
|
||
tap、指证=列表项单击进入、菜单左右滑+单击确认、`floor.state` 链级门控、不裸
|
||
waitIdle)——`tools/node/bin/node web/harness/transcribe.mjs detective`(含
|
||
`--session sessionStress`)两剧本零死锁跑通(主线虚拟 684s 全弧线到 pack B 短打;
|
||
乱按压力 396s:零进展三级抢救→保底指证→乱答修正→SETTLE→接新案)。
|
||
- 资产并行生产期:运行期引用 154 个 id 中缺失 13 个(新增句),mock 按可用推进
|
||
不卡流程;`tools/node/bin/node --check web/detective/game.js` 通过。
|
||
- 真人冷启动:待测(26 §6.3,3~5 人)。
|