Files
SoundGame/docs/design/26-apply-dungeon.md
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

18 KiB
Raw Permalink Blame History

26-apply · 《回声地窟》重构施工单(26 号文档落地)

设计单正文见 16-dungeon.md 附录 C(一句话核心动作 / 状态 / 手势表 / 等待点 / 首 3 分钟脚本 / 失败表 / 台词账目 / 断点复述),本施工单不重复, 只写:实现接线(§11)、偏差记录(§12)、台词类别映射(§8)、测试记录(§10)。 交互规则权威来源:26-audio-interaction-playbook.md、 00-global-ux.md §5.3。台词登记 16-dungeon-voice-ids.md。 本次只动交互层:地窟生成、回声编码、战斗数值、遗产经济一概不动。

1. 一句话核心动作

朝四个方向滑动在洞窟里走,单击发出声波脉冲听地形,按住屏幕问路。

2. 玩家可感知的状态(3 个)与声音身份

状态 听感 来源
探索(轮到你) 洞穴环境垫 amb_cave(静默 20s 补一层)+ 脚步/回声/怪物脚步就是状态声 §4.1 ACTION
听讲(游戏在说) 教学/遭遇/结算语音,BGM 整链压低(floor.holdDuck) §4.1 SPEAKING
危险(战斗) battle/boss BGM;敌方前摇音 tel_* + beat 震;血 ≤25% warning 震 ACTION + 战斗曲即状态

撞墙 = 闷响 bump + invalid 回执,不算第四态(一次性教,见 §7)。

3. 新手手势表(四向滑动是玩法 → §4.3 裁定:帮助换到长按)

手势 含义 说明
四向滑动 面朝相对移动:上=前进一格;左=向左一格并转向;右=向右一格并转向;下=后退一格(面朝不变) swipeCore,阶段 0 即核心,不按阶梯锁
单击 脉冲(探索);楼梯格=下潜确认;战斗我的回合=挥击;敌方前摇窗内=格挡 核心动词;旧「双击=免冷却重发」「双击=格挡」废除
长按 我在哪(层[+血 if 伤]+面朝+目标方位,≤20 字) longpressCore;旧「按住前进」废除;对局期关闭旁白快进
双击 新手期按单击处理;阶段 3 = 重听(结算/标题重听等待点句;探索 = 冷却外再脉冲) 禁绑「立刻免冷却重播」
下滑 探索/战斗=后退/逃跑(玩法占用);菜单仅阶段 2 且 TITLE/SETTLE 00 §5.3

管道:makeInputPipeline({ ..., opts: { swipeCore: true, longpressCore: true } }) + attachGestures(root, pipe, { doubleTapWindow: 0 })。

4. 状态 × 手势矩阵(新手期)

状态 \ 手势 单击 四向滑动 长按 双击(未解锁) 连点/乱滑
TITLE 开始/继续 + ok 右=新周目;上=元进度链;左/下(未解锁)=invalid+解释 重听询问句 按单击 计入迷茫
教学作答 按步骤(脉冲/确认) 按步骤走/转向;步骤外 invalid+inv_drill 帮助(D5 即教学内容) 按单击 计入迷茫
探索(ACTION) 楼梯格=下潜;否则脉冲+回声组(silent-ok);冷却中 invalid+inv_pulse 移动=脚步(silent-ok);撞墙=bump+invalid+归因+方位真话 帮助(层/血/面朝/方位) 按单击(=再脉冲) 乱滑计入迷茫;冷却连点 invalid
描述在播 跳过这句 + ok 打断并移动 打断,帮助 按单击 第一下有效
战斗·我的回合 挥击(面前才中) 左/右=转身(缠斗怪 btl_no_turn 每场一次);下=逃跑(Boss 拒绝);上=战斗状态 帮助(血+敌方位) 按单击 计入迷茫
战斗·敌前摇 格挡(面对 ×0.2 / 未面对 ×1.0) 左/右=转身(来得及则面对) invalid+inv_tel 按单击=格挡 只处理第一下
DESCEND 演出 跳句 + ok 打断演出(兜底定时器续流程) 同左 按单击 busy/ok
结算(critical 链) busy 回执(死亡/通关归因链不打断) busy 回执 busy 回执 busy busy
结算(等待) 再探一次 + ok 上=元进度链;左=invalid+inv_settle;下(阶段2)=菜单 重听结算句 (阶段3)重听结算句 只处理第一下
菜单 确认当前项 + ok 右=下一项 / 左=上一项(hold);上=帮助 重听菜单说明 按单击=确认 busy
迷茫 L2 期间 照常 只放行接管方向,其余 invalid(不移动) 照常 照常 照常

验收:无空格、无「没有声音」的格子;连点/乱滑无破坏性效果(重开走菜单二次确认)。

5. 等待点配置表(教学期)与探索期接管

教学等待点(6s/15s 两档;wrong 手势 = invalid 回执 + explainOnce,三级接管后 75s 兜底自动过步):

步 期待 指令句(full) short
D0 单击 d0_new「黑暗。点一下,听回声。」(critical) sys_first_tap_short「点一下。」
D1 再单击(巩固) tut_praise + tut_front_rule(回声规则) 「点一下。」
D2 上滑(前进) sys_turn_teach → tut_move「朝前,滑一下。」 hint_swipe「滑一下。」
D3 左/右滑(侧移转向) tut_side_move「向左滑,转身走。」 hint_swipe
D4 走到金币格(四向) tut_coin「房里有金币,走过去捡。」→ 拾取即 ladder.onGoal() hint_swipe
D5 长按 tut_help_hold「迷路了,按住屏幕。」→ 帮助链即答案 「按住屏幕。」
D6 教学战:前摇单击格挡→单击挥击 tut_mob → tut_parry_tap → tut_attack btl_turn_short「点一下,打。」
D7 自行走到楼梯→单击下潜 tut_stairs「铁器的回声,就是下潜的楼梯。」 hint_swipe

其他等待点:

id 期待 full short 静默 L3 演示
title tap/right sys_first_tap / sys_continue_ask 「点一下。」 12s/30s 提示音
battle tap/left/right gd_turn「轮到你了。单击挥击。」 btl_turn_short「点一下,打。」 8s/15s 游戏替你挥一拳
settle tap settle_again「单击,再探一次。」 「点一下。」 20s/45s 提示音
menu tap/left/right menu_help menu_help 20s/45s 提示音

探索期(无固定等待点,静默 40s 起每 20s 喂迷茫信号)三级接管:

级 做什么 台词
1 说目标(铁器暗示/窟主守梯,30s 台账去重) stair_hint_a「找找铁器的回声,那是楼梯。」/ stair_hint_b
2 只放行最短路首步方向(面朝相对换算) sys_only_*「现在,只要向左滑。」
3 听我做一次:游戏自己朝楼梯走一步 sys_demo + 脚步声 + sys_now_you

进展事件(拾取/击杀/踏上楼梯/下潜/下潜层)清零重来。

6. 首 3 分钟逐秒脚本

时间 游戏说 / 播 期待玩家做 没做 做错
0~3s amb_cave →「黑暗。点一下,听回声。」(critical) 单击脉冲 6s:「点一下。」15s:提示音 滑动:invalid + inv_drill
3~8s pulse + echo + 材质 →「对。」「回声回来越快,墙就越近。」 再点一次(巩固) 「点一下。」 冷却内连点:invalid + inv_pulse
8~10s 第二组回声 + 奖励音(levelup 低音量)= 第一次成功 —
10~25s 「听到这个声音,就是轮到你了。」→ 交话轮 →「朝前,滑一下。」 上滑前进 「滑一下。」 撞墙:bump + wall + wall_dir_front
25~40s 「向左滑,转身走。」→ 转身声+脚步 左/右滑侧移 「滑一下。」 其他方向也走(D3 接受左右)
40~60s 「房里有金币,走过去捡。」→ 拾金币 + onGoal 四向滑动 三档提示 撞墙归因
60~75s 「迷路了,按住屏幕。」→ 帮助链(层/面朝/楼梯方位) 长按 「按住屏幕。」 其他:inv_drill
75~90s 「前面有东西!放心,它伤不到你。」→ 教学蝠逼近 听脚步 接管 乱动:战斗内纠错
90~180s 「听到动静,单击格挡。」→ 前摇单击格挡 →「现在单击,挥拳打它」至击杀 →「铁器的回声,就是下潜的楼梯」→ 自行走到楼梯 →「楼梯就在脚下。单击,下潜。」 单击 三档/接管 挥空:btl_swish 每场一次

节奏检查 ✓:3s 内脉冲;~8s 第一次成功(听懂回声);每 30s 有可听进展(金币/击杀/下潜);开场零规则念白(intro_1/intro_2 砍掉)。

7. 失败表

失败类型 判定 归因句 回到哪里 新手期代价
撞墙 目标格越界 首次 wall「那边是墙。」;每方向整局一次 wall_dir_{front,left,right,back},之后只 bump+invalid 原地 无伤
脉冲冷却 1.2s 内再点 inv_pulse「回声还没回来,稍等。」(状态×手势一次) 原地 无
挥空 怪不在面前 btl_swish 每场一次(之后只挥空声) 本回合 无
格挡失败 前摇内未点/未面对 「慢了。听到就点。」= tut_parry_miss(教学期);背后 = btl_behind 每场一次 下回合 L1–2 怪打不死你
转身无效 缠斗怪时左右滑 btl_no_turn 每场一次,之后仅 invalid 本回合 无
死亡 HP≤0 die_cause_* 按 lastHit;die_adv_* 按真实格挡/逃跑账(critical 链,不许打断) SETTLE→新周目,金币入 meta 学期不可能死
迷路 迷茫信号 接管 L1→L2→L3 原地 无

8. 台词表(类别标注;清单见 tools/voice_lines_26/dungeon.md)

  • critical:d0_new(开场指令 <3s);死亡链 die_intro→…→settle_again 整链(结局,§4.6);通关链同
  • content:intro 砍掉后的教学链(tut_praise/tut_move/tut_side_move/tut_coin/tut_help_hold/tut_stairs/tut_mob/tut_attack…)、st_(层/血/金/面朝/威胁)、evt_、btl_(遭遇/半血/击杀/战利)、unlock_、settle_win_*、tut_stairs_on
  • hint:长按帮助链(st_floor/st_face/stair_dir_*)、gd_turn、btl_turn_short、hint_swipe、sys_first_tap(_short)、sys_continue_ask、stair_hint_a/b、menu_help
  • feedback:wall、wall_dir_、inv_(pulse/title/settle/drill/tel/menu_locked)、btl_swish、btl_behind、btl_no_turn、tut_parry_miss、die_cause_、die_adv_、sys_only_*、sys_demo、sys_now_you、menu_restart_confirm
  • 通用系统句与 storyline 逐字一致:sys_first_tap / sys_turn_teach / sys_say_again / sys_unlock_down / sys_unlock_dt(00 号 §5.2 阶梯表)。
  • 数字全分档整句不变(层 7 / 血 4 / 面朝 4 / 威胁 4 / 战利 3 / 死因 3 / 建议 3 / 元进度 3; 金位 = meta_gold 3 档 + gold_some 真话句——旧上滑状态链的 st_gold_1..4 随链下线)。
  • 净变化:新增 35、修改 4、删除 25(明细见 tools/voice_lines_26/dungeon.md);127 → 137 句 ×2 性别。

9. 断点复述句

  • 保存:拾取/战斗胜负/下潜/死亡/菜单保存/stop() 自动存(schema 1,summary 字段不变:第{floor}层 · {血量档} · 金币{meta.gold} · 遗产{n}/5)。
  • 回来:TITLE 播 sys_continue_ask → 交出话轮;单击 = 恢复 + 复述链 [st_floor_N, st_hp_X, st_face_X, 楼梯方位句](窟主未清换 stair_hint_b)→ 回 ACTION;右滑 = 新周目(meta 保留,开局 sys_new_run + 同款复述链)。

10. 测试记录

  • 无头 playtest:tools/node/bin/node web/dungeon/test/playtest.mjs,11 场景 + 资产审计, 断言 1551 条全绿、退出码 0(2026-10-02,seed 42/2026 等种子复现)。覆盖:
    1. seed 复现与七层网格不变式(两次构造逐格相等 / 连通 / 楼梯=最远房 / 安全区 / 密度 / L1 教学硬约束);
    2. 新教学链 D0~D7 全走通 + 回声调度全扫描(全地板格 ×4 面向 ===grid 真值,含延迟/音量/侧向时序)+ 下潜复现;
    3. 四向相对移动矩阵 / 撞墙归因(wall + wall_dir_* 每方向一次)/ 脉冲冷却 invalid / 双击(阶段 3)冷却外再脉冲 / 长按帮助 / 呼吸层;
    4. 战斗数学(单击格挡 ×0.2 / 缠斗纠错 / 下滑逃跑 / Boss 拒绝 / 绕位背刺 / 半血 ATK+1 / 自动喝药);
    5. 死亡归因真话 + 遗产自动购置 + 结算 critical 链(在途手势全 busy)+ 菜单(左右滑换项 / 单击确认 / 重开二次确认);
    6. 断点复述(stop 自动存档 / continue_ask / 复述链 / 右滑新周目 meta 保留);
    7. 迷茫接管三级(静默 40s 起 L1 目标句 → 乱撞 L2 sys_only_* 只放行 → 连续无效 L3 演示+交回;进展事件清零重来);
    8. 屏蔽 voice 资产流程不卡死(_sayFlow/_drillChain 兜底);
    9. L1..L7 全网格回声一致性 + 贴身即接战;
    10. 管道契约(stateName / invalidHint / PIPELINE_OPTS = { swipeCore, longpressCore });
    11. §6.2 乱点机器人(150 步):无声操作 0 / 打断失败 0(防连点 busy 回执不计——§4.2 刻意抑制且已有可听反馈)/ 被动原句重复 0 / 首次操作 ≤10s / 首次成功 ≤20s。
  • 资产审计:静态引用 192 id 全量双格式(ogg+m4a)齐全;新句以 PENDING_VOICE 35 条虚拟资产 模拟(照常播放可断言),主会话生成落地后清空清单即自动转实物断言(台词数断言 127 → 137, 口径见 tools/voice_lines_26/dungeon.md「生成与验收」)。
  • 真人冷启动:待测。

11. 实现接线(引擎六模块,对齐 escape 参考)

  • 装配(game.js 构造器 + index.html):this.receipts / this.floor / this.confusion / this.invalidHints(= new InvalidHints().bind(floor)) / this.ladder 全部暴露; audio.setRateBoostEnabled(false)(长按=帮助是核心手势,不触发旁白快进)。 get PIPELINE_OPTS() = { swipeCore: true, longpressCore: true };index.html 照 escape: makeInputPipeline({ floor, confusion, receipts, invalidHints, game, ladder, opts }) + attachGestures(root, pipe, { doubleTapWindow: 0 })。
  • onGesture 收口:返回 'ok' | 'hold' | 'invalid' | 'silent-ok'(移动=脚步声 silent-ok;撞墙/冷却/步骤外=invalid;转身(玩家回合)=hold 不消耗回合)。 stateName() → title/drill/explore/battle/tel/settle/menu/descend;invalidHint(state, g) → inv_pulse / inv_title / inv_settle / inv_drill / inv_tel / menu_help / locked=null (四向+长按均核心,无锁态)。
  • floor 状态流:探索/教学自由步 floor.enterAction()(玩法声即状态);描述/归因/ 帮助链走 floor.speak(_sayContent,播完回 ACTION 或等待点);流程链 _sayFlow (自然播完或超时先到先推进,资产缺失不卡死);教学链 _drillChain(arm 有界兜底)。 等待点 WaitPoint:drill0..7 / title / battle / settle / menu,全配 full/short/ silenceMs/expected/onDemo(§5 表)。
  • confusion:record 由管道喂(新手门之前,锁定手势也喂信号);探索态静默喂信号 40s 首次、每 8s 再喂(窗口内两记静默可累计权重 2);onConfused → 等待点 takeover (wp.takeover),探索态/教学态走游戏侧 _takeover / _drillTakeover(三级,台账去重)。
  • novice 阶梯:D4 拾金币 = ladder.onGoal()(阶段 1;返回的 up 教学对四向玩法 无意义,与 escape 同样忽略);死亡/通关 = ladder.onGameDone()(阶段 2/3),返回的 teachLine(已带 voice/ 前缀,2026-10 novice.js 修复后不要再加前缀)接在结算链尾。
  • 存档:schema 1、summary 第{floor}层 · {血量档} · 金币{meta.gold} · 遗产{n}/5 字段不动;拾取/战斗/下潜/死亡/菜单/stop() 自动存。

12. 偏差记录(与 26 号/16 号的落地差异及理由)

  1. D1 巩固步等待点不即时挂:设计单口径「巩固等待立即挂上」,实现改为回声组落地 (+1.3s)后播规则链、链播完才 yieldTurn——管道契约是「onGesture 返回时 floor 在 YOUR_TURN 即视为完成当前等待点」,手势内同步 yieldTurn 的新等待点会被当已完成摘掉, 随后 invalid 解释链播完无人恢复话轮(floor 停 BUSY 吞手势,D1 卡死根因)。0~1.3s 窗口由回声组内容音覆盖;窗口内抢先单击照常成立(case 1 直答)。
  2. 孤儿 BUSY 看门狗(_healOrphanBusy,800ms 周期,仅 stop() 停):引擎 InvalidHints 解释链的 onDone 只在「挂着等待点」时恢复话轮,探索/教学自由步没有 等待点,链播完 floor 停 BUSY——管道在 floor.handleInput 就拦下 busy,游戏层永远 收不到手势。看门狗按当前态拉回规范态(探索=ACTION / 答题步=重挂等待点 / 前摇= ACTION / TITLE·SETTLE=重交话轮)。引擎缺口:InvalidHints/feedback 链结束后 的状态恢复依赖调用方,建议引擎侧统一兜底(escape 用无条件 resumeTurn 达成同效)。
  3. 教学态接管不走 wp.takeover:其 L2(restrictLine/short 兜底)无 30s 台账检查, 会把刚说过的指令句原样重播,违反「被动原句重复 = 0」红线;改走游戏侧 _drillTakeover(L1 短句 → L2 重教指令句 → L3 _drillDemo,全过台账)。 引擎缺口:WaitPoint.takeover(2) 建议补台账去重。
  4. 战斗玩家回合转身返回 hold:转身不消耗回合,hold 让管道 settleWaitPoint(false) 保住战斗等待点(血量/敌方位长按链播完要回它;silent-ok 会把等待点当已完成摘掉)。
  5. D4 推进走 1.6s 有界定时:evt_coin 链被乱手势打断也不丢 onGoal/进 D5(对齐 _sayFlow 兜底语义,步骤号先守恒)。
  6. tut_praise 不进 D4 链:原则 9 逐字重复禁令(D2/D3 已各一次「对。」),D4 直接 布置任务 tut_coin。
  7. 遭遇自动面对落在 _encounter:走进怪格/相邻扑来先把玩家面朝转到怪的方向 (报名「就在你面前」即真话),保证 D6 单击格挡教学确定性(16 号 §5「遭遇自动面对」)。
  8. btl_no_turn 补 onDone:链播完回战斗等待点(无 onDone 会孤儿 BUSY,见偏差 2)。
  9. 教学不存步骤:断点回来教学未完从头再练(16 号 §10 口径),DRILL 步骤不进存档。