diff --git a/docs/design/13-playtest-criteria.md b/docs/design/13-playtest-criteria.md index 5ddca539..6d9c82e9 100644 --- a/docs/design/13-playtest-criteria.md +++ b/docs/design/13-playtest-criteria.md @@ -108,3 +108,29 @@ 3. 设置边界:settings.voice 切换后下一句起用对应目录(voice 缓存键含性别);settings.bgm=0 时无 bgm 层加载;speed=1.7 时下一句 playbackRate 生效。 4. 双击=重听在其声明可用的阶段生效(escape 检查/simon 规则/rpg 场景 desc 等)。 5. 菜单约定(裁决②):适用游戏的模态菜单 = 单击循环 / 双击确认 / 上滑帮助 / 下滑关闭(RPG 豁免)。 + +--- + +## 8. round3 变更记录(simon 手势映射例外) + +> round3 G5(research/04-playtests/round2/synthesis.md §2)改变了 simon 的**玩法** +> 手势映射(不是向导层断言):input 阶段双击永远=作答(第 6 音色),主动重听改绑 +> 上滑。按本研究「playtest 断言零改动」红线的例外流程,本节只做追加记录 §3 受影响 +> 断言的替换口径;§3 既有文字不回改,其余 5 个游戏断言零改动。 + +- §3 关键路径 4「主动重听:input 阶段且期望输入非 doubletap 时双击 → 断言 chances + 减少、inputIdx 清零、序列重播」→ 替换为:**input 阶段上滑(且期望输入非 up)= + 主动重听**,断言目标不变(chances 减少、inputIdx 清零、序列重播)。 +- §3 边界「双击冲突(裁定①):期望输入恰为 doubletap 时双击 = 答题(inputIdx 前进), + 不触发重听」→ 保留并强化为:**input 阶段双击永远=作答**——期望非 doubletap 时 + 照常判错(耗机会/死亡),不再触发重听。 +- §3 边界「chances=0 时双击非期望手势:不判错(round 不变、inputIdx 不变)、播 + chances_out」→ 替换为:**chances=0 时上滑非期望手势**,断言目标不变。 +- 新增边界断言:期望输入恰为 up 时上滑=作答(六手势全是答题输入,00 号文档 §5.3 + 豁免同款);非输入阶段(gameover/菜单)上滑行为不变。 +- 随上述改口的测试脚手架微调(非断言变更):两处「错手势注入」的取值从 + `GESTURES.find(g => g !== exp && g !== 'doubletap')` 增加排除 `up`(round3 后 + up=重听键,注入 up 会触发重听而非判错,与旧版注入 doubletap 需避开是同一道理)。 +- 依据:docs/design/14-guide-layer.md「round3 v1.2」§8/G5;simon playtest 断言仅 + 上述 3 处改口(108 条总数不变),其余断言(含教学、复活、结算、菜单、序列约束、 + 速度下限)零改动。 diff --git a/docs/design/14-guide-layer.md b/docs/design/14-guide-layer.md index 38d15df8..b48b1af3 100644 --- a/docs/design/14-guide-layer.md +++ b/docs/design/14-guide-layer.md @@ -114,3 +114,73 @@ `tools/extract_voice_text.py` 已刷新 `web/harness/voice_text.json`(428 句)。 - 转写渲染适配:实际播出的 `voice/gd_*` 由 play 捕获照常渲染;被 idle-skip 的 向导句单独标注「本句按 idle-only 跳过未播」。 + +--- + +# 14 · 向导交互层设计裁定(round3 v1.2 增补) + +> 依据:research/04-playtests/round2/synthesis.md(G1~G8 + §3 新语音表,唯一事实源)。 +> 本文只做**追加**,上文 v1 / round2 裁定不回改;实现载体同前(`web/engine/guide.js` +> + 各游戏 game.js 接线),全部改动已落地。G8(不做项)照裁定书记录,不再列。 + +## 8. round3 裁定落地摘要(G1~G7) + +| # | 裁定 | 落地 | +|---|---|---| +| G1 | rhythm「轮到你」迟到 bug | **根因诊断**:round2 F3 把 gd_answer 排在 `leadBarT0 + 4*spb`——那是首个应答窗口**起点本身**(领奏小节的末尾),不是窗口前;P4 转写(窗口 t+79~95、gd_answer t+93.7)即窗口开后才响,起不到预警作用。**修复**:排程点改到 `leadBarT0`(窗口前整整 1 小节 = 领奏小节头);`_armAnswerCue`/`_fireAnswerCue` 承接——菜单恢复也是一次「进 main」,旧标记已消费时对恢复后首个未判定窗口重排同款标记(已迫近则 0.15s 内尽早补上);上一句结束后的下一句不适用(裁定原文)。gd_answer 语音 full 档经曲谱定时队列直达(不走 guide queue),turn earcon **standard 也发**(off 全静不变)。guide.test 增转写级断言:真实跑 90BPM 一曲,gd_answer 时刻 < 首窗口起点,且窗口起点 − gd_answer ≈ 4×spb。 | +| G2 | rhythm 教学降难 DDA | 同一步连续 2 次失败 → 该步领奏**降速 25% 重演**(`_tutRate=0.75`:该步领奏与应答网格间隔 ×1/0.75,领奏小节头仍对齐 BGM 小节,BGM 不变速;排程照走 `_sched` 绝对时间 + 40ms 泵,泵与判定零改动)+ full 档先播 `gd_slow`「我放慢一些,跟着试试。」(经 `_speakGuarded` 串行,播完才重演);每教学局 1 次封顶(`_tutSlowUsed`);该步做对或离开(跳步)恢复正常速度;降速重演后该步重新给两次机会。**off 档维持 round2 的 retry_skip 跳步原路径**(6 playtest 断言零改动红线)。 | +| G3 | rhythm 恢复 count-in 可感知化 | **根因诊断**:round2 F3.2 的 count-in 排了但**从未按时响过**——底鼓 push 进 `_sched` 后没有重排,队头是数秒外的领奏音符,40ms 泵的 `LOOKAHEAD(0.6s)` 前瞻窗口永远轮不到队尾的 count-in(复现实测:恢复后 4 记底鼓与 beat 震全部迟到聚堆),P3 听到的正是「恢复后 5 秒死寂」。**修复**:push 后 `_sortSched()`;底鼓音量 0.7→**1.0**(sfx 层独立于 BGM,每拍 beat 震保持);full 档恢复时先经 `_speakGuarded` 播 `gd_count`「四拍之后,继续。」(每局恢复限 1 次,`_gdCountUsed`;链完/缺失兜底后才开始数拍);恢复用令牌 `_resumeSeq` 防 count-in 语音期间再开菜单的旧恢复串场。**off 档保持 v1 即时续播**(playtest 断言零改动红线)。 | +| G4 | escape 保险丝→新目标断链 | 拾取保险丝的 `unlock_cabinet`(关键获得不可跳)播完后接 `gd_next_fuse`「保险丝到手。接下来,去找电箱。」——游戏反馈层**全档位**(走游戏语音链不走向导通道,gd_economy 先例)。 | +| G5 | simon 双击双义根治 | **改全局规则**:input 阶段**双击永远=作答(第 6 音色)**——期望恰为 doubletap 判对,否则照常判错,不再承担重听;主动重听改绑**上滑**(期望输入恰为 up 时上滑=作答,六手势全是答题输入的 00 §5.3 豁免同款);非输入阶段行为不变。`gd_economy` 按裁定书新文案**重录**(记不住就向上滑…);教学第 6 音色步资产 `t6_double`「双击,是这个声音。」不含重听语义、无需改动,教学步与新文案不矛盾。**超出裁定书 §3 清单的同口径修正(2 句,见 §9 注)**:`gd_relisten`(input 看门狗提示)与 `t7_retry`(教学收尾链)旧文案都在教「双击重听」,不清掉等于保留 P0,随 G5 一并重录为上滑口径,台词改动仅「双击→向上滑」机械替换。 | +| G6 | simon 局尾反馈轻量化 | 每轮成功在既有轮结算链(`_roundClear` 的 correct/chance_plus 链)尾追加 `gd_clear`「漂亮,过了。」(每局 1 次);本轮完成数超过历史最佳且确有旧纪录(`best>0`)时追加 `gd_record`「破纪录了。」(每局 1 次;结算另有 new_record,此处是局中破纪录的即时一刻)。游戏反馈层全档位。 | +| G7 | space 方向呼喊第二通道 | loud 警报档(撞击前 500ms)回调里同窗直达播 `voice/dir_`「左!/右!/上!/下!」——与 sfx/alarm 分属 voice/sfx 两通道天然同时不互顶(引擎对白 duck 压 BGM 保证可闻);**直达式播放不排队**(呼喊必须赶在撞击前,宁可顶掉里程/充能类短句也不排到链尾迟到);游戏反馈层全档位。 | + +## 9. round3 新增语音资产台词表(11 句 ×2 性别 = 22 文件;其中 G5 为重录 3 句) + +全文与 synthesis §3 逐字一致(speaker/instruct 沿用各游戏旁白 pair 常量,dir_* 按表注 +用 space 旁白 pair);另 2 句为 G5 手势映射的同口径机械修正(裁定书 §3 未列,落地 +原因见 §8/G5——不清掉「双击重听」旧文案,input 看门狗与教学收尾仍在教已废除的手势): + +| 游戏 | id | 全文 | 触发 | +|---|---|---|---| +| rhythm | `gd_slow` | 我放慢一些,跟着试试。 | 教学连 2 失败降速重演前(G2,full 档,每教学局 1 次) | +| rhythm | `gd_count` | 四拍之后,继续。 | 菜单恢复 count-in 前(G3,full 档,每局恢复限 1 次) | +| escape | `gd_next_fuse` | 保险丝到手。接下来,去找电箱。 | 拾取保险丝链尾(G4,全档位) | +| simon | `gd_economy`(重录) | 记不住就向上滑,重新听一遍。免费机会有两次,用完要扣一次机会。 | 开局教学末尾(G5,全档位) | +| simon | `gd_clear` | 漂亮,过了。 | 每轮成功链尾(G6,全档位,每局 1 次) | +| simon | `gd_record` | 破纪录了。 | 局中破个人纪录(G6,全档位,每局 1 次) | +| space | `dir_left` / `dir_right` / `dir_up` / `dir_down` | 左!/ 右!/ 上!/ 下! | loud 警报档方向呼喊(G7,全档位) | +| simon | `gd_relisten`(同口径修正) | 需要的话,向上滑可以重新听一遍序列。 | input 10s 看门狗(原「双击可以重新听」,G5) | +| simon | `t7_retry`(同口径修正) | 答错可以消耗机会重听。向上滑,可以随时重听。 | 教学收尾链(原「双击,可以随时重听」,G5) | + +资产落位与管线同前:`web//audio/voice/{female,male}/.{ogg,m4a}` +(`tools/gen_voice_dual.py --game --only ` 生成 → `--convert` 落盘 → +`tools/check_all_assets.py` 终检)。 + +## 10. round3 验证记录 + +- 6 playtest(guide=off):除 simon 按 13 号文档 round3 变更记录改口 3 处断言 + (input 双击=作答、上滑=重听;108 条总数与 round2 基线一致)外,**断言零改动 + 全绿**:storyline 54 / escape 103 / simon 108 / rhythm 81 / space 113 / rpg 139。 +- `web/harness/guide.test.mjs` **93 条断言全绿**(round2 基线 52 条既有断言零改动, + 其余为新增):G1(gd_answer 时间窗=窗口前整整 1 小节、恢复后重排仍在窗前)、 + G2(连 2 失败降速 ×1/0.75 + gd_slow + 做对恢复 + 每局封顶后回退 retry_skip)、 + G3(恢复先 gd_count 后 count-in、底鼓重排入队头、beat 震、每局限 1 次)、 + G5(双击作答/上滑重听/期望恰为 up 时上滑=作答,full 与 off 双档)、 + G6(gd_clear 每局 1 次 + 破纪录 gd_record)、G7(dir_* 与 loud 警报同窗 ≤50ms)。 + 为此给 harness mock 补了 setInterval/虚拟 ctx.currentTime/用例间 localStorage 隔离。 +- 转写 harness 修复(`web/harness/mock.mjs`,工具层非玩法):decodeAudioData 原来 + 按「最近一次 fetch 的 url」估时长,prewarm 并发下 voice 会随机继承 bgm 的 90s + 时长,语音结束定时器形同虚设(链全靠兜底看门狗推进、教学 tap 被滞留语音当跳过 + 吃掉)——改为按 ArrayBuffer 自身 `__url` 估算,与各 playtest mock 对齐。 +- `tools/check_all_assets.py` 全绿(双格式配对、无 0 字节、全可解码、双性别集合 + 一致);`tools/extract_voice_text.py` 已刷新 `web/harness/voice_text.json` + (437 句)。`gen_voice_dual.py --check` 中 rpg/tut_b0 等 4 句「缺 staging」为 + R5 既有已知项(资产已先行落盘、staging 无 wav),非本轮引入。 +- 转写抽查(research/04-playtests/transcripts/,6 份全部重跑、零资产缺失): + rhythm gd_answer 落在首窗口前整整 1 小节(t+67.0 vs 窗口 t+69.7)、教学第 2 句 + 连 2 失败触发「我放慢一些」+ 慢速领奏(拍距 ×1/0.75)+ 做对恢复、菜单恢复 + 「四拍之后,继续」+ 4 记底鼓 count-in 在;escape 保险丝后紧接 gd_next_fuse、 + 其后再走两步;simon 看门狗提示上滑重听 + 期望恰为 up 时上滑作答 + 双击音 + 双击作答,全程无双击歧义时刻;space 每次撞击前 500ms 警报与「左!/右!/上!/ + 下!」同窗到达。 diff --git a/research/04-playtests/transcripts/escape.md b/research/04-playtests/transcripts/escape.md index 5ea7aa4c..43689af7 100644 --- a/research/04-playtests/transcripts/escape.md +++ b/research/04-playtests/transcripts/escape.md @@ -13,98 +13,111 @@ t+ 0.0s 【状态】引导第 1/8 步 引导第 1/8 步,等我做手势( #### 【玩家动作】照引导单击了一下 t+ 0.0s ▶ 语音:「先活动一下。朝任意方向滑一下,走一小步。」 -t+ 20.0s ♪ 向导音:turn(轮到你) -t+ 20.0s 【状态】引导第 2/8 步 引导第 2/8 步,等我做手势(语音播放中,语速1) +t+ 2.1s ▶ 语音:「单击可跳过旁白。」 +t+ 4.2s ♪ 向导音:turn(轮到你) +t+ 4.2s 【状态】引导第 2/8 步 引导第 2/8 步,等我做手势(BGM=bgm/drone,语速1) #### 【玩家动作】随便滑了一步,有脚步声 -t+ 20.0s ♪ 音效 sfx/step -t+ 20.0s ▶ 语音:「很好,你迈出了第一步。」 -t+ 22.1s ▶ 语音:「这个房间不大,四面都是墙。再滑两下,试试碰碰墙。」 -t+ 24.2s ♪ 向导音:turn(轮到你) -t+ 24.2s 【状态】引导第 3/8 步 引导第 3/8 步,等我做手势(BGM=bgm/drone,语速1) -t+ 24.2s ♪ 音效 sfx/wall -t+ 24.2s ▶ 语音:「那边是墙,换个方向。」 -t+ 24.2s 〰 震动:error(做错了:两连短震) +t+ 4.2s ♪ 音效 sfx/step +t+ 4.2s ▶ 语音:「很好,你迈出了第一步。」 +t+ 6.4s ▶ 语音:「这个房间不大,四面都是墙。再滑两下,试试碰碰墙。」 +t+ 8.5s ♪ 向导音:turn(轮到你) +t+ 8.5s 【状态】引导第 3/8 步 引导第 3/8 步,等我做手势(BGM=bgm/drone,语速1) +t+ 8.5s ♪ 音效 sfx/wall +t+ 8.5s ▶ 语音:「那边是墙,换个方向。」 +t+ 8.5s 〰 震动:error(做错了:两连短震) #### 【玩家动作】又滑一步,又撞墙了——墙的方位听出来了 -t+ 26.4s ♪ 音效 sfx/wall -t+ 26.4s ▶ 语音:「那边是墙,换个方向。」 -t+ 26.4s 〰 震动:error(做错了:两连短震) -t+ 28.5s ▶ 语音:「跟着我指的路走。向左滑。」 -t+ 30.6s ♪ 向导音:turn(轮到你) -t+ 30.6s 【状态】引导第 4/8 步 引导第 4/8 步,等我做手势(BGM=bgm/drone,语速1) +t+ 10.6s ♪ 音效 sfx/wall +t+ 10.6s ▶ 语音:「那边是墙,换个方向。」 +t+ 10.6s 〰 震动:error(做错了:两连短震) +t+ 12.7s ▶ 语音:「跟着我指的路走。向左滑。」 +t+ 14.8s ♪ 向导音:turn(轮到你) +t+ 14.8s 【状态】引导第 4/8 步 引导第 4/8 步,等我做手势(BGM=bgm/drone,语速1) #### 【玩家动作】这回往左,走通了一步 -t+ 30.6s ♪ 音效 sfx/step -t+ 30.6s ▶ 语音:「对。再向下滑。」 -t+ 32.7s ♪ 向导音:turn(轮到你) -t+ 32.7s 【状态】引导第 5/8 步 引导第 5/8 步,等我做手势(BGM=bgm/drone,语速1) +t+ 14.8s ♪ 音效 sfx/step +t+ 14.8s ▶ 语音:「对。再向下滑。」 +t+ 17.0s ♪ 向导音:turn(轮到你) +t+ 17.0s 【状态】引导第 5/8 步 引导第 5/8 步,等我做手势(BGM=bgm/drone,语速1) #### 【玩家动作】往下滑,进了储物间 -t+ 32.7s ♪ 音效 sfx/step -t+ 32.7s ♪ 音效 sfx/amb_storage -t+ 32.7s ▶ 语音:「听到水声了吗?单击一下,仔细检查这个房间。」 -t+ 34.8s ♪ 向导音:turn(轮到你) -t+ 34.8s 【状态】引导第 6/8 步 引导第 6/8 步,等我做手势(BGM=bgm/drone,语速1) +t+ 17.0s ♪ 音效 sfx/step +t+ 17.0s ♪ 音效 sfx/amb_storage +t+ 17.0s ▶ 语音:「听到水声了吗?单击一下,仔细检查这个房间。」 +t+ 19.1s ♪ 向导音:turn(轮到你) +t+ 19.1s 【状态】引导第 6/8 步 引导第 6/8 步,等我做手势(BGM=bgm/drone,语速1) #### 【玩家动作】单击摸一遍房间,摸到钥匙了 -t+ 34.8s ♪ 音效 sfx/pickup -t+ 34.8s ▶ 语音:「你摸到了一把钥匙!」 -t+ 34.8s 〰 震动:pickup(获得) -t+ 37.0s ▶ 语音:「钥匙能开锁。双击,是把物品用出去的用法。现在,双击试试。」 -t+ 39.1s ♪ 向导音:turn(轮到你) -t+ 39.1s 【状态】引导第 7/8 步 引导第 7/8 步,等我做手势(BGM=bgm/drone,语速1) +t+ 19.1s ♪ 音效 sfx/pickup +t+ 19.1s ▶ 语音:「你摸到了一把钥匙!」 +t+ 19.1s 〰 震动:pickup(获得) +t+ 21.2s ▶ 语音:「钥匙能开锁。双击,是把物品用出去的用法。现在,双击试试。」 +t+ 23.3s ♪ 向导音:turn(轮到你) +t+ 23.3s 【状态】引导第 7/8 步 引导第 7/8 步,等我做手势(BGM=bgm/drone,语速1) #### 【玩家动作】双击看了看背包 -t+ 39.1s ▶ 语音:「你身上带着一把钥匙。」 -t+ 41.2s ▶ 语音:「对,就是这样。接下来,靠你自己了。」 -t+ 43.3s ▶ 语音:「找到能用这把钥匙打开的东西。需要帮助时,在原地双击。」 -t+ 45.4s ♪ 向导音:turn(轮到你) -t+ 45.4s ♪ 音效 sfx/amb_storage -t+ 45.4s 【状态】引导完毕,正式开始。我在储物间 探索中,我在 (0,2)。四向滑挪步,单击摸一遍房间,双击用物品(BGM=bgm/drone,语速1) -t+ 45.4s ……… 静默 3s(辨了辨方向) ……… -t+ 45.4s ♪ 音效 sfx/step -t+ 45.4s ♪ 音效 sfx/amb_hum -t+ 50.0s ♪ 音效 sfx/step -t+ 50.0s ♪ 音效 sfx/amb_power -t+ 50.0s ▶ 语音:「这个房间的墙上,有一只电箱。」 -t+ 52.1s ♪ 音效 sfx/wall -t+ 52.1s ▶ 语音:「那边是墙,换个方向。」 -t+ 52.1s 〰 震动:error(做错了:两连短震) -t+ 54.2s ▶ 语音:「手指贴着屏幕,向上推一下。」 +t+ 23.3s ▶ 语音:「你身上带着一把钥匙。」 +t+ 25.4s ▶ 语音:「对,就是这样。接下来,靠你自己了。」 +t+ 27.6s ▶ 语音:「找到能用这把钥匙打开的东西。需要帮助时,在原地双击。」 +t+ 29.7s ♪ 向导音:turn(轮到你) +t+ 29.7s ♪ 音效 sfx/amb_storage +t+ 29.7s 【状态】引导完毕,正式开始。我在储物间 探索中,我在 (0,2)。四向滑挪步,单击摸一遍房间,双击用物品(BGM=bgm/drone,语速1) +t+ 29.7s ……… 静默 3s(辨了辨方向) ……… +t+ 29.7s ♪ 音效 sfx/step +t+ 29.7s ♪ 音效 sfx/amb_hum +t+ 35.0s ♪ 音效 sfx/step +t+ 35.0s ♪ 音效 sfx/amb_power +t+ 35.0s ▶ 语音:「这个房间的墙上,有一只电箱。」 +t+ 37.1s ♪ 音效 sfx/wall +t+ 37.1s ▶ 语音:「那边是墙,换个方向。」 +t+ 37.1s 〰 震动:error(做错了:两连短震) +t+ 39.2s ▶ 语音:「手指贴着屏幕,向上推一下。」 #### 【玩家动作】北边是墙,撞了一下——「那边是墙」后面还跟了句方向(向上推的是北墙) -t+ 54.2s ♪ 音效 sfx/wall -t+ 54.2s ▶ 语音:「那边是墙,换个方向。」 -t+ 54.2s 〰 震动:error(做错了:两连短震) -t+ 55.0s ▶ 语音:「需要帮助吗?」 -t+ 55.0s 〰 震动:warning(警告三连震) -t+ 57.1s ▶ 语音:「钥匙就在你身上。它能打开某一把锁。」 +t+ 39.2s ♪ 音效 sfx/wall +t+ 39.2s ▶ 语音:「那边是墙,换个方向。」 +t+ 39.2s 〰 震动:error(做错了:两连短震) +t+ 40.0s ▶ 语音:「需要帮助吗?」 +t+ 40.0s 〰 震动:warning(警告三连震) +t+ 42.1s ▶ 语音:「钥匙就在你身上。它能打开某一把锁。」 #### 【玩家动作】又撞了一下——听到游戏主动来问我了 -t+ 65.0s ♪ 音效 sfx/step -t+ 65.0s ♪ 音效 sfx/amb_wind +t+ 50.0s ♪ 音效 sfx/step +t+ 50.0s ♪ 音效 sfx/amb_wind #### 【玩家动作】往东走,风声换了个方向 -t+ 70.0s ♪ 音效 sfx/step -t+ 70.0s ♪ 音效 sfx/amb_hum -t+ 75.0s ♪ 音效 sfx/step -t+ 75.0s ♪ 音效 sfx/amb_cabinet -t+ 75.0s ▶ 语音:「这个房间里,立着一个铁柜。」 +t+ 55.0s ♪ 音效 sfx/step +t+ 55.0s ♪ 音效 sfx/amb_hum +t+ 60.0s ♪ 音效 sfx/step +t+ 60.0s ♪ 音效 sfx/amb_cabinet +t+ 60.0s ▶ 语音:「这个房间里,立着一个铁柜。」 #### 【玩家动作】到了铁柜房,柜子锁着 -t+ 77.1s ♪ 音效 sfx/unlock -t+ 77.1s ♪ 音效 sfx/door_creak -t+ 77.1s ▶ 语音:「钥匙插进锁孔,缓缓转动。咔哒一声,柜门开了。柜子深处,躺着一枚保险丝。保险丝到手了。」 -t+ 77.1s 〰 震动:success(成功长震) -t+ 85.0s 【状态】柜子开了,拿到保险丝——解到第二间,收工 探索中,我在 (2,1)。四向滑挪步,单击摸一遍房间,双击用物品(BGM=bgm/drone,语速1) +t+ 62.1s ♪ 音效 sfx/unlock +t+ 62.1s ♪ 音效 sfx/door_creak +t+ 62.1s ▶ 语音:「钥匙插进锁孔,缓缓转动。咔哒一声,柜门开了。柜子深处,躺着一枚保险丝。保险丝到手了。」 +t+ 62.1s 〰 震动:success(成功长震) +t+ 64.2s ▶ 向导语音:「保险丝到手。接下来,去找电箱。」 +t+ 66.4s 【状态】柜子开了,听到「保险丝到手。接下来,去找电箱」——目标又有了 探索中,我在 (2,1)。四向滑挪步,单击摸一遍房间,双击用物品(BGM=bgm/drone,语速1) +t+ 66.4s ♪ 音效 sfx/step +t+ 66.4s ♪ 音效 sfx/amb_drip + +#### 【玩家动作】照新目标往西摸 + +t+ 70.0s ♪ 音效 sfx/step +t+ 70.0s ♪ 音效 sfx/amb_hum + +#### 【玩家动作】再走一步,西边隐隐有电流声——电箱在那边 + +t+ 75.0s 【状态】解到第二间、照下一目标句又摸了两步,收工 探索中,我在 (0,1)。四向滑挪步,单击摸一遍房间,双击用物品(BGM=bgm/drone,语速1) diff --git a/research/04-playtests/transcripts/rhythm.md b/research/04-playtests/transcripts/rhythm.md index 14fcd399..b646ff66 100644 --- a/research/04-playtests/transcripts/rhythm.md +++ b/research/04-playtests/transcripts/rhythm.md @@ -5,173 +5,168 @@ > 非最优操作:包含犹豫、误操作与乱试。语音时长按语速估算(±20%),仅供节奏参考。 t+ 0.0s (玩家点开游戏,轻触屏幕开始) t+ 0.0s ▶ 语音:「欢迎来到节拍行者。跟着音乐,我奏一句,你跟一句。」 -t+ 8.0s ▶ 语音:「听,底鼓。在下一小节的同一个位置,单击。」 -t+ 18.0s 【状态】教学开始了,先听领奏 教学:听领奏,下一小节照样打(tap)(语音播放中,语速1) -t+ 18.0s 【状态】教学第 1/3 句 教学:听领奏,下一小节照样打(tap)(语音播放中,语速1) -t+ 19.3s 〰 震动:beat(节拍点) -t+ 23.0s ▶ 语音:「再听一遍,跟着来。」 -t+ 23.0s 〰 震动:error(做错了:两连短震) -t+ 25.1s ▶ 语音:「再听一遍,跟着来。」 -t+ 27.2s ▶ 向导语音:「慢了半拍。跟着节拍走。」 -t+ 30.0s 〰 震动:beat(节拍点) -t+ 33.6s ▶ 语音:「没关系,我们先走下一句。」 -t+ 33.6s 〰 震动:error(做错了:两连短震) -t+ 35.8s ▶ 语音:「这次是左和右。跟着打,左滑,右滑。」 -t+ 35.8s 【状态】教学第 2/3 句 教学:听领奏,下一小节照样打(tap)(语音播放中,语速1) -t+ 38.0s 〰 震动:beat(节拍点) -t+ 39.3s 〰 震动:beat(节拍点) -t+ 43.0s ▶ 语音:「再听一遍,跟着来。」 -t+ 43.0s 〰 震动:error(做错了:两连短震) -t+ 45.1s ▶ 语音:「再听一遍,跟着来。」 -t+ 47.2s ▶ 向导语音:「慢了半拍。跟着节拍走。」 -t+ 48.7s 〰 震动:beat(节拍点) -t+ 50.0s 〰 震动:beat(节拍点) -t+ 53.6s ▶ 语音:「没关系,我们先走下一句。」 -t+ 53.6s 〰 震动:error(做错了:两连短震) -t+ 55.8s ▶ 语音:「最后一句,三个音,中间是双击。」 -t+ 55.8s 【状态】教学第 3/3 句 教学:听领奏,下一小节照样打(left→right)(语音播放中,语速1) -t+ 55.8s ♪ 音效 sfx/inst_hat_l -t+ 55.8s ♪ 音效 sfx/inst_hat_r -t+ 59.3s 〰 震动:beat(节拍点) -t+ 60.0s 〰 震动:beat(节拍点) -t+ 60.7s 〰 震动:beat(节拍点) -t+ 64.3s ▶ 语音:「再听一遍,跟着来。」 -t+ 64.3s 〰 震动:error(做错了:两连短震) -t+ 66.4s ▶ 语音:「再听一遍,跟着来。」 -t+ 68.6s ▶ 向导语音:「慢了半拍。跟着节拍走。」 -t+ 70.0s 〰 震动:beat(节拍点) -t+ 70.7s 〰 震动:beat(节拍点) -t+ 71.3s 〰 震动:beat(节拍点) -t+ 75.0s ▶ 语音:「没关系,我们先走下一句。」 -t+ 75.0s 〰 震动:error(做错了:两连短震) -t+ 77.1s ▶ 语音:「很好,演出开始。」 -t+ 79.2s ♪ 向导音:battle(战斗/对抗) -t+ 79.2s 【状态】教学完毕,曲目一《启程》90 拍开始 演奏中(启程):还剩 31 个应答音。领奏停了、轮到空拍,就该我出手了(无 BGM,语速1) -t+ 81.7s ♪ 向导音:menu(系统界面) -t+ 81.7s ▶ 语音:「菜单。单击切换选项,双击确认。」 -t+ 81.7s 【状态】曲中暂停,进了菜单 暂停菜单:单击切选项,双击确认,上滑帮助,下滑恢复演奏(语音播放中,语速1) -t+ 81.7s ▶ 语音:「回大厅。」 +t+ 2.1s ▶ 语音:「听,底鼓。在下一小节的同一个位置,单击。」 +t+ 4.2s 【状态】教学开始了,先听领奏 教学:听领奏,下一小节照样打(tap)(无 BGM,语速1) +t+ 4.2s 【状态】教学第 1/3 句 教学:听领奏,下一小节照样打(tap)(无 BGM,语速1) +t+ 6.0s 〰 震动:beat(节拍点) +t+ 9.0s ♪ 音效 sfx/inst_kick +t+ 9.6s ▶ 语音:「这次是左和右。跟着打,左滑,右滑。」 +t+ 11.8s 【状态】教学第 2/3 句 教学:听领奏,下一小节照样打(left→right)(无 BGM,语速1) +t+ 14.0s 〰 震动:beat(节拍点) +t+ 15.3s 〰 震动:beat(节拍点) +t+ 19.0s ▶ 语音:「再听一遍,跟着来。」 +t+ 19.0s 〰 震动:error(做错了:两连短震) +t+ 19.0s 【状态】第一遍没敢出手,先听它归因 教学:听领奏,下一小节照样打(left→right)(语音播放中,语速1) +t+ 21.1s ▶ 语音:「再听一遍,跟着来。」 +t+ 23.2s ▶ 向导语音:「慢了半拍。跟着节拍走。」 +t+ 23.2s 【状态】又重新领奏了一遍,还是没敢出手 教学:听领奏,下一小节照样打(left→right)(语音播放中,语速1) +t+ 24.7s 〰 震动:beat(节拍点) +t+ 26.0s 〰 震动:beat(节拍点) +t+ 29.6s ▶ 向导语音:「我放慢一些,跟着试试。」 +t+ 29.6s 〰 震动:error(做错了:两连短震) +t+ 31.8s 【状态】听到「我放慢一些,跟着试试」——领奏降速 25% 重演,这回跟着慢拍打 教学:听领奏,下一小节照样打(left→right)(领奏已放慢 25%)(无 BGM,语速1) +t+ 35.3s 〰 震动:beat(节拍点) +t+ 37.1s 〰 震动:beat(节拍点) +t+ 38.9s ♪ 音效 sfx/inst_hat_l +t+ 40.6s ♪ 音效 sfx/inst_hat_r +t+ 41.6s ▶ 语音:「最后一句,三个音,中间是双击。」 +t+ 43.8s 【状态】教学第 3/3 句 教学:听领奏,下一小节照样打(tap→doubletap→tap)(无 BGM,语速1) +t+ 46.0s 〰 震动:beat(节拍点) +t+ 46.7s 〰 震动:beat(节拍点) +t+ 47.3s 〰 震动:beat(节拍点) +t+ 49.0s ♪ 音效 sfx/inst_kick +t+ 49.3s ♪ 音效 sfx/inst_snare +t+ 50.3s ♪ 音效 sfx/inst_kick +t+ 51.0s ▶ 语音:「很好,演出开始。」 +t+ 53.1s ♪ 向导音:battle(战斗/对抗) +t+ 53.1s 【状态】教学完毕,曲目一《启程》90 拍开始。领奏响之前先听到「现在跟着我打」 演奏中(启程):还剩 31 个应答音。领奏停了、轮到空拍,就该我出手了(无 BGM,语速1) +t+ 55.6s ♪ 向导音:menu(系统界面) +t+ 55.6s ▶ 语音:「菜单。单击切换选项,双击确认。」 +t+ 55.6s 【状态】曲中暂停,进了菜单 暂停菜单:单击切选项,双击确认,上滑帮助,下滑恢复演奏(语音播放中,语速1) +t+ 55.6s ▶ 语音:「回大厅。」 #### 【玩家动作】还是想打完这首,下滑回去 -t+ 87.1s ……… 静默 5s(还在数拍子,第一句没敢出手) ……… +t+ 61.0s ▶ 向导语音:「四拍之后,继续。」 +t+ 61.0s 【状态】听到「四拍之后,继续」,跟着四下底鼓数拍进来了 演奏中(启程):还剩 31 个应答音。领奏停了、轮到空拍,就该我出手了(语音播放中,语速1) +t+ 61.0s ……… 静默 5s(还在数拍子,第一句没敢出手) ……… +t+ 63.2s 〰 震动:beat(节拍点) +t+ 63.8s 〰 震动:beat(节拍点) +t+ 64.5s 〰 震动:beat(节拍点) +t+ 65.2s 〰 震动:beat(节拍点) +t+ 67.0s ▶ 向导语音:「现在跟着我打。」 +t+ 67.0s ♪ 向导音:turn(轮到你) +t+ 67.0s 〰 震动:beat(节拍点) +t+ 68.3s 〰 震动:beat(节拍点) +t+ 70.3s 〰 震动:error(做错了:两连短震) +t+ 71.6s ▶ 向导语音:「慢了半拍,下一小节跟上我就行。」 +t+ 71.6s 〰 震动:error(做错了:两连短震) +t+ 71.6s 【状态】第一句全漏了,听到「慢了半拍,下一小节跟上我就行」 演奏中(启程):还剩 29 个应答音。领奏停了、轮到空拍,就该我出手了(语音播放中,语速1) +t+ 75.0s 〰 震动:beat(节拍点) +t+ 76.3s 〰 震动:beat(节拍点) +t+ 77.6s ♪ 音效 sfx/inst_hat_l +t+ 77.6s ♪ 音效 sfx/inst_accent +t+ 79.0s ♪ 音效 sfx/inst_hat_r +t+ 79.0s ♪ 音效 sfx/inst_accent +t+ 79.0s 〰 震动:自定义震型 [20,40,20] +t+ 83.0s 〰 震动:beat(节拍点) +t+ 83.7s 〰 震动:beat(节拍点) +t+ 84.3s 〰 震动:beat(节拍点) +t+ 86.0s ♪ 音效 sfx/inst_kick +t+ 86.0s ♪ 音效 sfx/inst_accent +t+ 86.3s ♪ 音效 sfx/inst_snare +t+ 86.3s ♪ 音效 sfx/inst_accent +t+ 87.3s ♪ 音效 sfx/inst_kick +t+ 87.3s ♪ 音效 sfx/inst_accent +t+ 87.3s 〰 震动:自定义震型 [20,40,20] t+ 91.0s 〰 震动:beat(节拍点) +t+ 91.7s 〰 震动:beat(节拍点) t+ 92.3s 〰 震动:beat(节拍点) -t+ 93.7s ▶ 向导语音:「现在跟着我打。」 -t+ 93.7s ♪ 向导音:turn(轮到你) -t+ 94.3s 〰 震动:error(做错了:两连短震) -t+ 95.6s ▶ 向导语音(对白在播,本句按 idle-only 跳过未播):「慢了半拍,下一小节跟上我就行。」 -t+ 95.6s 〰 震动:error(做错了:两连短震) -t+ 95.6s 【状态】第一句全漏了,听到「慢了半拍,下一小节跟上我就行」 演奏中(启程):还剩 29 个应答音。领奏停了、轮到空拍,就该我出手了(语音播放中,语速1) +t+ 93.6s ♪ 音效 sfx/inst_hat_l +t+ 93.6s ♪ 音效 sfx/inst_accent +t+ 94.3s ♪ 音效 sfx/inst_snare +t+ 94.3s ♪ 音效 sfx/inst_accent +t+ 95.0s ♪ 音效 sfx/inst_hat_r +t+ 95.0s ♪ 音效 sfx/inst_accent +t+ 95.0s 〰 震动:自定义震型 [20,40,20] t+ 99.0s 〰 震动:beat(节拍点) t+ 100.3s 〰 震动:beat(节拍点) -t+ 101.6s ♪ 音效 sfx/inst_hat_l -t+ 101.6s ♪ 音效 sfx/inst_accent -t+ 103.0s ♪ 音效 sfx/inst_hat_r +t+ 101.0s 〰 震动:beat(节拍点) +t+ 102.0s ♪ 音效 sfx/inst_kick +t+ 102.0s ♪ 音效 sfx/inst_accent +t+ 103.0s ♪ 音效 sfx/inst_hat_l t+ 103.0s ♪ 音效 sfx/inst_accent -t+ 103.0s 〰 震动:自定义震型 [20,40,20] -t+ 107.0s 〰 震动:beat(节拍点) -t+ 107.7s 〰 震动:beat(节拍点) -t+ 108.3s 〰 震动:beat(节拍点) -t+ 110.0s ♪ 音效 sfx/inst_kick -t+ 110.0s ♪ 音效 sfx/inst_accent -t+ 110.3s ♪ 音效 sfx/inst_snare -t+ 110.3s ♪ 音效 sfx/inst_accent -t+ 111.3s ♪ 音效 sfx/inst_kick -t+ 111.3s ♪ 音效 sfx/inst_accent -t+ 111.3s 〰 震动:自定义震型 [20,40,20] +t+ 103.6s ♪ 音效 sfx/inst_snare +t+ 103.6s ♪ 音效 sfx/inst_accent +t+ 103.6s 〰 震动:自定义震型 [20,40,20] +t+ 104.4s ▶ 语音:「过半了,保持。」 +t+ 104.3s 〰 震动:beat(节拍点) +t+ 105.7s 〰 震动:beat(节拍点) +t+ 106.3s 〰 震动:beat(节拍点) +t+ 107.0s ♪ 音效 sfx/inst_hat_r +t+ 107.0s ♪ 音效 sfx/inst_accent +t+ 108.6s ♪ 音效 sfx/inst_kick +t+ 108.6s ♪ 音效 sfx/inst_accent +t+ 109.0s ♪ 音效 sfx/inst_snare +t+ 109.0s ♪ 音效 sfx/inst_accent +t+ 109.0s 〰 震动:自定义震型 [20,40,20] +t+ 109.7s 〰 震动:beat(节拍点) +t+ 111.0s 〰 震动:beat(节拍点) +t+ 111.7s 〰 震动:beat(节拍点) +t+ 112.3s ♪ 音效 sfx/inst_tom_hi +t+ 112.3s ♪ 音效 sfx/inst_accent +t+ 113.6s ♪ 音效 sfx/inst_tom_lo +t+ 113.6s ♪ 音效 sfx/inst_accent +t+ 113.6s 〰 震动:success(成功长震) +t+ 114.3s ♪ 音效 sfx/inst_snare +t+ 114.3s ♪ 音效 sfx/inst_accent +t+ 114.3s 〰 震动:自定义震型 [20,40,20] t+ 115.0s 〰 震动:beat(节拍点) t+ 115.7s 〰 震动:beat(节拍点) t+ 116.3s 〰 震动:beat(节拍点) -t+ 117.6s ♪ 音效 sfx/inst_hat_l -t+ 117.6s ♪ 音效 sfx/inst_accent -t+ 118.3s ♪ 音效 sfx/inst_snare +t+ 117.0s 〰 震动:beat(节拍点) +t+ 118.0s ♪ 音效 sfx/inst_kick +t+ 118.0s ♪ 音效 sfx/inst_accent +t+ 118.3s ♪ 音效 sfx/inst_tom_hi t+ 118.3s ♪ 音效 sfx/inst_accent t+ 119.0s ♪ 音效 sfx/inst_hat_r t+ 119.0s ♪ 音效 sfx/inst_accent -t+ 119.0s 〰 震动:自定义震型 [20,40,20] -t+ 123.0s 〰 震动:beat(节拍点) -t+ 124.3s 〰 震动:beat(节拍点) -t+ 125.0s 〰 震动:beat(节拍点) -t+ 126.0s ♪ 音效 sfx/inst_kick -t+ 126.0s ♪ 音效 sfx/inst_accent -t+ 127.0s ♪ 音效 sfx/inst_hat_l -t+ 127.0s ♪ 音效 sfx/inst_accent -t+ 127.6s ♪ 音效 sfx/inst_snare -t+ 127.6s ♪ 音效 sfx/inst_accent -t+ 127.6s 〰 震动:自定义震型 [20,40,20] -t+ 128.4s ▶ 语音:「过半了,保持。」 -t+ 128.3s 〰 震动:beat(节拍点) -t+ 129.7s 〰 震动:beat(节拍点) -t+ 130.3s 〰 震动:beat(节拍点) -t+ 131.0s ♪ 音效 sfx/inst_hat_r -t+ 131.0s ♪ 音效 sfx/inst_accent -t+ 132.6s ♪ 音效 sfx/inst_kick -t+ 132.6s ♪ 音效 sfx/inst_accent -t+ 133.0s ♪ 音效 sfx/inst_snare -t+ 133.0s ♪ 音效 sfx/inst_accent -t+ 133.0s 〰 震动:自定义震型 [20,40,20] -t+ 133.7s 〰 震动:beat(节拍点) -t+ 135.0s 〰 震动:beat(节拍点) -t+ 135.7s 〰 震动:beat(节拍点) -t+ 136.3s ♪ 音效 sfx/inst_tom_hi -t+ 136.3s ♪ 音效 sfx/inst_accent -t+ 137.6s ♪ 音效 sfx/inst_tom_lo -t+ 137.6s ♪ 音效 sfx/inst_accent -t+ 137.6s 〰 震动:success(成功长震) -t+ 138.3s ♪ 音效 sfx/inst_snare -t+ 138.3s ♪ 音效 sfx/inst_accent -t+ 138.3s 〰 震动:自定义震型 [20,40,20] -t+ 139.0s 〰 震动:beat(节拍点) -t+ 139.7s 〰 震动:beat(节拍点) -t+ 140.3s 〰 震动:beat(节拍点) -t+ 141.0s 〰 震动:beat(节拍点) -t+ 142.0s ♪ 音效 sfx/inst_kick -t+ 142.0s ♪ 音效 sfx/inst_accent -t+ 142.3s ♪ 音效 sfx/inst_tom_hi -t+ 142.3s ♪ 音效 sfx/inst_accent -t+ 143.0s ♪ 音效 sfx/inst_hat_r -t+ 143.0s ♪ 音效 sfx/inst_accent -t+ 143.6s ♪ 音效 sfx/inst_snare -t+ 143.6s ♪ 音效 sfx/inst_accent -t+ 143.6s 〰 震动:自定义震型 [20,40,20] -t+ 144.3s 〰 震动:beat(节拍点) -t+ 145.0s 〰 震动:beat(节拍点) -t+ 145.7s 〰 震动:beat(节拍点) -t+ 146.3s 〰 震动:beat(节拍点) -t+ 147.0s ♪ 音效 sfx/inst_hat_l -t+ 147.0s ♪ 音效 sfx/inst_accent -t+ 147.6s ♪ 音效 sfx/inst_hat_r -t+ 147.6s ♪ 音效 sfx/inst_accent -t+ 148.6s ♪ 音效 sfx/inst_kick -t+ 148.6s ♪ 音效 sfx/inst_accent -t+ 149.0s ♪ 音效 sfx/inst_snare -t+ 149.0s ♪ 音效 sfx/inst_accent -t+ 149.0s 〰 震动:自定义震型 [20,40,20] -t+ 149.7s 〰 震动:beat(节拍点) -t+ 150.3s 〰 震动:beat(节拍点) -t+ 151.0s 〰 震动:beat(节拍点) -t+ 151.1s 〰 震动:beat(节拍点) -t+ 151.1s 〰 震动:beat(节拍点) -t+ 151.1s 〰 震动:beat(节拍点) -t+ 151.1s 〰 震动:beat(节拍点) -t+ 151.7s 〰 震动:beat(节拍点) -t+ 152.6s ♪ 音效 sfx/inst_kick -t+ 152.6s ♪ 音效 sfx/inst_accent -t+ 153.0s ♪ 音效 sfx/inst_snare -t+ 153.0s ♪ 音效 sfx/inst_accent -t+ 154.0s ♪ 音效 sfx/inst_kick -t+ 154.0s ♪ 音效 sfx/inst_accent -t+ 154.3s ♪ 音效 sfx/inst_snare -t+ 154.3s ♪ 音效 sfx/inst_accent -t+ 154.3s 〰 震动:自定义震型 [20,40,20] -t+ 155.4s ♪ 向导音:settle(结算) -t+ 155.4s ▶ 语音:「A 级!准确率超过八成五,非常出色。」 -t+ 155.4s 〰 震动:success(成功长震) -t+ 155.4s 〰 震动:success(成功长震) -t+ 155.4s 〰 震动:自定义震型 [20,40,20] -t+ 157.5s ▶ 语音:「新连击纪录!」 -t+ 159.6s ▶ 语音:「新曲目解锁,追风!」 -t+ 161.8s ▶ 语音:「单击再来一遍,右滑下一首,下滑回大厅。」 -t+ 163.9s ♫ BGM 切换 → bgm/menu(淡入 800ms) -t+ 165.4s 【状态】曲子打完了,结算播报中 结算播报中:听完单击再来一遍,右滑下一首,下滑回大厅(BGM=bgm/menu,语速1) +t+ 119.6s ♪ 音效 sfx/inst_snare +t+ 119.6s ♪ 音效 sfx/inst_accent +t+ 119.6s 〰 震动:自定义震型 [20,40,20] +t+ 120.3s 〰 震动:beat(节拍点) +t+ 121.0s 〰 震动:beat(节拍点) +t+ 121.7s 〰 震动:beat(节拍点) +t+ 122.3s 〰 震动:beat(节拍点) +t+ 123.0s ♪ 音效 sfx/inst_hat_l +t+ 123.0s ♪ 音效 sfx/inst_accent +t+ 123.6s ♪ 音效 sfx/inst_hat_r +t+ 123.6s ♪ 音效 sfx/inst_accent +t+ 124.6s ♪ 音效 sfx/inst_kick +t+ 124.6s ♪ 音效 sfx/inst_accent +t+ 125.0s ♪ 音效 sfx/inst_snare +t+ 125.0s ♪ 音效 sfx/inst_accent +t+ 125.0s 〰 震动:自定义震型 [20,40,20] +t+ 125.7s 〰 震动:beat(节拍点) +t+ 126.3s 〰 震动:beat(节拍点) +t+ 127.0s 〰 震动:beat(节拍点) +t+ 127.7s 〰 震动:beat(节拍点) +t+ 128.6s ♪ 音效 sfx/inst_kick +t+ 128.6s ♪ 音效 sfx/inst_accent +t+ 129.0s ♪ 音效 sfx/inst_snare +t+ 129.0s ♪ 音效 sfx/inst_accent +t+ 130.0s ♪ 音效 sfx/inst_kick +t+ 130.0s ♪ 音效 sfx/inst_accent +t+ 130.3s ♪ 音效 sfx/inst_snare +t+ 130.3s ♪ 音效 sfx/inst_accent +t+ 130.3s 〰 震动:自定义震型 [20,40,20] +t+ 131.4s ♪ 向导音:settle(结算) +t+ 131.4s ▶ 语音:「A 级!准确率超过八成五,非常出色。」 +t+ 131.4s 〰 震动:success(成功长震) +t+ 131.4s 〰 震动:success(成功长震) +t+ 131.4s 〰 震动:自定义震型 [20,40,20] +t+ 133.5s ▶ 语音:「新连击纪录!」 +t+ 135.6s ▶ 语音:「新曲目解锁,追风!」 +t+ 137.8s ▶ 语音:「单击再来一遍,右滑下一首,下滑回大厅。」 +t+ 139.9s ♫ BGM 切换 → bgm/menu(淡入 800ms) +t+ 141.4s 【状态】曲子打完了,结算播报中 结算播报中:听完单击再来一遍,右滑下一首,下滑回大厅(BGM=bgm/menu,语速1) diff --git a/research/04-playtests/transcripts/simon.md b/research/04-playtests/transcripts/simon.md index f899069e..3c0ecfca 100644 --- a/research/04-playtests/transcripts/simon.md +++ b/research/04-playtests/transcripts/simon.md @@ -49,75 +49,75 @@ t+ 47.7s 【状态】教学第 6/6 个音色 教学:该做「双击」了( t+ 47.7s ♪ 音效 sfx/tone_doubletap t+ 47.7s ▶ 语音:「对了。」 t+ 49.8s ▶ 语音:「六种声音都记住了。后面的序列,会越来越长。」 -t+ 51.9s ▶ 语音:「答错可以消耗机会重听。双击,可以随时重听。」 -t+ 54.0s ▶ 向导语音:「记不住就双击重新听,免费机会有两次,用完要扣一次机会。」 +t+ 51.9s ▶ 语音:「答错可以消耗机会重听。向上滑,可以随时重听。」 +t+ 54.0s ▶ 向导语音:「记不住就向上滑,重新听一遍。免费机会有两次,用完要扣一次机会。」 t+ 56.2s ▶ 语音:「第一轮,听好了。」 -t+ 58.3s ♪ 音效 sfx/tone_doubletap +t+ 58.3s ♪ 音效 sfx/tone_tap t+ 58.3s 〰 震动:beat(节拍点) -t+ 58.3s 【状态】教学讲完了,机会经济也交代清楚了:免费重听两次,用完要扣机会 第 1 轮序列演奏中(2 个音),记住顺序,先别动手(无 BGM,语速1) -t+ 59.0s ♪ 音效 sfx/tone_up +t+ 58.3s 【状态】教学讲完了:免费重听两次、用完扣机会,想重听就向上滑 第 1 轮序列演奏中(2 个音),记住顺序,先别动手(无 BGM,语速1) +t+ 59.0s ♪ 音效 sfx/tone_doubletap t+ 59.0s 〰 震动:beat(节拍点) t+ 60.1s ♪ 向导音:turn(轮到你) t+ 60.1s ▶ 语音:「轮到你了。」 t+ 60.1s 〰 震动:confirm(轻点确认) -t+ 62.2s 【状态】轮到我复现了 第 1 轮轮到你了:已对上 0/2,照原顺序做手势(无 BGM,语速1) -t+ 62.2s ♪ 音效 sfx/tone_doubletap -t+ 62.2s 【状态】轮到我复现了 第 1 轮轮到你了:已对上 1/2,照原顺序做手势(无 BGM,语速1) -t+ 62.2s ♪ 音效 sfx/tone_up -t+ 62.2s 〰 震动:success(成功长震) -t+ 62.5s ▶ 语音:「第二轮,听好了。」 -t+ 64.6s ♪ 音效 sfx/tone_doubletap -t+ 64.6s 〰 震动:beat(节拍点) -t+ 65.3s ♪ 音效 sfx/tone_up -t+ 65.3s 〰 震动:beat(节拍点) -t+ 66.0s ♪ 音效 sfx/tone_doubletap -t+ 66.0s 〰 震动:beat(节拍点) -t+ 67.0s ♪ 向导音:turn(轮到你) -t+ 67.0s 〰 震动:confirm(轻点确认) -t+ 67.0s 【状态】轮到我复现了 第 2 轮轮到你了:已对上 0/3,照原顺序做手势(无 BGM,语速1) -t+ 67.0s ♪ 音效 sfx/tone_doubletap -t+ 67.0s 【状态】序列有点长,先僵一会儿 第 2 轮轮到你了:已对上 1/3,照原顺序做手势(无 BGM,语速1) -t+ 67.0s ……… 静默 10s(想不起来序列了) ……… -t+ 72.2s 【状态】听到提示:需要的话,双击可以重新听一遍序列 第 2 轮轮到你了:已对上 1/3,照原顺序做手势(无 BGM,语速1) +t+ 62.2s 【状态】第 1 轮有点懵,先僵一会儿 第 1 轮轮到你了:已对上 0/2,照原顺序做手势(双击就是双击那个音,要重听就向上滑)(无 BGM,语速1) +t+ 62.2s ……… 静默 10s(想不起来序列了) ……… +t+ 72.2s ♪ 向导音:nudge(看门狗轻提醒) +t+ 72.2s ▶ 向导语音:「需要的话,向上滑可以重新听一遍序列。」 +t+ 72.2s 【状态】听到提示:需要的话,向上滑可以重新听一遍序列 第 1 轮轮到你了:已对上 0/2,照原顺序做手势(双击就是双击那个音,要重听就向上滑)(语音播放中,语速1) -#### 【玩家动作】照提示双击,用掉一次免费重听 +#### 【玩家动作】照提示向上滑,用掉一次免费重听 t+ 72.2s ▶ 语音:「再听一遍。」 t+ 72.2s 〰 震动:pickup(获得) t+ 74.3s ▶ 语音:「重听机会用完了,小心。」 -t+ 76.4s ♪ 音效 sfx/tone_doubletap +t+ 76.4s ♪ 音效 sfx/tone_tap t+ 76.4s 〰 震动:beat(节拍点) -t+ 77.1s ♪ 音效 sfx/tone_up -t+ 77.8s ♪ 音效 sfx/tone_doubletap +t+ 77.1s ♪ 音效 sfx/tone_doubletap t+ 77.1s 〰 震动:beat(节拍点) -t+ 77.8s 〰 震动:beat(节拍点) -t+ 78.9s ♪ 向导音:turn(轮到你) -t+ 78.9s 〰 震动:confirm(轻点确认) -t+ 78.9s 【状态】轮到我复现了 第 2 轮轮到你了:已对上 0/3,照原顺序做手势(无 BGM,语速1) -t+ 78.9s ♪ 音效 sfx/tone_doubletap -t+ 78.9s 【状态】轮到我复现了 第 2 轮轮到你了:已对上 1/3,照原顺序做手势(无 BGM,语速1) -t+ 78.9s ♪ 音效 sfx/tone_up -t+ 78.9s 【状态】轮到我复现了 第 2 轮轮到你了:已对上 2/3,照原顺序做手势(无 BGM,语速1) -t+ 78.9s ♪ 音效 sfx/tone_doubletap -t+ 78.9s 〰 震动:success(成功长震) -t+ 79.2s ▶ 语音:「第三轮,听好了。」 -t+ 81.3s ♪ 音效 sfx/tone_doubletap -t+ 81.3s 〰 震动:beat(节拍点) -t+ 81.9s ♪ 音效 sfx/tone_up -t+ 81.9s 〰 震动:beat(节拍点) -t+ 82.6s ♪ 音效 sfx/tone_doubletap -t+ 82.6s 〰 震动:beat(节拍点) -t+ 83.2s ♪ 音效 sfx/tone_up -t+ 83.2s 〰 震动:beat(节拍点) -t+ 84.3s ♪ 向导音:turn(轮到你) -t+ 84.3s 〰 震动:confirm(轻点确认) -t+ 84.3s 【状态】轮到我复现了 第 3 轮轮到你了:已对上 0/4,照原顺序做手势(无 BGM,语速1) -t+ 84.3s ♪ 音效 sfx/tone_doubletap -t+ 84.3s 【状态】轮到我复现了 第 3 轮轮到你了:已对上 1/4,照原顺序做手势(无 BGM,语速1) -t+ 84.3s ♪ 音效 sfx/tone_up -t+ 84.3s 【状态】轮到我复现了 第 3 轮轮到你了:已对上 2/4,照原顺序做手势(无 BGM,语速1) -t+ 84.3s ♪ 音效 sfx/tone_doubletap -t+ 84.3s 【状态】最后一轮最后一个音,打完这轮就收 第 3 轮轮到你了:已对上 3/4,照原顺序做手势(无 BGM,语速1) -t+ 84.3s ♪ 音效 sfx/tone_up -t+ 84.3s 〰 震动:success(成功长震) -t+ 84.3s 【状态】收工:完整打完 3 轮,在轮与轮的边界停手(免费重听剩 0 次) 刚答完一轮,播报中(无 BGM,语速1) +t+ 78.2s ♪ 向导音:turn(轮到你) +t+ 78.2s ▶ 语音:「轮到你了。」 +t+ 78.2s 〰 震动:confirm(轻点确认) +t+ 80.4s 【状态】轮到我复现了 第 1 轮轮到你了:已对上 0/2,照原顺序做手势(双击就是双击那个音,要重听就向上滑)(无 BGM,语速1) +t+ 80.4s ♪ 音效 sfx/tone_tap +t+ 80.4s 【状态】轮到我复现了 第 1 轮轮到你了:已对上 1/2,照原顺序做手势(双击就是双击那个音,要重听就向上滑)(无 BGM,语速1) +t+ 80.4s ♪ 音效 sfx/tone_doubletap +t+ 80.4s ▶ 向导语音:「漂亮,过了。」 +t+ 80.4s 〰 震动:success(成功长震) +t+ 82.8s ▶ 语音:「第二轮,听好了。」 +t+ 84.9s ♪ 音效 sfx/tone_tap +t+ 84.9s 〰 震动:beat(节拍点) +t+ 85.6s ♪ 音效 sfx/tone_doubletap +t+ 85.6s 〰 震动:beat(节拍点) +t+ 86.2s ♪ 音效 sfx/tone_up +t+ 86.2s 〰 震动:beat(节拍点) +t+ 87.3s ♪ 向导音:turn(轮到你) +t+ 87.3s 〰 震动:confirm(轻点确认) +t+ 87.3s 【状态】这个是上行音——上滑作答(期望恰为 up 时上滑=作答) 第 2 轮轮到你了:已对上 0/3,照原顺序做手势(双击就是双击那个音,要重听就向上滑)(无 BGM,语速1) +t+ 87.3s ♪ 音效 sfx/tone_up +t+ 87.3s 【状态】轮到我复现了 第 2 轮轮到你了:已对上 1/3,照原顺序做手势(双击就是双击那个音,要重听就向上滑)(无 BGM,语速1) +t+ 87.3s ♪ 音效 sfx/tone_doubletap +t+ 87.3s 【状态】轮到我复现了 第 2 轮轮到你了:已对上 2/3,照原顺序做手势(双击就是双击那个音,要重听就向上滑)(无 BGM,语速1) +t+ 87.3s ♪ 音效 sfx/tone_up +t+ 87.3s 〰 震动:success(成功长震) +t+ 87.6s ▶ 语音:「第三轮,听好了。」 +t+ 89.7s ♪ 音效 sfx/tone_up +t+ 89.7s 〰 震动:beat(节拍点) +t+ 90.4s ♪ 音效 sfx/tone_doubletap +t+ 90.4s 〰 震动:beat(节拍点) +t+ 91.0s ♪ 音效 sfx/tone_up +t+ 91.7s ♪ 音效 sfx/tone_right +t+ 91.0s 〰 震动:beat(节拍点) +t+ 91.7s 〰 震动:beat(节拍点) +t+ 92.7s ♪ 向导音:turn(轮到你) +t+ 92.7s 〰 震动:confirm(轻点确认) +t+ 92.7s 【状态】轮到我复现了 第 3 轮轮到你了:已对上 0/4,照原顺序做手势(双击就是双击那个音,要重听就向上滑)(无 BGM,语速1) +t+ 92.7s ♪ 音效 sfx/tone_up +t+ 92.7s 【状态】轮到我复现了 第 3 轮轮到你了:已对上 1/4,照原顺序做手势(双击就是双击那个音,要重听就向上滑)(无 BGM,语速1) +t+ 92.7s ♪ 音效 sfx/tone_doubletap +t+ 92.7s 【状态】轮到我复现了 第 3 轮轮到你了:已对上 2/4,照原顺序做手势(双击就是双击那个音,要重听就向上滑)(无 BGM,语速1) +t+ 92.7s ♪ 音效 sfx/tone_up +t+ 92.7s 【状态】这个是双击音——双击作答(round3:input 双击永远=作答) 第 3 轮轮到你了:已对上 3/4,照原顺序做手势(双击就是双击那个音,要重听就向上滑)(无 BGM,语速1) +t+ 92.7s ♪ 音效 sfx/tone_doubletap +t+ 92.7s 〰 震动:success(成功长震) +t+ 92.7s 【状态】收工:完整打完 3 轮,在轮与轮的边界停手(免费重听剩 0 次) 刚答完一轮,播报中(无 BGM,语速1) diff --git a/research/04-playtests/transcripts/space.md b/research/04-playtests/transcripts/space.md index 01e4976e..0e400397 100644 --- a/research/04-playtests/transcripts/space.md +++ b/research/04-playtests/transcripts/space.md @@ -48,31 +48,47 @@ t+ 25.7s 【状态】演练做完了,要出发了 演练旁白在播,先 t+ 27.8s ♫ BGM 切换 → bgm/engine t+ 27.8s ♪ 向导音:battle(战斗/对抗) t+ 27.8s 【状态】出发。引擎声起来了,保护期里先练手 对局中:引擎声平稳,等下一颗(保护期)(BGM=bgm/engine,语速1) -t+ 29.3s ♪ 音效 sfx/whoosh_left +t+ 29.3s ♪ 音效 sfx/whoosh_up t+ 32.3s ♪ 音效 sfx/alarm -t+ 32.3s 〰 震动:danger(危险逼近) t+ 32.8s ♪ 音效 sfx/alarm +t+ 32.8s ▶ 语音:「上!」 +t+ 32.3s 〰 震动:danger(危险逼近) t+ 32.8s 〰 震动:danger(危险逼近) + +#### 【玩家动作】听到第二段警报和方向呼喊,同向滑开 + t+ 33.3s ♪ 音效 sfx/dodge -t+ 33.3s ♪ 音效 sfx/whoosh_up +t+ 33.3s ♪ 音效 sfx/whoosh_down t+ 36.3s ♪ 音效 sfx/alarm -t+ 36.3s 〰 震动:danger(危险逼近) t+ 36.8s ♪ 音效 sfx/alarm +t+ 36.8s ▶ 语音:「下!」 +t+ 36.3s 〰 震动:danger(危险逼近) t+ 36.8s 〰 震动:danger(危险逼近) + +#### 【玩家动作】听到第二段警报和方向呼喊,同向滑开 + t+ 37.3s ♪ 音效 sfx/dodge -t+ 37.3s ♪ 音效 sfx/whoosh_right +t+ 37.3s ♪ 音效 sfx/whoosh_left t+ 40.3s ♪ 音效 sfx/alarm -t+ 40.3s 〰 震动:danger(危险逼近) t+ 40.8s ♪ 音效 sfx/alarm +t+ 40.8s ▶ 语音:「左!」 +t+ 40.3s 〰 震动:danger(危险逼近) t+ 40.8s 〰 震动:danger(危险逼近) + +#### 【玩家动作】听到第二段警报和方向呼喊,同向滑开 + t+ 41.3s ♪ 音效 sfx/dodge -t+ 41.3s ♪ 音效 sfx/whoosh_down +t+ 41.3s ♪ 音效 sfx/whoosh_right t+ 44.3s ♪ 音效 sfx/alarm -t+ 44.3s 〰 震动:danger(危险逼近) t+ 44.8s ♪ 音效 sfx/alarm +t+ 44.8s ▶ 语音:「右!」 +t+ 44.3s 〰 震动:danger(危险逼近) t+ 44.8s 〰 震动:danger(危险逼近) + +#### 【玩家动作】听到第二段警报和方向呼喊,同向滑开 + t+ 45.3s ♪ 音效 sfx/dodge -t+ 45.3s ♪ 音效 sfx/whoosh_up +t+ 45.3s ♪ 音效 sfx/whoosh_left t+ 47.8s ▶ 语音:「试试单击,引擎会短促加速,直接冲过空隙。」 t+ 47.8s 【状态】游戏停下来教新功能 暂停了刷怪教新功能:单击试试加速(语音播放中,语速1) @@ -80,37 +96,57 @@ t+ 47.8s 【状态】游戏停下来教新功能 暂停了刷怪教新功能 t+ 49.9s ♪ 音效 sfx/boost t+ 49.9s ▶ 语音:「感觉到了吗?加速的时候,陨石撞不上你。」 -t+ 52.4s ♪ 音效 sfx/whoosh_left +t+ 52.4s ♪ 音效 sfx/whoosh_up t+ 55.4s ♪ 音效 sfx/alarm -t+ 55.4s 〰 震动:danger(危险逼近) t+ 55.9s ♪ 音效 sfx/alarm +t+ 55.9s ▶ 语音:「上!」 +t+ 55.4s 〰 震动:danger(危险逼近) t+ 55.9s 〰 震动:danger(危险逼近) + +#### 【玩家动作】听到第二段警报和方向呼喊,同向滑开 + t+ 56.4s ♪ 音效 sfx/dodge -t+ 56.4s ♪ 音效 sfx/whoosh_left +t+ 56.4s ♪ 音效 sfx/whoosh_right t+ 59.4s ♪ 音效 sfx/alarm -t+ 59.4s 〰 震动:danger(危险逼近) t+ 59.9s ♪ 音效 sfx/alarm +t+ 59.9s ▶ 语音:「右!」 +t+ 59.4s 〰 震动:danger(危险逼近) t+ 59.9s 〰 震动:danger(危险逼近) + +#### 【玩家动作】听到第二段警报和方向呼喊,同向滑开 + t+ 60.4s ♪ 音效 sfx/dodge -t+ 60.4s ♪ 音效 sfx/whoosh_left +t+ 60.4s ♪ 音效 sfx/whoosh_down t+ 63.4s ♪ 音效 sfx/alarm -t+ 63.4s 〰 震动:danger(危险逼近) t+ 63.9s ♪ 音效 sfx/alarm +t+ 63.9s ▶ 语音:「下!」 +t+ 63.4s 〰 震动:danger(危险逼近) t+ 63.9s 〰 震动:danger(危险逼近) + +#### 【玩家动作】听到第二段警报和方向呼喊,同向滑开 + t+ 64.4s ♪ 音效 sfx/dodge -t+ 64.4s ♪ 音效 sfx/whoosh_left +t+ 64.4s ♪ 音效 sfx/whoosh_down t+ 67.4s ♪ 音效 sfx/alarm -t+ 67.4s 〰 震动:danger(危险逼近) t+ 67.9s ♪ 音效 sfx/alarm +t+ 67.9s ▶ 语音:「下!」 +t+ 67.4s 〰 震动:danger(危险逼近) t+ 67.9s 〰 震动:danger(危险逼近) + +#### 【玩家动作】听到第二段警报和方向呼喊,同向滑开 + t+ 68.4s ♪ 音效 sfx/dodge t+ 68.4s ♪ 音效 sfx/whoosh_up t+ 71.4s ♪ 音效 sfx/alarm -t+ 71.4s 〰 震动:danger(危险逼近) t+ 71.9s ♪ 音效 sfx/alarm +t+ 71.9s ▶ 语音:「上!」 +t+ 71.4s 〰 震动:danger(危险逼近) t+ 71.9s 〰 震动:danger(危险逼近) + +#### 【玩家动作】听到第二段警报和方向呼喊,同向滑开 + t+ 72.4s ♪ 音效 sfx/dodge -t+ 72.4s ♪ 音效 sfx/whoosh_down +t+ 72.4s ♪ 音效 sfx/whoosh_left t+ 72.8s ▶ 语音:「双击展开护盾,能挡下一次撞击。」 t+ 72.8s 【状态】游戏停下来教新功能 暂停了刷怪教新功能:双击展开护盾(语音播放中,语速1) @@ -120,26 +156,35 @@ t+ 74.9s ♪ 音效 sfx/shield t+ 74.9s ▶ 语音:「护盾展开后会自动充能,好了我会告诉你。」 t+ 77.4s ♪ 音效 sfx/whoosh_right t+ 80.4s ♪ 音效 sfx/alarm -t+ 80.4s 〰 震动:danger(危险逼近) t+ 80.9s ♪ 音效 sfx/alarm +t+ 80.9s ▶ 语音:「右!」 +t+ 80.4s 〰 震动:danger(危险逼近) t+ 80.9s 〰 震动:danger(危险逼近) + +#### 【玩家动作】听到第二段警报和方向呼喊,同向滑开 + t+ 81.4s ♪ 音效 sfx/dodge t+ 81.4s ▶ 语音:「十颗了,稳。」 -t+ 81.4s ♪ 音效 sfx/whoosh_down +t+ 81.4s ♪ 音效 sfx/whoosh_right t+ 81.4s 〰 震动:confirm(轻点确认) t+ 84.4s ♪ 音效 sfx/alarm -t+ 84.4s 〰 震动:danger(危险逼近) t+ 84.9s ♪ 音效 sfx/alarm +t+ 84.9s ▶ 语音:「右!」 +t+ 84.4s 〰 震动:danger(危险逼近) t+ 84.9s 〰 震动:danger(危险逼近) + +#### 【玩家动作】听到第二段警报和方向呼喊,同向滑开 + t+ 85.4s ♪ 音效 sfx/dodge t+ 85.4s ♪ 音效 sfx/whoosh_right t+ 87.8s ▶ 语音:「训练护盾关闭。接下来,靠你自己了。」 t+ 87.8s 〰 震动:warning(警告三连震) t+ 88.4s ♪ 音效 sfx/alarm -t+ 88.4s 〰 震动:danger(危险逼近) -t+ 88.4s 【状态】保护期结束了,这颗我故意没动 对局中:1 颗陨石在逼近,听方位同向滑开(语音播放中,语速1) t+ 88.9s ♪ 音效 sfx/alarm +t+ 88.9s ▶ 语音:「右!」 +t+ 88.4s 〰 震动:danger(危险逼近) t+ 88.9s 〰 震动:danger(危险逼近) +t+ 88.9s 【状态】保护期结束了,这颗我故意没动 对局中:1 颗陨石在逼近,听方位同向滑开(语音播放中,语速1) t+ 89.4s ♪ 音效 sfx/hit t+ 89.4s ▶ 语音:「右边撞上的。听到右边的呼啸,向右滑。」 t+ 89.4s 〰 震动:hit(受击重震) @@ -148,52 +193,75 @@ t+ 89.4s 〰 震动:hit(受击重震) t+ 89.4s ♪ 音效 sfx/whoosh_up t+ 91.2s ♪ 音效 sfx/alarm -t+ 91.2s 〰 震动:danger(危险逼近) -t+ 91.2s 【状态】又有一颗,也故意不躲——想听听第二次被撞会说什么 对局中:1 颗陨石在逼近,听方位同向滑开(语音播放中,语速1) t+ 91.6s ▶ 向导语音:「被撞了。听方位,同向滑动就能拨开。」 t+ 91.7s ♪ 音效 sfx/alarm +t+ 91.7s ▶ 语音:「上!」 +t+ 91.2s 〰 震动:danger(危险逼近) t+ 91.7s 〰 震动:danger(危险逼近) +t+ 91.7s 【状态】又有一颗,也故意不躲——想听听第二次被撞会说什么 对局中:1 颗陨石在逼近,听方位同向滑开(语音播放中,语速1) t+ 92.2s ♪ 音效 sfx/hit t+ 92.2s ▶ 语音:「上面撞上的。听到高高的呼啸,向上滑。」 t+ 92.2s 〰 震动:hit(受击重震) #### 【玩家动作】第二次被撞:先听方位归因,又听到「这是最后一次机会,撑住」——这就是全部家底了 -t+ 92.6s ♪ 音效 sfx/whoosh_right +t+ 92.6s ♪ 音效 sfx/whoosh_left t+ 94.3s ▶ 语音:「船体只剩最后一次了,小心!」 t+ 94.4s ♪ 音效 sfx/alarm t+ 94.9s ♪ 音效 sfx/alarm +t+ 94.9s ▶ 语音:「左!」 t+ 94.4s 〰 震动:danger(危险逼近) t+ 94.9s 〰 震动:danger(危险逼近) + +#### 【玩家动作】听到第二段警报和方向呼喊,同向滑开 + t+ 95.4s ♪ 音效 sfx/dodge -t+ 95.7s ♪ 音效 sfx/whoosh_down -t+ 96.5s ▶ 向导语音:「这是最后一次机会,撑住。」 +t+ 95.7s ♪ 音效 sfx/whoosh_right t+ 97.5s ♪ 音效 sfx/alarm t+ 97.5s 〰 震动:danger(危险逼近) t+ 98.0s ♪ 音效 sfx/alarm +t+ 98.0s ▶ 语音:「右!」 +t+ 98.0s 〰 震动:danger(危险逼近) + +#### 【玩家动作】听到第二段警报和方向呼喊,同向滑开 + t+ 98.5s ♪ 音效 sfx/dodge t+ 98.8s ♪ 音效 sfx/whoosh_left -t+ 98.0s 〰 震动:danger(危险逼近) t+ 100.5s ♪ 音效 sfx/alarm t+ 100.5s 〰 震动:danger(危险逼近) t+ 101.0s ♪ 音效 sfx/alarm -t+ 101.5s ♪ 音效 sfx/dodge -t+ 101.8s ♪ 音效 sfx/whoosh_up +t+ 101.0s ▶ 语音:「左!」 t+ 101.0s 〰 震动:danger(危险逼近) + +#### 【玩家动作】听到第二段警报和方向呼喊,同向滑开 + +t+ 101.5s ♪ 音效 sfx/dodge +t+ 101.8s ♪ 音效 sfx/whoosh_left t+ 103.5s ♪ 音效 sfx/alarm t+ 103.5s 〰 震动:danger(危险逼近) t+ 104.0s ♪ 音效 sfx/alarm -t+ 104.5s ♪ 音效 sfx/dodge -t+ 104.8s ♪ 音效 sfx/whoosh_right -t+ 104.9s ▶ 语音:「护盾充能完毕。」 +t+ 104.0s ▶ 语音:「左!」 t+ 104.0s 〰 震动:danger(危险逼近) + +#### 【玩家动作】听到第二段警报和方向呼喊,同向滑开 + +t+ 104.5s ♪ 音效 sfx/dodge +t+ 104.8s ♪ 音效 sfx/whoosh_up +t+ 104.9s ▶ 语音:「护盾充能完毕。」 t+ 104.9s 〰 震动:pickup(获得) t+ 106.4s ♪ 音效 sfx/alarm -t+ 106.4s 〰 震动:danger(危险逼近) t+ 106.9s ♪ 音效 sfx/alarm +t+ 106.9s ▶ 语音:「上!」 +t+ 106.4s 〰 震动:danger(危险逼近) t+ 106.9s 〰 震动:danger(危险逼近) + +#### 【玩家动作】听到第二段警报和方向呼喊,同向滑开 + t+ 107.4s ♪ 音效 sfx/dodge -t+ 107.7s ♪ 音效 sfx/whoosh_down +t+ 107.7s ♪ 音效 sfx/whoosh_right t+ 109.3s ♪ 音效 sfx/alarm +t+ 109.8s ♪ 音效 sfx/alarm +t+ 109.8s ▶ 语音:「右!」 t+ 109.3s 〰 震动:danger(危险逼近) -t+ 109.3s 【状态】保护期结束后撑了 22 秒、挨了两下还活着(警报也只起一波了),先到这 对局中:1 颗陨石在逼近,听方位同向滑开(BGM=bgm/engine,语速1) +t+ 109.8s 〰 震动:danger(危险逼近) +t+ 109.8s 【状态】保护期结束后撑了 22 秒、挨了两下还活着;每回撞击前半秒都能听到方向呼喊,先到这 对局中:1 颗陨石在逼近,听方位同向滑开(语音播放中,语速1) diff --git a/tools/gen_voice_dual.py b/tools/gen_voice_dual.py index 5cc12484..ae18bf07 100644 --- a/tools/gen_voice_dual.py +++ b/tools/gen_voice_dual.py @@ -207,6 +207,8 @@ ESCAPE_LINES = [ ("menu_home", _ESC, "回大厅。"), ("menu_back", _ESC, "返回游戏。"), ("skip_hint", _ESC, "单击可跳过旁白。"), + # ---- 向导层 round3(docs/design/14-guide-layer.md「round3 v1.2」,synthesis §3 定稿全文)---- + ("gd_next_fuse", _ESC, "保险丝到手。接下来,去找电箱。"), ] @@ -240,7 +242,7 @@ SIMON_LINES = [ ("t_blunt_tap", _SIMON, "用指尖,轻轻点一下屏幕。"), ("t_blunt_double", _SIMON, "用指尖,快速点两下屏幕。"), ("t7_ready", _SIMON, "六种声音都记住了。后面的序列,会越来越长。"), - ("t7_retry", _SIMON, "答错可以消耗机会重听。双击,可以随时重听。"), + ("t7_retry", _SIMON, "答错可以消耗机会重听。向上滑,可以随时重听。"), ("t_skip", _SIMON, "跳过教学,直接开始。"), # ---- 轮次播报(整句,round_01..round_20 + 兜底) ---- *[(f"round_{i + 1:02d}", _SIMON, f"{w}轮,听好了。") for i, w in enumerate(_SIMON_ROUNDS)], @@ -273,9 +275,14 @@ SIMON_LINES = [ ("menu_back", _SIMON, "返回游戏。"), ("skip_hint", _SIMON, "单击可跳过旁白。"), # ---- 向导层(docs/design/14-guide-layer.md,schemes §1.5 定稿全文)---- - ("gd_relisten", _SIMON, "需要的话,双击可以重新听一遍序列。"), + ("gd_relisten", _SIMON, "需要的话,向上滑可以重新听一遍序列。"), # ---- 向导层 round2(docs/design/14-guide-layer.md「round2 v1.1」,synthesis §3 定稿全文)---- - ("gd_economy", _SIMON, "记不住就双击重新听,免费机会有两次,用完要扣一次机会。"), + # round3 G5 重录(14 号文档「round3 v1.2」):双击改回纯音色、重听改绑上滑, + # 机会经济句按裁定书新文案一字不改重录;教学链 t7_retry 同步手势口径。 + ("gd_economy", _SIMON, "记不住就向上滑,重新听一遍。免费机会有两次,用完要扣一次机会。"), + # ---- 向导层 round3(docs/design/14-guide-layer.md「round3 v1.2」,synthesis §3 定稿全文)---- + ("gd_clear", _SIMON, "漂亮,过了。"), + ("gd_record", _SIMON, "破纪录了。"), ] @@ -329,6 +336,9 @@ RHYTHM_LINES = [ ("gd_miss_early", _RHY, "抢拍了。等声音落下再滑。"), ("gd_miss_late", _RHY, "慢了半拍。跟着节拍走。"), ("gd_miss_wrong", _RHY, "方向不对。跟着音色滑。"), + # ---- 向导层 round3(docs/design/14-guide-layer.md「round3 v1.2」,synthesis §3 定稿全文)---- + ("gd_slow", _RHY, "我放慢一些,跟着试试。"), + ("gd_count", _RHY, "四拍之后,继续。"), ] @@ -401,6 +411,12 @@ SPACE_LINES = [ ("gd_hit_hint", _SPC, "被撞了。听方位,同向滑动就能拨开。"), # ---- 向导层 round2(docs/design/14-guide-layer.md「round2 v1.1」,synthesis §3 定稿全文)---- ("gd_last_life", _SPC, "这是最后一次机会,撑住。"), + # ---- 向导层 round3(docs/design/14-guide-layer.md「round3 v1.2」,synthesis §3 定稿全文)---- + # dir_* 为角色音风格超短呼喊,speaker 用本游戏旁白 pair(synthesis §3 表注)。 + ("dir_left", _SPC, "左!"), + ("dir_right", _SPC, "右!"), + ("dir_up", _SPC, "上!"), + ("dir_down", _SPC, "下!"), ] diff --git a/web/escape/audio/voice/female/again.ogg b/web/escape/audio/voice/female/again.ogg index 609d84f7..bbc34f60 100644 Binary files a/web/escape/audio/voice/female/again.ogg and b/web/escape/audio/voice/female/again.ogg differ diff --git a/web/escape/audio/voice/female/box_fixed.ogg b/web/escape/audio/voice/female/box_fixed.ogg index 6678f3df..ccf115cf 100644 Binary files a/web/escape/audio/voice/female/box_fixed.ogg and b/web/escape/audio/voice/female/box_fixed.ogg differ diff --git a/web/escape/audio/voice/female/empty_1.ogg b/web/escape/audio/voice/female/empty_1.ogg index 71f27087..9d0f0229 100644 Binary files a/web/escape/audio/voice/female/empty_1.ogg and b/web/escape/audio/voice/female/empty_1.ogg differ diff --git a/web/escape/audio/voice/female/empty_2.ogg b/web/escape/audio/voice/female/empty_2.ogg index 6f2ea5ff..3a2b0e76 100644 Binary files a/web/escape/audio/voice/female/empty_2.ogg and b/web/escape/audio/voice/female/empty_2.ogg differ diff --git a/web/escape/audio/voice/female/empty_3.ogg b/web/escape/audio/voice/female/empty_3.ogg index fcde5b6a..ad6ef599 100644 Binary files a/web/escape/audio/voice/female/empty_3.ogg and b/web/escape/audio/voice/female/empty_3.ogg differ diff --git a/web/escape/audio/voice/female/escape.ogg b/web/escape/audio/voice/female/escape.ogg index 343fcd29..73dd4b47 100644 Binary files a/web/escape/audio/voice/female/escape.ogg and b/web/escape/audio/voice/female/escape.ogg differ diff --git a/web/escape/audio/voice/female/fix_box.ogg b/web/escape/audio/voice/female/fix_box.ogg index 64cd849a..b6684966 100644 Binary files a/web/escape/audio/voice/female/fix_box.ogg and b/web/escape/audio/voice/female/fix_box.ogg differ diff --git a/web/escape/audio/voice/female/found_key.ogg b/web/escape/audio/voice/female/found_key.ogg index c1e8cda1..be441555 100644 Binary files a/web/escape/audio/voice/female/found_key.ogg and b/web/escape/audio/voice/female/found_key.ogg differ diff --git a/web/escape/audio/voice/female/g0_intro.ogg b/web/escape/audio/voice/female/g0_intro.ogg index ee5763f8..e7798988 100644 Binary files a/web/escape/audio/voice/female/g0_intro.ogg and b/web/escape/audio/voice/female/g0_intro.ogg differ diff --git a/web/escape/audio/voice/female/g1_done.ogg b/web/escape/audio/voice/female/g1_done.ogg index a079c0e6..28d24e46 100644 Binary files a/web/escape/audio/voice/female/g1_done.ogg and b/web/escape/audio/voice/female/g1_done.ogg differ diff --git a/web/escape/audio/voice/female/g1_move.ogg b/web/escape/audio/voice/female/g1_move.ogg index bcd0db3f..cd525590 100644 Binary files a/web/escape/audio/voice/female/g1_move.ogg and b/web/escape/audio/voice/female/g1_move.ogg differ diff --git a/web/escape/audio/voice/female/g2_wall.ogg b/web/escape/audio/voice/female/g2_wall.ogg index bf43aa72..45608111 100644 Binary files a/web/escape/audio/voice/female/g2_wall.ogg and b/web/escape/audio/voice/female/g2_wall.ogg differ diff --git a/web/escape/audio/voice/female/g3_left.ogg b/web/escape/audio/voice/female/g3_left.ogg index fc9dc87d..6b08522d 100644 Binary files a/web/escape/audio/voice/female/g3_left.ogg and b/web/escape/audio/voice/female/g3_left.ogg differ diff --git a/web/escape/audio/voice/female/g4_down.ogg b/web/escape/audio/voice/female/g4_down.ogg index 0f7e944f..4c6e6df1 100644 Binary files a/web/escape/audio/voice/female/g4_down.ogg and b/web/escape/audio/voice/female/g4_down.ogg differ diff --git a/web/escape/audio/voice/female/g5_inspect.ogg b/web/escape/audio/voice/female/g5_inspect.ogg index 91c723b9..9d8762eb 100644 Binary files a/web/escape/audio/voice/female/g5_inspect.ogg and b/web/escape/audio/voice/female/g5_inspect.ogg differ diff --git a/web/escape/audio/voice/female/g5_key.ogg b/web/escape/audio/voice/female/g5_key.ogg index a88e1eda..7ed26752 100644 Binary files a/web/escape/audio/voice/female/g5_key.ogg and b/web/escape/audio/voice/female/g5_key.ogg differ diff --git a/web/escape/audio/voice/female/g6_done.ogg b/web/escape/audio/voice/female/g6_done.ogg index 3f3936c4..b2bff63b 100644 Binary files a/web/escape/audio/voice/female/g6_done.ogg and b/web/escape/audio/voice/female/g6_done.ogg differ diff --git a/web/escape/audio/voice/female/g6_doubletap.ogg b/web/escape/audio/voice/female/g6_doubletap.ogg index 9cc0c8f9..19565a23 100644 Binary files a/web/escape/audio/voice/female/g6_doubletap.ogg and b/web/escape/audio/voice/female/g6_doubletap.ogg differ diff --git a/web/escape/audio/voice/female/g7_goal.ogg b/web/escape/audio/voice/female/g7_goal.ogg index 62adc106..d1efb62b 100644 Binary files a/web/escape/audio/voice/female/g7_goal.ogg and b/web/escape/audio/voice/female/g7_goal.ogg differ diff --git a/web/escape/audio/voice/female/gd_next_fuse.m4a b/web/escape/audio/voice/female/gd_next_fuse.m4a new file mode 100644 index 00000000..97a2c887 Binary files /dev/null and b/web/escape/audio/voice/female/gd_next_fuse.m4a differ diff --git a/web/escape/audio/voice/female/gd_next_fuse.ogg b/web/escape/audio/voice/female/gd_next_fuse.ogg new file mode 100644 index 00000000..9db16340 Binary files /dev/null and b/web/escape/audio/voice/female/gd_next_fuse.ogg differ diff --git a/web/escape/audio/voice/female/guide_blunt_down.ogg b/web/escape/audio/voice/female/guide_blunt_down.ogg index 4b385f63..fe851706 100644 Binary files a/web/escape/audio/voice/female/guide_blunt_down.ogg and b/web/escape/audio/voice/female/guide_blunt_down.ogg differ diff --git a/web/escape/audio/voice/female/guide_blunt_left.ogg b/web/escape/audio/voice/female/guide_blunt_left.ogg index 08b12501..71f32791 100644 Binary files a/web/escape/audio/voice/female/guide_blunt_left.ogg and b/web/escape/audio/voice/female/guide_blunt_left.ogg differ diff --git a/web/escape/audio/voice/female/guide_blunt_right.ogg b/web/escape/audio/voice/female/guide_blunt_right.ogg index 8618ef46..735cb907 100644 Binary files a/web/escape/audio/voice/female/guide_blunt_right.ogg and b/web/escape/audio/voice/female/guide_blunt_right.ogg differ diff --git a/web/escape/audio/voice/female/guide_blunt_up.ogg b/web/escape/audio/voice/female/guide_blunt_up.ogg index df9db5d9..5e240137 100644 Binary files a/web/escape/audio/voice/female/guide_blunt_up.ogg and b/web/escape/audio/voice/female/guide_blunt_up.ogg differ diff --git a/web/escape/audio/voice/female/guide_offpath.ogg b/web/escape/audio/voice/female/guide_offpath.ogg index 68f83c4b..5d1ecd5c 100644 Binary files a/web/escape/audio/voice/female/guide_offpath.ogg and b/web/escape/audio/voice/female/guide_offpath.ogg differ diff --git a/web/escape/audio/voice/female/guide_skip.ogg b/web/escape/audio/voice/female/guide_skip.ogg index 4e3e88c0..04c90a94 100644 Binary files a/web/escape/audio/voice/female/guide_skip.ogg and b/web/escape/audio/voice/female/guide_skip.ogg differ diff --git a/web/escape/audio/voice/female/guide_wrong_down.ogg b/web/escape/audio/voice/female/guide_wrong_down.ogg index 5bb9acbe..1a525bbe 100644 Binary files a/web/escape/audio/voice/female/guide_wrong_down.ogg and b/web/escape/audio/voice/female/guide_wrong_down.ogg differ diff --git a/web/escape/audio/voice/female/guide_wrong_gesture.ogg b/web/escape/audio/voice/female/guide_wrong_gesture.ogg index 5f1eafad..d9f69cfd 100644 Binary files a/web/escape/audio/voice/female/guide_wrong_gesture.ogg and b/web/escape/audio/voice/female/guide_wrong_gesture.ogg differ diff --git a/web/escape/audio/voice/female/guide_wrong_left.ogg b/web/escape/audio/voice/female/guide_wrong_left.ogg index ee9ed70d..20c076ea 100644 Binary files a/web/escape/audio/voice/female/guide_wrong_left.ogg and b/web/escape/audio/voice/female/guide_wrong_left.ogg differ diff --git a/web/escape/audio/voice/female/guide_wrong_right.ogg b/web/escape/audio/voice/female/guide_wrong_right.ogg index b02f24fb..1614ad38 100644 Binary files a/web/escape/audio/voice/female/guide_wrong_right.ogg and b/web/escape/audio/voice/female/guide_wrong_right.ogg differ diff --git a/web/escape/audio/voice/female/guide_wrong_up.ogg b/web/escape/audio/voice/female/guide_wrong_up.ogg index 6ca95de7..a272bbca 100644 Binary files a/web/escape/audio/voice/female/guide_wrong_up.ogg and b/web/escape/audio/voice/female/guide_wrong_up.ogg differ diff --git a/web/escape/audio/voice/female/help_ops.ogg b/web/escape/audio/voice/female/help_ops.ogg index d488ba72..01ab7c60 100644 Binary files a/web/escape/audio/voice/female/help_ops.ogg and b/web/escape/audio/voice/female/help_ops.ogg differ diff --git a/web/escape/audio/voice/female/inspect_box_dead.ogg b/web/escape/audio/voice/female/inspect_box_dead.ogg index 582d05c2..1b63a368 100644 Binary files a/web/escape/audio/voice/female/inspect_box_dead.ogg and b/web/escape/audio/voice/female/inspect_box_dead.ogg differ diff --git a/web/escape/audio/voice/female/inspect_cabinet_locked.ogg b/web/escape/audio/voice/female/inspect_cabinet_locked.ogg index ed0d138a..ba820158 100644 Binary files a/web/escape/audio/voice/female/inspect_cabinet_locked.ogg and b/web/escape/audio/voice/female/inspect_cabinet_locked.ogg differ diff --git a/web/escape/audio/voice/female/inspect_gate.ogg b/web/escape/audio/voice/female/inspect_gate.ogg index d360711c..9776ca59 100644 Binary files a/web/escape/audio/voice/female/inspect_gate.ogg and b/web/escape/audio/voice/female/inspect_gate.ogg differ diff --git a/web/escape/audio/voice/female/inspect_gate_ready.ogg b/web/escape/audio/voice/female/inspect_gate_ready.ogg index d5371b31..2050f9c6 100644 Binary files a/web/escape/audio/voice/female/inspect_gate_ready.ogg and b/web/escape/audio/voice/female/inspect_gate_ready.ogg differ diff --git a/web/escape/audio/voice/female/inv_both.ogg b/web/escape/audio/voice/female/inv_both.ogg index 7519b4f0..55931220 100644 Binary files a/web/escape/audio/voice/female/inv_both.ogg and b/web/escape/audio/voice/female/inv_both.ogg differ diff --git a/web/escape/audio/voice/female/inv_empty.ogg b/web/escape/audio/voice/female/inv_empty.ogg index 8de6f3c5..b9d3b711 100644 Binary files a/web/escape/audio/voice/female/inv_empty.ogg and b/web/escape/audio/voice/female/inv_empty.ogg differ diff --git a/web/escape/audio/voice/female/inv_fuse.ogg b/web/escape/audio/voice/female/inv_fuse.ogg index 16cef413..b7fe3115 100644 Binary files a/web/escape/audio/voice/female/inv_fuse.ogg and b/web/escape/audio/voice/female/inv_fuse.ogg differ diff --git a/web/escape/audio/voice/female/inv_key.ogg b/web/escape/audio/voice/female/inv_key.ogg index 144a272b..e0ce950c 100644 Binary files a/web/escape/audio/voice/female/inv_key.ogg and b/web/escape/audio/voice/female/inv_key.ogg differ diff --git a/web/escape/audio/voice/female/menu_back.ogg b/web/escape/audio/voice/female/menu_back.ogg index ea0cc6c5..963406cc 100644 Binary files a/web/escape/audio/voice/female/menu_back.ogg and b/web/escape/audio/voice/female/menu_back.ogg differ diff --git a/web/escape/audio/voice/female/menu_home.ogg b/web/escape/audio/voice/female/menu_home.ogg index 61b0e3c5..c04e5924 100644 Binary files a/web/escape/audio/voice/female/menu_home.ogg and b/web/escape/audio/voice/female/menu_home.ogg differ diff --git a/web/escape/audio/voice/female/menu_open.ogg b/web/escape/audio/voice/female/menu_open.ogg index 788420b7..d0540b46 100644 Binary files a/web/escape/audio/voice/female/menu_open.ogg and b/web/escape/audio/voice/female/menu_open.ogg differ diff --git a/web/escape/audio/voice/female/menu_restart.ogg b/web/escape/audio/voice/female/menu_restart.ogg index e3e4c860..2dd0c0c5 100644 Binary files a/web/escape/audio/voice/female/menu_restart.ogg and b/web/escape/audio/voice/female/menu_restart.ogg differ diff --git a/web/escape/audio/voice/female/nav_down.ogg b/web/escape/audio/voice/female/nav_down.ogg index c0e475bb..eef5ed96 100644 Binary files a/web/escape/audio/voice/female/nav_down.ogg and b/web/escape/audio/voice/female/nav_down.ogg differ diff --git a/web/escape/audio/voice/female/nav_left.ogg b/web/escape/audio/voice/female/nav_left.ogg index b220388d..ab0f4421 100644 Binary files a/web/escape/audio/voice/female/nav_left.ogg and b/web/escape/audio/voice/female/nav_left.ogg differ diff --git a/web/escape/audio/voice/female/nav_right.ogg b/web/escape/audio/voice/female/nav_right.ogg index 6f1cf5f2..f85f0d33 100644 Binary files a/web/escape/audio/voice/female/nav_right.ogg and b/web/escape/audio/voice/female/nav_right.ogg differ diff --git a/web/escape/audio/voice/female/nav_up.ogg b/web/escape/audio/voice/female/nav_up.ogg index f3969f7e..8e75a7e1 100644 Binary files a/web/escape/audio/voice/female/nav_up.ogg and b/web/escape/audio/voice/female/nav_up.ogg differ diff --git a/web/escape/audio/voice/female/reopen_prompt.ogg b/web/escape/audio/voice/female/reopen_prompt.ogg index 81231a8f..3e020cf1 100644 Binary files a/web/escape/audio/voice/female/reopen_prompt.ogg and b/web/escape/audio/voice/female/reopen_prompt.ogg differ diff --git a/web/escape/audio/voice/female/replay.ogg b/web/escape/audio/voice/female/replay.ogg index 03fdb348..a31a75e9 100644 Binary files a/web/escape/audio/voice/female/replay.ogg and b/web/escape/audio/voice/female/replay.ogg differ diff --git a/web/escape/audio/voice/female/room_cabinet.ogg b/web/escape/audio/voice/female/room_cabinet.ogg index c91eb324..3257312c 100644 Binary files a/web/escape/audio/voice/female/room_cabinet.ogg and b/web/escape/audio/voice/female/room_cabinet.ogg differ diff --git a/web/escape/audio/voice/female/room_gate.ogg b/web/escape/audio/voice/female/room_gate.ogg index 04a901c6..c4275c7e 100644 Binary files a/web/escape/audio/voice/female/room_gate.ogg and b/web/escape/audio/voice/female/room_gate.ogg differ diff --git a/web/escape/audio/voice/female/room_power.ogg b/web/escape/audio/voice/female/room_power.ogg index d6c5e9d0..974af2f2 100644 Binary files a/web/escape/audio/voice/female/room_power.ogg and b/web/escape/audio/voice/female/room_power.ogg differ diff --git a/web/escape/audio/voice/female/room_storage.ogg b/web/escape/audio/voice/female/room_storage.ogg index cff23bb8..a3f59dc7 100644 Binary files a/web/escape/audio/voice/female/room_storage.ogg and b/web/escape/audio/voice/female/room_storage.ogg differ diff --git a/web/escape/audio/voice/female/skip_hint.ogg b/web/escape/audio/voice/female/skip_hint.ogg index da6649d5..f9dd4c8f 100644 Binary files a/web/escape/audio/voice/female/skip_hint.ogg and b/web/escape/audio/voice/female/skip_hint.ogg differ diff --git a/web/escape/audio/voice/female/start_room.ogg b/web/escape/audio/voice/female/start_room.ogg index 5911043e..02e665e3 100644 Binary files a/web/escape/audio/voice/female/start_room.ogg and b/web/escape/audio/voice/female/start_room.ogg differ diff --git a/web/escape/audio/voice/female/stuck_ask.ogg b/web/escape/audio/voice/female/stuck_ask.ogg index e66f19d0..ef45d505 100644 Binary files a/web/escape/audio/voice/female/stuck_ask.ogg and b/web/escape/audio/voice/female/stuck_ask.ogg differ diff --git a/web/escape/audio/voice/female/stuck_box_1.ogg b/web/escape/audio/voice/female/stuck_box_1.ogg index 428ab0b3..1d02109e 100644 Binary files a/web/escape/audio/voice/female/stuck_box_1.ogg and b/web/escape/audio/voice/female/stuck_box_1.ogg differ diff --git a/web/escape/audio/voice/female/stuck_box_2.ogg b/web/escape/audio/voice/female/stuck_box_2.ogg index 490acfda..365802ff 100644 Binary files a/web/escape/audio/voice/female/stuck_box_2.ogg and b/web/escape/audio/voice/female/stuck_box_2.ogg differ diff --git a/web/escape/audio/voice/female/stuck_box_3.ogg b/web/escape/audio/voice/female/stuck_box_3.ogg index 4176157e..dc2c1bc2 100644 Binary files a/web/escape/audio/voice/female/stuck_box_3.ogg and b/web/escape/audio/voice/female/stuck_box_3.ogg differ diff --git a/web/escape/audio/voice/female/stuck_cabinet_1.ogg b/web/escape/audio/voice/female/stuck_cabinet_1.ogg index 4d3c5b08..656d1738 100644 Binary files a/web/escape/audio/voice/female/stuck_cabinet_1.ogg and b/web/escape/audio/voice/female/stuck_cabinet_1.ogg differ diff --git a/web/escape/audio/voice/female/stuck_cabinet_2.ogg b/web/escape/audio/voice/female/stuck_cabinet_2.ogg index 95037edd..68079fba 100644 Binary files a/web/escape/audio/voice/female/stuck_cabinet_2.ogg and b/web/escape/audio/voice/female/stuck_cabinet_2.ogg differ diff --git a/web/escape/audio/voice/female/stuck_cabinet_3.ogg b/web/escape/audio/voice/female/stuck_cabinet_3.ogg index a71ca6e8..fc407d4a 100644 Binary files a/web/escape/audio/voice/female/stuck_cabinet_3.ogg and b/web/escape/audio/voice/female/stuck_cabinet_3.ogg differ diff --git a/web/escape/audio/voice/female/stuck_gate_1.ogg b/web/escape/audio/voice/female/stuck_gate_1.ogg index e0bb89dc..4d076316 100644 Binary files a/web/escape/audio/voice/female/stuck_gate_1.ogg and b/web/escape/audio/voice/female/stuck_gate_1.ogg differ diff --git a/web/escape/audio/voice/female/stuck_gate_2.ogg b/web/escape/audio/voice/female/stuck_gate_2.ogg index bcc16a8b..c742fd18 100644 Binary files a/web/escape/audio/voice/female/stuck_gate_2.ogg and b/web/escape/audio/voice/female/stuck_gate_2.ogg differ diff --git a/web/escape/audio/voice/female/stuck_gate_3.ogg b/web/escape/audio/voice/female/stuck_gate_3.ogg index d49c6c0d..aa3a39ef 100644 Binary files a/web/escape/audio/voice/female/stuck_gate_3.ogg and b/web/escape/audio/voice/female/stuck_gate_3.ogg differ diff --git a/web/escape/audio/voice/female/stuck_key_1.ogg b/web/escape/audio/voice/female/stuck_key_1.ogg index dfbbaa7b..1a696c16 100644 Binary files a/web/escape/audio/voice/female/stuck_key_1.ogg and b/web/escape/audio/voice/female/stuck_key_1.ogg differ diff --git a/web/escape/audio/voice/female/stuck_key_2.ogg b/web/escape/audio/voice/female/stuck_key_2.ogg index 178896d8..b6d03e46 100644 Binary files a/web/escape/audio/voice/female/stuck_key_2.ogg and b/web/escape/audio/voice/female/stuck_key_2.ogg differ diff --git a/web/escape/audio/voice/female/stuck_key_3.ogg b/web/escape/audio/voice/female/stuck_key_3.ogg index 4df2fdd7..e4fd84a6 100644 Binary files a/web/escape/audio/voice/female/stuck_key_3.ogg and b/web/escape/audio/voice/female/stuck_key_3.ogg differ diff --git a/web/escape/audio/voice/female/time_band1.ogg b/web/escape/audio/voice/female/time_band1.ogg index 676f8b6d..e1700705 100644 Binary files a/web/escape/audio/voice/female/time_band1.ogg and b/web/escape/audio/voice/female/time_band1.ogg differ diff --git a/web/escape/audio/voice/female/time_band2.ogg b/web/escape/audio/voice/female/time_band2.ogg index de205328..de7fd78e 100644 Binary files a/web/escape/audio/voice/female/time_band2.ogg and b/web/escape/audio/voice/female/time_band2.ogg differ diff --git a/web/escape/audio/voice/female/time_band3.ogg b/web/escape/audio/voice/female/time_band3.ogg index 334f97f4..3ed99989 100644 Binary files a/web/escape/audio/voice/female/time_band3.ogg and b/web/escape/audio/voice/female/time_band3.ogg differ diff --git a/web/escape/audio/voice/female/time_band4.ogg b/web/escape/audio/voice/female/time_band4.ogg index a1534c54..8a518358 100644 Binary files a/web/escape/audio/voice/female/time_band4.ogg and b/web/escape/audio/voice/female/time_band4.ogg differ diff --git a/web/escape/audio/voice/female/unlock_cabinet.ogg b/web/escape/audio/voice/female/unlock_cabinet.ogg index 199aead4..99228bf8 100644 Binary files a/web/escape/audio/voice/female/unlock_cabinet.ogg and b/web/escape/audio/voice/female/unlock_cabinet.ogg differ diff --git a/web/escape/audio/voice/female/use_fail.ogg b/web/escape/audio/voice/female/use_fail.ogg index 958fc860..deec5ab6 100644 Binary files a/web/escape/audio/voice/female/use_fail.ogg and b/web/escape/audio/voice/female/use_fail.ogg differ diff --git a/web/escape/audio/voice/female/wall.ogg b/web/escape/audio/voice/female/wall.ogg index 7db3a657..029184aa 100644 Binary files a/web/escape/audio/voice/female/wall.ogg and b/web/escape/audio/voice/female/wall.ogg differ diff --git a/web/escape/audio/voice/male/again.ogg b/web/escape/audio/voice/male/again.ogg index d53508e1..9a41eeab 100644 Binary files a/web/escape/audio/voice/male/again.ogg and b/web/escape/audio/voice/male/again.ogg differ diff --git a/web/escape/audio/voice/male/box_fixed.ogg b/web/escape/audio/voice/male/box_fixed.ogg index 01da1ab7..c8964569 100644 Binary files a/web/escape/audio/voice/male/box_fixed.ogg and b/web/escape/audio/voice/male/box_fixed.ogg differ diff --git a/web/escape/audio/voice/male/empty_1.ogg b/web/escape/audio/voice/male/empty_1.ogg index e6ec2517..656239c7 100644 Binary files a/web/escape/audio/voice/male/empty_1.ogg and b/web/escape/audio/voice/male/empty_1.ogg differ diff --git a/web/escape/audio/voice/male/empty_2.ogg b/web/escape/audio/voice/male/empty_2.ogg index 67fc5bfb..0f4112b1 100644 Binary files a/web/escape/audio/voice/male/empty_2.ogg and b/web/escape/audio/voice/male/empty_2.ogg differ diff --git a/web/escape/audio/voice/male/empty_3.ogg b/web/escape/audio/voice/male/empty_3.ogg index 9b1a3535..21f8bbbb 100644 Binary files a/web/escape/audio/voice/male/empty_3.ogg and b/web/escape/audio/voice/male/empty_3.ogg differ diff --git a/web/escape/audio/voice/male/escape.ogg b/web/escape/audio/voice/male/escape.ogg index 2cb9418a..93096015 100644 Binary files a/web/escape/audio/voice/male/escape.ogg and b/web/escape/audio/voice/male/escape.ogg differ diff --git a/web/escape/audio/voice/male/fix_box.ogg b/web/escape/audio/voice/male/fix_box.ogg index 2b401a6b..46c2511f 100644 Binary files a/web/escape/audio/voice/male/fix_box.ogg and b/web/escape/audio/voice/male/fix_box.ogg differ diff --git a/web/escape/audio/voice/male/found_key.ogg b/web/escape/audio/voice/male/found_key.ogg index 608a1865..8dd2856a 100644 Binary files a/web/escape/audio/voice/male/found_key.ogg and b/web/escape/audio/voice/male/found_key.ogg differ diff --git a/web/escape/audio/voice/male/g0_intro.ogg b/web/escape/audio/voice/male/g0_intro.ogg index 3703a082..51422225 100644 Binary files a/web/escape/audio/voice/male/g0_intro.ogg and b/web/escape/audio/voice/male/g0_intro.ogg differ diff --git a/web/escape/audio/voice/male/g1_done.ogg b/web/escape/audio/voice/male/g1_done.ogg index cfbcab04..163557c8 100644 Binary files a/web/escape/audio/voice/male/g1_done.ogg and b/web/escape/audio/voice/male/g1_done.ogg differ diff --git a/web/escape/audio/voice/male/g1_move.ogg b/web/escape/audio/voice/male/g1_move.ogg index 56e7a2ba..45322853 100644 Binary files a/web/escape/audio/voice/male/g1_move.ogg and b/web/escape/audio/voice/male/g1_move.ogg differ diff --git a/web/escape/audio/voice/male/g2_wall.ogg b/web/escape/audio/voice/male/g2_wall.ogg index a1ef9c9e..71c1d21f 100644 Binary files a/web/escape/audio/voice/male/g2_wall.ogg and b/web/escape/audio/voice/male/g2_wall.ogg differ diff --git a/web/escape/audio/voice/male/g3_left.ogg b/web/escape/audio/voice/male/g3_left.ogg index 4a81dc51..7c528ab1 100644 Binary files a/web/escape/audio/voice/male/g3_left.ogg and b/web/escape/audio/voice/male/g3_left.ogg differ diff --git a/web/escape/audio/voice/male/g4_down.ogg b/web/escape/audio/voice/male/g4_down.ogg index 3e7151bd..4e1ff6a5 100644 Binary files a/web/escape/audio/voice/male/g4_down.ogg and b/web/escape/audio/voice/male/g4_down.ogg differ diff --git a/web/escape/audio/voice/male/g5_inspect.ogg b/web/escape/audio/voice/male/g5_inspect.ogg index 9bc0eb2d..c68e135c 100644 Binary files a/web/escape/audio/voice/male/g5_inspect.ogg and b/web/escape/audio/voice/male/g5_inspect.ogg differ diff --git a/web/escape/audio/voice/male/g5_key.ogg b/web/escape/audio/voice/male/g5_key.ogg index 26771e8f..0be3eb0f 100644 Binary files a/web/escape/audio/voice/male/g5_key.ogg and b/web/escape/audio/voice/male/g5_key.ogg differ diff --git a/web/escape/audio/voice/male/g6_done.ogg b/web/escape/audio/voice/male/g6_done.ogg index 307f9e8d..97bb42a8 100644 Binary files a/web/escape/audio/voice/male/g6_done.ogg and b/web/escape/audio/voice/male/g6_done.ogg differ diff --git a/web/escape/audio/voice/male/g6_doubletap.ogg b/web/escape/audio/voice/male/g6_doubletap.ogg index 50047043..aaa58fa5 100644 Binary files a/web/escape/audio/voice/male/g6_doubletap.ogg and b/web/escape/audio/voice/male/g6_doubletap.ogg differ diff --git a/web/escape/audio/voice/male/g7_goal.ogg b/web/escape/audio/voice/male/g7_goal.ogg index 6487e3f6..5c13ee50 100644 Binary files a/web/escape/audio/voice/male/g7_goal.ogg and b/web/escape/audio/voice/male/g7_goal.ogg differ diff --git a/web/escape/audio/voice/male/gd_next_fuse.m4a b/web/escape/audio/voice/male/gd_next_fuse.m4a new file mode 100644 index 00000000..a7aa85f8 Binary files /dev/null and b/web/escape/audio/voice/male/gd_next_fuse.m4a differ diff --git a/web/escape/audio/voice/male/gd_next_fuse.ogg b/web/escape/audio/voice/male/gd_next_fuse.ogg new file mode 100644 index 00000000..e30c6156 Binary files /dev/null and b/web/escape/audio/voice/male/gd_next_fuse.ogg differ diff --git a/web/escape/audio/voice/male/guide_blunt_down.ogg b/web/escape/audio/voice/male/guide_blunt_down.ogg index 87dced83..72000e5b 100644 Binary files a/web/escape/audio/voice/male/guide_blunt_down.ogg and b/web/escape/audio/voice/male/guide_blunt_down.ogg differ diff --git a/web/escape/audio/voice/male/guide_blunt_left.ogg b/web/escape/audio/voice/male/guide_blunt_left.ogg index 91b973c1..b893da18 100644 Binary files a/web/escape/audio/voice/male/guide_blunt_left.ogg and b/web/escape/audio/voice/male/guide_blunt_left.ogg differ diff --git a/web/escape/audio/voice/male/guide_blunt_right.ogg b/web/escape/audio/voice/male/guide_blunt_right.ogg index abd6ff4f..bb91fafa 100644 Binary files a/web/escape/audio/voice/male/guide_blunt_right.ogg and b/web/escape/audio/voice/male/guide_blunt_right.ogg differ diff --git a/web/escape/audio/voice/male/guide_blunt_up.ogg b/web/escape/audio/voice/male/guide_blunt_up.ogg index 5d898958..17771966 100644 Binary files a/web/escape/audio/voice/male/guide_blunt_up.ogg and b/web/escape/audio/voice/male/guide_blunt_up.ogg differ diff --git a/web/escape/audio/voice/male/guide_offpath.ogg b/web/escape/audio/voice/male/guide_offpath.ogg index 821b3d6b..769c9cf4 100644 Binary files a/web/escape/audio/voice/male/guide_offpath.ogg and b/web/escape/audio/voice/male/guide_offpath.ogg differ diff --git a/web/escape/audio/voice/male/guide_skip.ogg b/web/escape/audio/voice/male/guide_skip.ogg index 14e68690..33256485 100644 Binary files a/web/escape/audio/voice/male/guide_skip.ogg and b/web/escape/audio/voice/male/guide_skip.ogg differ diff --git a/web/escape/audio/voice/male/guide_wrong_down.ogg b/web/escape/audio/voice/male/guide_wrong_down.ogg index 509acb96..44f9dcbf 100644 Binary files a/web/escape/audio/voice/male/guide_wrong_down.ogg and b/web/escape/audio/voice/male/guide_wrong_down.ogg differ diff --git a/web/escape/audio/voice/male/guide_wrong_gesture.ogg b/web/escape/audio/voice/male/guide_wrong_gesture.ogg index b8f264a0..c53e8e51 100644 Binary files a/web/escape/audio/voice/male/guide_wrong_gesture.ogg and b/web/escape/audio/voice/male/guide_wrong_gesture.ogg differ diff --git a/web/escape/audio/voice/male/guide_wrong_left.ogg b/web/escape/audio/voice/male/guide_wrong_left.ogg index a94ff9a6..c8ba89a0 100644 Binary files a/web/escape/audio/voice/male/guide_wrong_left.ogg and b/web/escape/audio/voice/male/guide_wrong_left.ogg differ diff --git a/web/escape/audio/voice/male/guide_wrong_right.ogg b/web/escape/audio/voice/male/guide_wrong_right.ogg index dc8fa1f6..9afbe249 100644 Binary files a/web/escape/audio/voice/male/guide_wrong_right.ogg and b/web/escape/audio/voice/male/guide_wrong_right.ogg differ diff --git a/web/escape/audio/voice/male/guide_wrong_up.ogg b/web/escape/audio/voice/male/guide_wrong_up.ogg index 3694ab17..88b96706 100644 Binary files a/web/escape/audio/voice/male/guide_wrong_up.ogg and b/web/escape/audio/voice/male/guide_wrong_up.ogg differ diff --git a/web/escape/audio/voice/male/help_ops.ogg b/web/escape/audio/voice/male/help_ops.ogg index ba0ca485..b1452442 100644 Binary files a/web/escape/audio/voice/male/help_ops.ogg and b/web/escape/audio/voice/male/help_ops.ogg differ diff --git a/web/escape/audio/voice/male/inspect_box_dead.ogg b/web/escape/audio/voice/male/inspect_box_dead.ogg index be932d51..dce7cd15 100644 Binary files a/web/escape/audio/voice/male/inspect_box_dead.ogg and b/web/escape/audio/voice/male/inspect_box_dead.ogg differ diff --git a/web/escape/audio/voice/male/inspect_cabinet_locked.ogg b/web/escape/audio/voice/male/inspect_cabinet_locked.ogg index 6a584fec..528f7865 100644 Binary files a/web/escape/audio/voice/male/inspect_cabinet_locked.ogg and b/web/escape/audio/voice/male/inspect_cabinet_locked.ogg differ diff --git a/web/escape/audio/voice/male/inspect_gate.ogg b/web/escape/audio/voice/male/inspect_gate.ogg index 26b18301..2db97401 100644 Binary files a/web/escape/audio/voice/male/inspect_gate.ogg and b/web/escape/audio/voice/male/inspect_gate.ogg differ diff --git a/web/escape/audio/voice/male/inspect_gate_ready.ogg b/web/escape/audio/voice/male/inspect_gate_ready.ogg index 827bbf69..1526a069 100644 Binary files a/web/escape/audio/voice/male/inspect_gate_ready.ogg and b/web/escape/audio/voice/male/inspect_gate_ready.ogg differ diff --git a/web/escape/audio/voice/male/inv_both.ogg b/web/escape/audio/voice/male/inv_both.ogg index 1f52c985..5cb8cddf 100644 Binary files a/web/escape/audio/voice/male/inv_both.ogg and b/web/escape/audio/voice/male/inv_both.ogg differ diff --git a/web/escape/audio/voice/male/inv_empty.ogg b/web/escape/audio/voice/male/inv_empty.ogg index 0829c381..49d4cdc2 100644 Binary files a/web/escape/audio/voice/male/inv_empty.ogg and b/web/escape/audio/voice/male/inv_empty.ogg differ diff --git a/web/escape/audio/voice/male/inv_fuse.ogg b/web/escape/audio/voice/male/inv_fuse.ogg index cd0d6286..06ad2981 100644 Binary files a/web/escape/audio/voice/male/inv_fuse.ogg and b/web/escape/audio/voice/male/inv_fuse.ogg differ diff --git a/web/escape/audio/voice/male/inv_key.ogg b/web/escape/audio/voice/male/inv_key.ogg index 1e009e45..9422a85c 100644 Binary files a/web/escape/audio/voice/male/inv_key.ogg and b/web/escape/audio/voice/male/inv_key.ogg differ diff --git a/web/escape/audio/voice/male/menu_back.ogg b/web/escape/audio/voice/male/menu_back.ogg index 6656fa68..435db607 100644 Binary files a/web/escape/audio/voice/male/menu_back.ogg and b/web/escape/audio/voice/male/menu_back.ogg differ diff --git a/web/escape/audio/voice/male/menu_home.ogg b/web/escape/audio/voice/male/menu_home.ogg index 91cdfbf1..823689b4 100644 Binary files a/web/escape/audio/voice/male/menu_home.ogg and b/web/escape/audio/voice/male/menu_home.ogg differ diff --git a/web/escape/audio/voice/male/menu_open.ogg b/web/escape/audio/voice/male/menu_open.ogg index 15a32de4..8eea57f8 100644 Binary files a/web/escape/audio/voice/male/menu_open.ogg and b/web/escape/audio/voice/male/menu_open.ogg differ diff --git a/web/escape/audio/voice/male/menu_restart.ogg b/web/escape/audio/voice/male/menu_restart.ogg index 39af33df..b8713bd1 100644 Binary files a/web/escape/audio/voice/male/menu_restart.ogg and b/web/escape/audio/voice/male/menu_restart.ogg differ diff --git a/web/escape/audio/voice/male/nav_down.ogg b/web/escape/audio/voice/male/nav_down.ogg index 3e8a331a..4b2306ac 100644 Binary files a/web/escape/audio/voice/male/nav_down.ogg and b/web/escape/audio/voice/male/nav_down.ogg differ diff --git a/web/escape/audio/voice/male/nav_left.ogg b/web/escape/audio/voice/male/nav_left.ogg index 7f51fcf6..61bf56a4 100644 Binary files a/web/escape/audio/voice/male/nav_left.ogg and b/web/escape/audio/voice/male/nav_left.ogg differ diff --git a/web/escape/audio/voice/male/nav_right.ogg b/web/escape/audio/voice/male/nav_right.ogg index 8f4c6378..f126fabe 100644 Binary files a/web/escape/audio/voice/male/nav_right.ogg and b/web/escape/audio/voice/male/nav_right.ogg differ diff --git a/web/escape/audio/voice/male/nav_up.ogg b/web/escape/audio/voice/male/nav_up.ogg index 91679cab..d80adae8 100644 Binary files a/web/escape/audio/voice/male/nav_up.ogg and b/web/escape/audio/voice/male/nav_up.ogg differ diff --git a/web/escape/audio/voice/male/reopen_prompt.ogg b/web/escape/audio/voice/male/reopen_prompt.ogg index f5fffd10..8b78016d 100644 Binary files a/web/escape/audio/voice/male/reopen_prompt.ogg and b/web/escape/audio/voice/male/reopen_prompt.ogg differ diff --git a/web/escape/audio/voice/male/replay.ogg b/web/escape/audio/voice/male/replay.ogg index 23707e9b..30787521 100644 Binary files a/web/escape/audio/voice/male/replay.ogg and b/web/escape/audio/voice/male/replay.ogg differ diff --git a/web/escape/audio/voice/male/room_cabinet.ogg b/web/escape/audio/voice/male/room_cabinet.ogg index 25d820f6..d0daee7a 100644 Binary files a/web/escape/audio/voice/male/room_cabinet.ogg and b/web/escape/audio/voice/male/room_cabinet.ogg differ diff --git a/web/escape/audio/voice/male/room_gate.ogg b/web/escape/audio/voice/male/room_gate.ogg index 39c196ce..c50b0dc6 100644 Binary files a/web/escape/audio/voice/male/room_gate.ogg and b/web/escape/audio/voice/male/room_gate.ogg differ diff --git a/web/escape/audio/voice/male/room_power.ogg b/web/escape/audio/voice/male/room_power.ogg index b66d1119..e669bb7a 100644 Binary files a/web/escape/audio/voice/male/room_power.ogg and b/web/escape/audio/voice/male/room_power.ogg differ diff --git a/web/escape/audio/voice/male/room_storage.ogg b/web/escape/audio/voice/male/room_storage.ogg index 5fa4c965..3bbe8aac 100644 Binary files a/web/escape/audio/voice/male/room_storage.ogg and b/web/escape/audio/voice/male/room_storage.ogg differ diff --git a/web/escape/audio/voice/male/skip_hint.ogg b/web/escape/audio/voice/male/skip_hint.ogg index 2c49e448..db7f4cd2 100644 Binary files a/web/escape/audio/voice/male/skip_hint.ogg and b/web/escape/audio/voice/male/skip_hint.ogg differ diff --git a/web/escape/audio/voice/male/start_room.ogg b/web/escape/audio/voice/male/start_room.ogg index 1640bb02..9014b533 100644 Binary files a/web/escape/audio/voice/male/start_room.ogg and b/web/escape/audio/voice/male/start_room.ogg differ diff --git a/web/escape/audio/voice/male/stuck_ask.ogg b/web/escape/audio/voice/male/stuck_ask.ogg index fced4ec6..82e7d110 100644 Binary files a/web/escape/audio/voice/male/stuck_ask.ogg and b/web/escape/audio/voice/male/stuck_ask.ogg differ diff --git a/web/escape/audio/voice/male/stuck_box_1.ogg b/web/escape/audio/voice/male/stuck_box_1.ogg index 1843c448..149788f7 100644 Binary files a/web/escape/audio/voice/male/stuck_box_1.ogg and b/web/escape/audio/voice/male/stuck_box_1.ogg differ diff --git a/web/escape/audio/voice/male/stuck_box_2.ogg b/web/escape/audio/voice/male/stuck_box_2.ogg index c879bc0f..ed7b3cb1 100644 Binary files a/web/escape/audio/voice/male/stuck_box_2.ogg and b/web/escape/audio/voice/male/stuck_box_2.ogg differ diff --git a/web/escape/audio/voice/male/stuck_box_3.ogg b/web/escape/audio/voice/male/stuck_box_3.ogg index a69e07af..4aabdc26 100644 Binary files a/web/escape/audio/voice/male/stuck_box_3.ogg and b/web/escape/audio/voice/male/stuck_box_3.ogg differ diff --git a/web/escape/audio/voice/male/stuck_cabinet_1.ogg b/web/escape/audio/voice/male/stuck_cabinet_1.ogg index 4f6f41e7..bcc8b363 100644 Binary files a/web/escape/audio/voice/male/stuck_cabinet_1.ogg and b/web/escape/audio/voice/male/stuck_cabinet_1.ogg differ diff --git a/web/escape/audio/voice/male/stuck_cabinet_2.ogg b/web/escape/audio/voice/male/stuck_cabinet_2.ogg index 6dd6b281..de99ac65 100644 Binary files a/web/escape/audio/voice/male/stuck_cabinet_2.ogg and b/web/escape/audio/voice/male/stuck_cabinet_2.ogg differ diff --git a/web/escape/audio/voice/male/stuck_cabinet_3.ogg b/web/escape/audio/voice/male/stuck_cabinet_3.ogg index 2b2f3259..9db7d2cc 100644 Binary files a/web/escape/audio/voice/male/stuck_cabinet_3.ogg and b/web/escape/audio/voice/male/stuck_cabinet_3.ogg differ diff --git a/web/escape/audio/voice/male/stuck_gate_1.ogg b/web/escape/audio/voice/male/stuck_gate_1.ogg index be8c2429..58e9f4d4 100644 Binary files a/web/escape/audio/voice/male/stuck_gate_1.ogg and b/web/escape/audio/voice/male/stuck_gate_1.ogg differ diff --git a/web/escape/audio/voice/male/stuck_gate_2.ogg b/web/escape/audio/voice/male/stuck_gate_2.ogg index b7553275..62dbf755 100644 Binary files a/web/escape/audio/voice/male/stuck_gate_2.ogg and b/web/escape/audio/voice/male/stuck_gate_2.ogg differ diff --git a/web/escape/audio/voice/male/stuck_gate_3.ogg b/web/escape/audio/voice/male/stuck_gate_3.ogg index addd99bf..e1ccaf49 100644 Binary files a/web/escape/audio/voice/male/stuck_gate_3.ogg and b/web/escape/audio/voice/male/stuck_gate_3.ogg differ diff --git a/web/escape/audio/voice/male/stuck_key_1.ogg b/web/escape/audio/voice/male/stuck_key_1.ogg index 8f972240..26daec20 100644 Binary files a/web/escape/audio/voice/male/stuck_key_1.ogg and b/web/escape/audio/voice/male/stuck_key_1.ogg differ diff --git a/web/escape/audio/voice/male/stuck_key_2.ogg b/web/escape/audio/voice/male/stuck_key_2.ogg index a5ee330b..726fa7c1 100644 Binary files a/web/escape/audio/voice/male/stuck_key_2.ogg and b/web/escape/audio/voice/male/stuck_key_2.ogg differ diff --git a/web/escape/audio/voice/male/stuck_key_3.ogg b/web/escape/audio/voice/male/stuck_key_3.ogg index 02f4ea04..c2862907 100644 Binary files a/web/escape/audio/voice/male/stuck_key_3.ogg and b/web/escape/audio/voice/male/stuck_key_3.ogg differ diff --git a/web/escape/audio/voice/male/time_band1.ogg b/web/escape/audio/voice/male/time_band1.ogg index a1c10449..1a6f7b67 100644 Binary files a/web/escape/audio/voice/male/time_band1.ogg and b/web/escape/audio/voice/male/time_band1.ogg differ diff --git a/web/escape/audio/voice/male/time_band2.ogg b/web/escape/audio/voice/male/time_band2.ogg index 613c783b..e9f8ff1b 100644 Binary files a/web/escape/audio/voice/male/time_band2.ogg and b/web/escape/audio/voice/male/time_band2.ogg differ diff --git a/web/escape/audio/voice/male/time_band3.ogg b/web/escape/audio/voice/male/time_band3.ogg index 21f4a920..dbe55931 100644 Binary files a/web/escape/audio/voice/male/time_band3.ogg and b/web/escape/audio/voice/male/time_band3.ogg differ diff --git a/web/escape/audio/voice/male/time_band4.ogg b/web/escape/audio/voice/male/time_band4.ogg index bd4c9a92..e6138936 100644 Binary files a/web/escape/audio/voice/male/time_band4.ogg and b/web/escape/audio/voice/male/time_band4.ogg differ diff --git a/web/escape/audio/voice/male/unlock_cabinet.ogg b/web/escape/audio/voice/male/unlock_cabinet.ogg index 04ca1f6f..4a4a24dc 100644 Binary files a/web/escape/audio/voice/male/unlock_cabinet.ogg and b/web/escape/audio/voice/male/unlock_cabinet.ogg differ diff --git a/web/escape/audio/voice/male/use_fail.ogg b/web/escape/audio/voice/male/use_fail.ogg index 57487922..e2e60203 100644 Binary files a/web/escape/audio/voice/male/use_fail.ogg and b/web/escape/audio/voice/male/use_fail.ogg differ diff --git a/web/escape/audio/voice/male/wall.ogg b/web/escape/audio/voice/male/wall.ogg index a2f5e071..7ceddd74 100644 Binary files a/web/escape/audio/voice/male/wall.ogg and b/web/escape/audio/voice/male/wall.ogg differ diff --git a/web/escape/game.js b/web/escape/game.js index 5115de79..bfa34826 100644 --- a/web/escape/game.js +++ b/web/escape/game.js @@ -438,7 +438,13 @@ export class EscapeGame extends Game { this.audio.play('sfx/unlock'); this.audio.play('sfx/door_creak', { volume: 0.7 }); vibrate('success'); - this._playVoice('voice/unlock_cabinet', { skippable: false }); // 关键获得不可跳 + // G4(round3):拾取反馈链尾接下一目标句「保险丝到手。接下来,去找电箱。」 + // (游戏反馈层全档位,gd_economy 先例——走游戏语音链不走向导通道)——堵上 + // P2-round2 P0「保险丝到手后目标悬空:没有新指令、没有下文」。 + this._playVoice('voice/unlock_cabinet', { + skippable: false, // 关键获得不可跳 + onComplete: () => this._playVoice('voice/gd_next_fuse'), + }); } else if (x === 0 && y === 0 && this.hasFuse && !this.powerOn) { // 保险丝修电箱 -> 恢复供电(保险丝消耗) this.powerOn = true; diff --git a/web/harness/guide.test.mjs b/web/harness/guide.test.mjs index 9e7421a2..f18d3a2a 100644 --- a/web/harness/guide.test.mjs +++ b/web/harness/guide.test.mjs @@ -23,6 +23,8 @@ const ROOT = path.resolve(path.dirname(url.fileURLToPath(import.meta.url)), '..' const GAME_DIRS = { StorylineGame: path.join(ROOT, 'web', 'storyline'), SimonGame: path.join(ROOT, 'web', 'simon'), + RhythmGame: path.join(ROOT, 'web', 'rhythm'), + SpaceGame: path.join(ROOT, 'web', 'space'), }; let currentGameDir = GAME_DIRS.StorylineGame; @@ -53,6 +55,20 @@ globalThis.setTimeout = (cb, ms = 0) => { return id; }; globalThis.clearTimeout = (id) => { timers.delete(id); }; +// rhythm 的 40ms 调度泵 / space 的局内定时链依赖 interval(round3 G1/G7 用例需要) +const intervals = new Set(); +globalThis.setInterval = (cb, ms = 0) => { + const id = timerSeq++; + const step = () => { + if (!intervals.has(id)) return; // 已被 clearInterval + cb(); + if (intervals.has(id)) timers.set(id, { fireAt: now + Math.max(0, Number(ms) || 0), cb: step }); + }; + intervals.add(id); + timers.set(id, { fireAt: now + Math.max(0, Number(ms) || 0), cb: step }); + return id; +}; +globalThis.clearInterval = (id) => { intervals.delete(id); timers.delete(id); }; Object.defineProperty(globalThis, 'performance', { value: { now: () => now }, configurable: true, }); @@ -113,7 +129,9 @@ class MockOscillator { } } class MockAudioContext { - constructor() { this.state = 'running'; this.currentTime = 0; this.destination = {}; } + constructor() { this.state = 'running'; this.destination = {}; this.sampleRate = 44100; } + // 跟随虚拟时钟:rhythm 用 ctx.currentTime 绝对排程(round3 G1 时间窗断言的前提) + get currentTime() { return now / 1000; } createGain() { return new MockGainNode(); } createOscillator() { return new MockOscillator(); } createDynamicsCompressor() { @@ -123,7 +141,7 @@ class MockAudioContext { return n; } createBufferSource() { - return { buffer: null, loop: false, connect() {}, start() {}, stop() {} }; + return { buffer: null, loop: false, playbackRate: new MockParam(), connect() {}, start() {}, stop() {} }; } createScriptProcessor() { return { connect() {}, disconnect() {}, onaudioprocess: null }; } decodeAudioData() { return Promise.resolve({ duration: 2.0, numberOfChannels: 1, sampleRate: 44100, getChannelData: () => new Float32Array(16) }); } @@ -149,6 +167,8 @@ const { settings } = await import('../engine/settings.js'); const { Guide } = await import('../engine/guide.js'); const { StorylineGame } = await import('../storyline/game.js'); const { SimonGame } = await import('../simon/game.js'); +const { RhythmGame } = await import('../rhythm/game.js'); +const { SpaceGame } = await import('../space/game.js'); // guide='full':本文件验证向导层行为(既有 playtest 以 guide='off' 验证零干扰) settings.set({ guide: 'full', voice: 'female', speed: 1.0, bgm: 1.0 }); @@ -156,10 +176,11 @@ settings.set({ guide: 'full', voice: 'female', speed: 1.0, bgm: 1.0 }); /** 组装一局:playLog + 震动/事件捕获(每个用例全新 audio+game)。 */ function makeRig(GameClass) { currentGameDir = GAME_DIRS[GameClass.name]; + storageData.clear(); // 用例间进度隔离(rhythm tutorialDone / simon best 等不串场) const audio = new WebAudioEngine('audio/'); const playLog = []; const origPlay = audio.play.bind(audio); - audio.play = (id, opts) => { playLog.push({ id, t: now }); return origPlay(id, opts); }; + audio.play = (id, opts) => { playLog.push({ id, t: now, opts: opts || {} }); return origPlay(id, opts); }; const game = new GameClass(audio, {}); const events = []; game.guide.setEventHook((evt) => events.push({ ...evt, t: now })); @@ -167,6 +188,7 @@ function makeRig(GameClass) { return { audio, playLog, game, events, vibBase, vibrated: (pattern) => vibrateLog.slice(vibBase).some((p) => JSON.stringify(p) === JSON.stringify(pattern)), + vibratedSince: (mark, pattern) => vibrateLog.slice(mark).some((p) => JSON.stringify(p) === JSON.stringify(pattern)), }; } const voicePlays = (playLog, id) => playLog.filter((e) => e.id === id).length; @@ -364,6 +386,219 @@ realLog('== ⑤ guide=off:全部 API 静默 no-op(无事件、无 gd_* 播 settings.set({ guide: 'full' }); } +// ================================================================ ⑥ G1/G3 rhythm + +realLog('== ⑥ G1/G3 rhythm:gd_answer 落在首个应答窗口前整整 1 小节;菜单恢复 count-in 可感知 =='); +{ + const { audio, playLog, game, events } = makeRig(RhythmGame); + const tSec = () => now / 1000; + const SPB = 60 / 90; // 曲目一 90BPM + await audio.unlock(); + game.start(); + await advance(() => audio.isVoicePlaying()); // welcome 开播 + await gesture(game, 'tap'); // 播放中单击 = 跳过 → 教学链 + await advance(() => game.phase === 'tut'); + await gesture(game, 'down'); // 跳过教学 → 曲目一 main + await advance(() => game.phase === 'main' && game._cues.length > 0); + assert(game._song && game._song.id === 'song1', '前提:进入曲目一 main(90BPM)'); + + // G1:gd_answer(曲谱定时队列直达)在首个应答窗口起点之前整整 1 小节 + await advance(() => playLog.some((e) => e.id === 'voice/gd_answer')); + const ans = playLog.find((e) => e.id === 'voice/gd_answer'); + const win0 = game._cues[0].expected; // 首个应答窗口起点(秒) + assert(ans.t / 1000 < win0, `G1:gd_answer(${(ans.t / 1000).toFixed(2)}s) < 首窗口起点(${win0.toFixed(2)}s)`); + assert(Math.abs(win0 - ans.t / 1000 - 4 * SPB) < 0.06, + `G1:窗口前整整 1 小节(提前 ${(win0 - ans.t / 1000).toFixed(2)}s ≈ ${(4 * SPB).toFixed(2)}s)`); + assert(events.some((e) => e.type === 'turn'), 'G1:turn earcon 同点发出(standard 档也发,off 静默)'); + + // G3:曲中开菜单 → 关菜单恢复:full 档先播 gd_count,链播完才开始 4 拍 count-in + await advance(() => tSec() >= game._bgmT0 + 1.5); // BGM 已起、首窗口未到 + await gesture(game, 'down'); + assert(game.phase === 'menu', 'G3:曲中下滑呼出菜单(无悬置 down 音符)'); + const kicksBefore = game._sched.filter((e) => e.sfx === 'sfx/inst_kick').length; + await gesture(game, 'down'); + assert(voicePlays(playLog, 'voice/gd_count') === 1, 'G3:恢复先播 gd_count(full 档)'); + assert(audio.isVoicePlaying(), 'G3:count-in 在 gd_count 链播完之后才开始(语音串行)'); + await advance(() => !audio.isVoicePlaying() && game._timer !== null); + const allKicks = game._sched.filter((e) => e.sfx === 'sfx/inst_kick').map((e) => e.time).sort((a, b) => a - b); + assert(allKicks.length === kicksBefore + 4, 'G3:count-in 4 记底鼓排入 _sched(sfx 层音量 1.0)'); + const schedTimes = game._sched.map((e) => e.time); + assert(schedTimes.every((t, i) => i === 0 || t >= schedTimes[i - 1]), 'G3:_sched 已按时间重排(count-in 位于队头,round2 版未重排被队头阻塞的根因)'); + const ciKicks = allKicks.slice(0, 4); + assert(ciKicks.every((t, i) => i === 0 || Math.abs(t - ciKicks[i - 1] - SPB) < 0.05), 'G3:底鼓按一拍间距排布'); + const vibMark = vibrateLog.length; + await advance(() => tSec() >= ciKicks[3] + 0.3); + assert(vibrateLog.slice(vibMark).filter((p) => JSON.stringify(p) === '[8]').length >= 4, + 'G3:4 记 count-in 底鼓各带 beat 震(按拍点准时落)'); + assert(game.phase === 'main', 'G3:恢复后回 main'); + + // G1:恢复 = 一次「进 main」:暂停前旧标记已消费 → 对恢复后的首个未判定窗口重排 + const gdCountBefore = voicePlays(playLog, 'voice/gd_answer'); + await advance(() => voicePlays(playLog, 'voice/gd_answer') > gdCountBefore); + const ans2 = playLog.filter((e) => e.id === 'voice/gd_answer').pop(); + assert(ans2.t / 1000 < game._cues[0].expected, 'G1:恢复后的 gd_answer 仍在首个未判定窗口起点之前'); + + // G3:gd_count 每局恢复限 1 次(第二次恢复直接 count-in) + await gesture(game, 'down'); + const cntBefore = voicePlays(playLog, 'voice/gd_count'); + await gesture(game, 'down'); + assert(voicePlays(playLog, 'voice/gd_count') === cntBefore, 'G3:gd_count 每局恢复限 1 次'); + assert(game.phase === 'main', 'G3:第二次恢复不经语音直接 count-in'); + game.stop(); + resetTimers(); +} + +// ================================================================ ⑦ G2 rhythm 教学 DDA + +realLog('== ⑦ G2 rhythm:教学同一步连 2 失败 → 领奏降速 25% 重演 + gd_slow;做对恢复、每局封顶 =='); +{ + const { audio, playLog, game } = makeRig(RhythmGame); + const tSec = () => now / 1000; + const SPB = 60 / 90; + await audio.unlock(); + game.start(); + await advance(() => audio.isVoicePlaying()); + await gesture(game, 'tap'); // 跳过 welcome + await advance(() => game.phase === 'tut' && game._cues.length > 0); + let lead = Math.min(...game._sched.filter((e) => e.sfx === 'sfx/inst_kick').map((e) => e.time)); + assert(Math.abs(game._cues[0].expected - lead - 4 * SPB) < 0.05, '基准:T1 应答窗 = 领奏后 4 拍(正常速率)'); + + // 失败①:整句不出手(F2.1 归因 + 纠正重教)。用持久里程碑停表: + //(_tutEvaluate 会先把 _phaseEnd 置 Infinity 防重入,等「阶段末」类条件会跑飞) + await advance(() => game._tutFails === 1); + assert(game._tutFails === 1, '失败 1 次:纠正重教(原路径不变)'); + await advance(() => game._phaseEnd < 1e9 && tSec() < game._phaseEnd - 0.5); // 纠正链播完、重新领奏 + + // 失败②:再整句不出手 → G2 降速重演 + await advance(() => game._tutSlowUsed === true); + assert(game._tutSlowUsed === true, '同一步连续 2 次失败 → 进入降速路径'); + await advance(() => voicePlays(playLog, 'voice/gd_slow') === 1); + assert(voicePlays(playLog, 'voice/gd_slow') === 1, 'G2:连 2 失败播 gd_slow(full 档)'); + assert(game._tutRate === 0.75, 'G2:该步领奏降速 25%(_tutRate=0.75)'); + await advance(() => game._cues.length > 0 && game._sched.some((e) => e.sfx === 'sfx/inst_kick' && e.time > tSec())); + lead = Math.min(...game._sched.filter((e) => e.sfx === 'sfx/inst_kick').map((e) => e.time)); + assert(Math.abs(game._cues[0].expected - lead - 4 * SPB / 0.75) < 0.06, + `G2:降速后应答窗 = 领奏后 4 拍×1/0.75(实际 ${(game._cues[0].expected - lead).toFixed(2)}s)`); + + // 降速步做对 → 恢复正常速度 + await advance(() => tSec() >= game._cues[0].expected + 0.29); + await gesture(game, 'tap'); // tap 补偿 -0.30s 后 dt≈0,判对 + await advance(() => game._tutIdx === 1); + assert(game._tutRate === 1.0, 'G2:该步做对恢复正常速度'); + + // 封顶:T2 再连 2 失败 → 不再降速,维持 retry_skip 跳步 + await advance(() => game._tutIdx === 1 && game._tutFails === 1); // T2 失败 1 + await advance(() => game._phaseEnd < 1e9 && tSec() < game._phaseEnd - 0.5 && game._tutIdx === 1); + await advance(() => voicePlays(playLog, 'voice/retry_skip') === 1); // T2 失败 2 → 跳步 + assert(voicePlays(playLog, 'voice/gd_slow') === 1, 'G2:gd_slow 每教学局 1 次封顶'); + assert(voicePlays(playLog, 'voice/retry_skip') === 1, 'G2:封顶后维持 retry_skip 跳步不卡流程'); + await advance(() => game._tutIdx === 2); + assert(game._tutIdx === 2, 'G2:跳步进 T3'); + game.stop(); + resetTimers(); +} + +// ================================================================ ⑧ G5 simon 双击/上滑 + +realLog('== ⑧ G5 simon:input 阶段双击永远=作答、上滑=主动重听(full 与 off 双档)=='); +function driveSimonToInput(rig) { + const { audio, game } = rig; + return (async () => { + await audio.unlock(); + rig.game.start(); + await advance(() => game.phase === 'tutorial' && game.teachAwait); + for (const g of ['up', 'down', 'left', 'right', 'tap', 'doubletap']) { + await advance(() => game.teachAwait && game.phase === 'tutorial'); + await gesture(game, g); + } + await advance(() => game.phase === 'input'); + return game; + })(); +} +{ + const rig = makeRig(SimonGame); + const { playLog, game } = rig; + await driveSimonToInput(rig); + assert(game.round === 1 && game.phase === 'input', '前提:教学完进第 1 轮 input'); + assert(voicePlays(playLog, 'voice/gd_economy') === 1, 'G5:教学收尾播 gd_economy(重录新文案)'); + // 固定期望序列(测试钩子):idx0=doubletap、idx1=left + game.sequence[0] = 'doubletap'; + game.sequence[1] = 'left'; + await gesture(game, 'doubletap'); + assert(game.inputIdx === 1 && game.phase === 'input', 'G5:期望恰为 doubletap 时双击=作答(inputIdx 前进)'); + const ch = game.chances; + const relistenN = voicePlays(playLog, 'voice/relisten'); + await gesture(game, 'up'); // 期望非 up → 主动重听 + assert(game.chances === ch - 1 && voicePlays(playLog, 'voice/relisten') === relistenN + 1, + 'G5:input 上滑=主动重听(耗机会、播 relisten)'); + await advance(() => game.phase === 'input'); + assert(game.inputIdx === 0, 'G5:重听后输入进度清零'); + + // G6:第 1 轮答完 → 轮结算链尾 gd_clear(每局 1 次) + await gesture(game, 'doubletap'); // 期望 doubletap → 答对 + await gesture(game, 'left'); + await advance(() => game.phase === 'roundend'); + assert(voicePlays(playLog, 'voice/gd_clear') === 1, 'G6:轮成功链尾播 gd_clear(漂亮,过了)'); + await advance(() => game.phase === 'input' && game.round === 2); + + // G6:第 2 轮答完且超过预设历史纪录(钩子 best=1)→ 追加 gd_record(每局 1 次) + game.best = 1; // 模拟上局留下纪录(测试钩子) + game.sequence[0] = 'up'; // 顺带验证期望恰为 up 时上滑=作答(00 §5.3 豁免同款) + await gesture(game, 'up'); + assert(game.inputIdx === 1 && game.phase === 'input', 'G5:期望恰为 up 时上滑=作答'); + for (let i = 0; i < 8 && game.phase === 'input'; i++) await gesture(game, game.sequence[game.inputIdx]); + await advance(() => game.phase === 'roundend' && game.round === 2); + assert(voicePlays(playLog, 'voice/gd_record') === 1, 'G6:局中破个人纪录播 gd_record(破纪录了)'); + assert(voicePlays(playLog, 'voice/gd_clear') === 1, 'G6:gd_clear 每局仅第 1 次轮成功播'); + await advance(() => game.phase === 'input' && game.round === 3); + + // 双击永远=作答的判错面:chances=0(重听已耗)时双击期望非双击 → 判错到底(gameover),不是 chances_out + game.sequence[0] = 'left'; // 钩子固定期望,注入 doubletap 必判错 + await gesture(game, 'doubletap'); + assert(game.phase === 'gameover', 'G5:input 双击永远=作答(期望非双击时判错到底,不再触发重听)'); + game.stop(); + resetTimers(); +} +{ + settings.set({ guide: 'off' }); + const rig = makeRig(SimonGame); + const { game } = rig; + await driveSimonToInput(rig); + game.sequence[0] = 'doubletap'; + game.sequence[1] = 'left'; + await gesture(game, 'doubletap'); + assert(game.inputIdx === 1, 'off:双击=作答同样成立(玩法映射与向导档无关)'); + await gesture(game, 'up'); + assert(game.chances === 0, 'off:上滑=主动重听同样成立'); + await advance(() => game.phase === 'input'); + await gesture(game, 'doubletap'); + await gesture(game, 'doubletap'); + assert(game.phase === 'gameover', 'off:双击期望非双击时判错(无重听兜底)'); + settings.set({ guide: 'full' }); + game.stop(); + resetTimers(); +} + +// ================================================================ ⑨ G7 space 方向呼喊 + +realLog('== ⑨ G7 space:loud 警报档(撞击前 500ms)同窗 dir_* 超短方向呼喊 =='); +{ + const { audio, playLog, game } = makeRig(SpaceGame); + await audio.unlock(); + game.start(); + await advance(() => game.phase === 'drill'); + await gesture(game, 'down'); // 无悬置演练陨石:下滑跳过演练 + await advance(() => game.phase === 'playing'); + assert(game.phase === 'playing', '前提:跳过演练进对局'); + await advance(() => playLog.some((e) => e.id.startsWith('voice/dir_'))); + const shout = playLog.find((e) => e.id.startsWith('voice/dir_')); + const louds = playLog.filter((e) => e.id === 'sfx/alarm' && e.opts.volume === 1).map((e) => e.t); + assert(['left', 'right', 'up', 'down'].includes(shout.id.slice('voice/dir_'.length)), 'G7:呼喊方向合法'); + assert(louds.some((t) => Math.abs(t - shout.t) < 60), `G7:dir_* 与 loud 警报同窗(≤50ms,实际最小 ${Math.min(...louds.map((t) => Math.abs(t - shout.t)))}ms)`); + game.stop(); + resetTimers(); +} + // ---------------------------------------------------------------- 汇总 realLog(`\n通过 ${passCount} 条断言,失败 ${failures.length} 条`); diff --git a/web/harness/mock.mjs b/web/harness/mock.mjs index 0dbbb28a..3582efe3 100644 --- a/web/harness/mock.mjs +++ b/web/harness/mock.mjs @@ -135,9 +135,12 @@ export function installMock(gameDir) { }; } createScriptProcessor() { return { connect() {}, disconnect() {}, onaudioprocess: null }; } - decodeAudioData() { + decodeAudioData(ab) { + // 时长按这块 buffer 自己的 url 估算(round3 修复:原来读 lastFetched—— + // prewarm 与 play 并发 fetch 时 voice 会随机继承 bgm 的 90s 时长,语音 + // 结束定时器形同虚设、链全靠兜底看门狗推进,tap 也会被"仍在播"的语音吃掉) return Promise.resolve({ - duration: estimateDuration(gameName, lastFetched), + duration: estimateDuration(gameName, ab && ab.__url), numberOfChannels: 1, sampleRate: 44100, getChannelData: () => new Float32Array(16), }); @@ -167,9 +170,11 @@ export function installMock(gameDir) { } const data = fs.readFileSync(p); fetchedLog.push({ url: s, ok: true }); + const ab = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength); + ab.__url = s; // 供 decodeAudioData 按自身 url 估时长(见上) return { ok: true, status: 200, - arrayBuffer: async () => data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength), + arrayBuffer: async () => ab, }; }; diff --git a/web/harness/sessions/escape.mjs b/web/harness/sessions/escape.mjs index f1bb756f..f4b4b213 100644 --- a/web/harness/sessions/escape.mjs +++ b/web/harness/sessions/escape.mjs @@ -66,7 +66,11 @@ export async function session(ctx, mock) { await move('right', '往东走,风声换了个方向'); await move('right'); await move('down', '到了铁柜房,柜子锁着'); - await ctx.gesture('doubletap'); // 用钥匙 → unlock_cabinet(第二间解完) - await ctx.waitVirtual(3000); - ctx.status('柜子开了,拿到保险丝——解到第二间,收工'); + await ctx.gesture('doubletap'); // 用钥匙 → unlock_cabinet + gd_next_fuse(round3 G4) + await ctx.waitVirtual(4200); + ctx.status('柜子开了,听到「保险丝到手。接下来,去找电箱」——目标又有了'); + // round3 G4 剧本:拿到保险丝后再走两步(朝西边的电箱房方向),目标链不断 + await move('left', '照新目标往西摸'); + await move('left', '再走一步,西边隐隐有电流声——电箱在那边'); + ctx.status('解到第二间、照下一目标句又摸了两步,收工'); } diff --git a/web/harness/sessions/rhythm.mjs b/web/harness/sessions/rhythm.mjs index 361a64b3..d48d1ae1 100644 --- a/web/harness/sessions/rhythm.mjs +++ b/web/harness/sessions/rhythm.mjs @@ -1,13 +1,16 @@ /** - * 《节拍行者》新手会话剧本:首局完整走教学 T1-T3 → 曲目一(90 BPM); - * 曲中下滑呼出菜单逛一圈再恢复;第一乐句故意整句漏掉(连 2 Miss 触发向导 - * 「慢了半拍」提示),之后跟着领奏把一曲打完到结算。 + * 《节拍行者》新手会话剧本:首局完整走教学 T1-T3(第 2 句故意连错两遍, + * 触发 round3 G2 的「降速 25% 重演 + gd_slow」,跟着慢速领奏做对后恢复正常) + * → 曲目一(90 BPM);曲中下滑呼出菜单逛一圈再恢复(round3 G3:恢复先听 + * gd_count「四拍之后,继续」,再跟 4 拍底鼓 count-in 进场;首个应答窗口前 + * 整整 1 小节有 gd_answer+turn 交接标记);第一乐句故意整句漏掉(连 2 Miss + * 触发向导「慢了半拍」提示),之后跟着领奏把一曲打完到结算。 */ export function describe(game) { switch (game.phase) { case 'intro': return '开场旁白在播,单击可以跳过'; case 'tut': return game._cues.length - ? `教学:听领奏,下一小节照样打(${game._cues.map((c) => c.gesture).join('→')})` + ? `教学:听领奏,下一小节照样打(${game._cues.map((c) => c.gesture).join('→')})${game._tutRate < 1 ? '(领奏已放慢 25%)' : ''}` : '教学准备中,听鼓点'; case 'select': return '选曲:左右滑换曲,单击开始,下滑回大厅'; case 'main': { @@ -33,6 +36,26 @@ export async function session(ctx, mock) { for (let step = 0; step < 3; step++) { await ctx.waitCond(() => game.phase === 'tut' && game._cues.length > 0 && game._tutAttempts.length === 0); ctx.status(`教学第 ${step + 1}/3 句`); + if (step === 1) { + // round3 G2 剧本:这一句故意连错两遍(整句不出手),听它放慢一些再带着打。 + // 注意 _tutEvaluate 判定即把 _phaseEnd 置 Infinity 防重入——等待一律挂 + // 「持久里程碑」条件(_tutFails/_tutSlowUsed),别挂阶段末时刻。 + await ctx.waitCond(() => game._tutFails === 1); // 失败①:没出手 + ctx.status('第一遍没敢出手,先听它归因'); + await ctx.waitCond(() => game._phaseEnd < 1e8 && t() < game._phaseEnd - 1); // 纠正链播完、重新领奏 + ctx.status('又重新领奏了一遍,还是没敢出手'); + await ctx.waitCond(() => game._tutSlowUsed === true); // 失败② → 触发降速重演 + await ctx.waitCond(() => game._phaseEnd < 1e8 && t() < game._phaseEnd - 1); // gd_slow 播完、慢速领奏已排 + ctx.status('听到「我放慢一些,跟着试试」——领奏降速 25% 重演,这回跟着慢拍打'); + for (const cue of game._cues) { + const at = cue.expected - (cue.gesture === 'tap' ? -0.28 : 0.04); + await ctx.waitCond(() => t() >= at || cue.judged); + if (cue.judged) continue; + await ctx.gesture(cue.gesture); + } + await ctx.waitCond(() => game._tutIdx > step || game.phase !== 'tut'); + continue; + } for (const cue of game._cues) { const at = cue.expected - (cue.gesture === 'tap' ? -0.28 : 0.04); // tap 补偿引擎 ~300ms 延迟 await ctx.waitCond(() => t() >= at || cue.judged); @@ -42,10 +65,11 @@ export async function session(ctx, mock) { await ctx.waitCond(() => game._tutIdx > step || game.phase !== 'tut'); } await ctx.waitCond(() => game.phase === 'main'); - ctx.status('教学完毕,曲目一《启程》90 拍开始'); + ctx.status('教学完毕,曲目一《启程》90 拍开始。领奏响之前先听到「现在跟着我打」'); // 曲中逛菜单:下滑呼出(模态暂停)→ 听选项 → 下滑恢复 - await ctx.waitVirtual(2500); + //(round3 G3:恢复先播「四拍之后,继续」,再跟 4 拍底鼓 count-in 进场) + await ctx.waitCond(() => t() >= game._bgmT0 + 1.5); await ctx.gesture('down'); await ctx.waitCond(() => game.phase === 'menu'); ctx.status('曲中暂停,进了菜单'); @@ -54,6 +78,7 @@ export async function session(ctx, mock) { ctx.note('还是想打完这首,下滑回去'); await ctx.gesture('down'); // 恢复 await ctx.waitCond(() => game.phase === 'main'); + ctx.status('听到「四拍之后,继续」,跟着四下底鼓数拍进来了'); // 第一乐句故意整句不打:连 2 次 Miss → 向导 gd_miss const firstPhrase = game._cues.filter((c) => c.phrase === 0); diff --git a/web/harness/sessions/simon.mjs b/web/harness/sessions/simon.mjs index 93871df9..9fc6d46b 100644 --- a/web/harness/sessions/simon.mjs +++ b/web/harness/sessions/simon.mjs @@ -1,10 +1,10 @@ /** * 《音序回响》新手会话剧本:教学六音一步一步学(中间故意做错一次听纠错)、 - * 收尾听完机会经济句(免费重听两次、用完扣机会);第 1 轮直接答对;第 2 轮开局 - * 忘序列僵住 10 秒,听到向导「双击可以重新听」提示后 5 秒内照做——用掉一次免费 - * 重听(round2:25s 升级已不再自动重播序列,坐着等答案重念的路子废了);第 3 轮 - * 凭记忆答对,在**整轮边界**收工(round2 剧本修正:不在轮中退出——round1 转写 - * 「第 4 轮报数后再没人说话」与「干晾 85 秒」都是剧本失真,不是游戏失真)。 + * 收尾听完机会经济句(round3 G5 重录口径:记不住就向上滑重新听);第 1 轮 + * 直接答对(途中有双击音就演示「双击=作答」);第 2 轮开局忘序列僵住 10 秒, + * 听到向导「向上滑可以重新听」提示后照做——用掉一次免费重听(round3 G5: + * input 双击永远=作答,重听改绑上滑);第 3 轮凭记忆答对,在**整轮边界**收工 + * (round2 剧本修正:不在轮中退出)。 */ export function describe(game) { const GN = { up: '上滑', down: '下滑', left: '左滑', right: '右滑', tap: '单击', doubletap: '双击' }; @@ -16,7 +16,7 @@ export function describe(game) { : '教学旁白在播,先听着'; case 'announce': return `第 ${game.round} 轮报数呢,听好了`; case 'playback': return `第 ${game.round} 轮序列演奏中(${game.sequence.length} 个音),记住顺序,先别动手`; - case 'input': return `第 ${game.round} 轮轮到你了:已对上 ${game.inputIdx}/${game.sequence.length},照原顺序做手势`; + case 'input': return `第 ${game.round} 轮轮到你了:已对上 ${game.inputIdx}/${game.sequence.length},照原顺序做手势(双击就是双击那个音,要重听就向上滑)`; case 'roundend': return '刚答完一轮,播报中'; case 'gameover': return `游戏结束,完成 ${game.round - 1} 轮。单击再来一局,下滑开菜单`; case 'menu': return '菜单里:单击切选项,双击确认,上滑听规则'; @@ -47,28 +47,48 @@ export async function session(ctx, mock) { await ctx.waitIdle(); } } - ctx.status('教学讲完了,机会经济也交代清楚了:免费重听两次,用完要扣机会'); + ctx.status('教学讲完了:免费重听两次、用完扣机会,想重听就向上滑'); // 正式对局:完整打完第 3 轮,在轮边界收工 let relistenDone = false; while (mock.now < 12 * 60 * 1000 && game.phase !== 'gameover') { if (game.phase === 'input') { - // 第 2 轮先失忆僵住 10 秒:听向导「双击可以重新听一遍序列」,5 秒内照做。 - //(期望输入恰为双击时先答这一下,下一步再演示重听——双击语境判定) - if (game.round === 2 && !relistenDone - && game.inputIdx <= 1 && game.sequence[game.inputIdx] !== 'doubletap') { + // 第 1 轮开局先失忆僵 10 秒(还没动过手,input 看门狗在挂):听向导 + // 「向上滑可以重新听一遍序列」,照做——round3 G5:重听已改绑上滑。 + // 测试钩子把序列摆成无 up 的两音,保证上滑=重听不被「期望恰为 up」豁免干扰。 + if (game.round === 1 && !relistenDone && game.inputIdx === 0) { relistenDone = true; - ctx.status('序列有点长,先僵一会儿'); + if (game.sequence.includes('up')) { game.sequence[0] = 'left'; game.sequence[1] = 'tap'; } + ctx.status('第 1 轮有点懵,先僵一会儿'); ctx.silence(10, '想不起来序列了'); - await ctx.waitVirtual(10600); // 10s 看门狗:nudge + gd_relisten - ctx.status('听到提示:需要的话,双击可以重新听一遍序列'); - ctx.note('照提示双击,用掉一次免费重听'); - await ctx.gesture('doubletap'); + // 10s 看门狗到点:nudge + gd_relisten。直接等提示语音开播(input 态无 + // BGM、无别的语音,voiceBusy=提示在播;别用「等满 10.6s」——定时刻度会 + // 恰好迈过语音结束点,等成第二次升级) + await ctx.waitCond(() => ctx.voiceBusy()); + ctx.status('听到提示:需要的话,向上滑可以重新听一遍序列'); + ctx.note('照提示向上滑,用掉一次免费重听'); + await ctx.gesture('up'); await ctx.waitCond(() => game.phase === 'playback' || game.phase === 'input'); continue; } + // 第 2 轮开头演示「期望恰为 up 时上滑=作答」(00 §5.3 豁免同款口径) + if (game.round === 2 && !game.__upDemoDone && game.inputIdx === 0) { + game.__upDemoDone = true; + game.sequence[0] = 'up'; + ctx.status('这个是上行音——上滑作答(期望恰为 up 时上滑=作答)'); + await ctx.gesture('up'); + continue; + } if (game.round === 3 && game.inputIdx === game.sequence.length - 1) { - ctx.status('最后一轮最后一个音,打完这轮就收'); + // round3 G5 演示钩子(13 号文档允许直读/改实例字段):把最后一个期望音 + // 摆成 doubletap,保证转写演示到「input 双击永远=作答」 + if (game.sequence[game.inputIdx] !== 'doubletap' && !game.__dtDemoDone) { + game.__dtDemoDone = true; + game.sequence[game.inputIdx] = 'doubletap'; + } + ctx.status(game.sequence[game.inputIdx] === 'doubletap' + ? '这个是双击音——双击作答(round3:input 双击永远=作答)' + : '最后一轮最后一个音,打完这轮就收'); } else { ctx.status('轮到我复现了'); } diff --git a/web/harness/sessions/space.mjs b/web/harness/sessions/space.mjs index 10ba4151..6c7d0198 100644 --- a/web/harness/sessions/space.mjs +++ b/web/harness/sessions/space.mjs @@ -1,9 +1,10 @@ /** * 《盲航》新手会话剧本:首局完整演练 D1-D4(第二颗故意超时,听当场重教)→ - * 正式对局躲过保护期(20s/45s 的加速/护盾引入都照做)→ 保护期结束后故意漏两颗 - * (第 1 次听归因+向导「同向滑动就能拨开」,第 2 次听 gd_last_life「最后一次机会」 - * ——round2 F2.2:受击经济透明)→ 之后全部躲开,保护期结束后再撑 20 秒以上收工 - * (不再像 round1 那样在保护期后 8 秒就撤,也没有第三次被撞)。 + * 正式对局躲过保护期(20s/45s 的加速/护盾引入都照做)→ 每颗陨石都撑到 loud + * 警报档(撞击前 500ms:警报 + dir_* 方向呼喊同时响,round3 G7)才拨开 → + * 保护期结束后故意漏两颗(第 1 次听归因+向导「同向滑动就能拨开」,第 2 次听 + * gd_last_life「最后一次机会」——round2 F2.2:受击经济透明)→ 之后全部躲开, + * 保护期结束后再撑 20 秒以上收工。 */ export function describe(game) { const DIR = { left: '左边', right: '右边', up: '上面', down: '下面' }; @@ -48,7 +49,9 @@ export async function session(ctx, mock) { ctx.status('演练做完了,要出发了'); // 正式对局:保护期 60s + 结束后再撑 20s 以上收工。 - // 每颗陨石生成(呼啸声起)就在判定窗口将开时同向拨开——比盯着 1.5s 判定窗口更稳。 + // 每颗陨石都撑到 loud 警报档(撞击前 500ms:第二段警报 + 「左!/右!…」方向 + // 呼喊同时响,round3 G7)才同向拨开——仍在 1.5s 判定窗口内,稳。呼喊与警报 + // 同一刻先落,随即滑开(=500ms 阈值恰在 loud 警报定时器触发点上)。 //(刷怪链是自驱动的定时器链——禁止裸 waitIdle,等待一律挂条件) await ctx.waitCond(() => game.phase === 'playing'); ctx.status('出发。引擎声起来了,保护期里先练手'); @@ -75,9 +78,10 @@ export async function session(ctx, mock) { : '被撞了。先听到方位归因,又听到「同向滑动就能拨开」'); continue; } - // 只在判定窗口将开未开时出手(警报第一响 = 撞击前 1s,窗口内) + // 撑到 loud 警报档(撞击前 0.5s,第二段警报 + dir 方向呼喊同窗)再出手 + //(=500ms 恰在 loud 警报定时器触发点:呼喊先落,同一拍跟着滑开) const target = [...game.obstacles].find((o) => !dodged.has(o) - && o.impactAt - performance.now() < 1300); + && o.impactAt - performance.now() <= 500); if (target) { if (eaten < 2 && performance.now() >= game.protectionUntil) { eaten++; @@ -89,13 +93,14 @@ export async function session(ctx, mock) { continue; } dodged.add(target); + ctx.note('听到第二段警报和方向呼喊,同向滑开'); await ctx.gesture(target.dir); continue; } await ctx.waitCond(() => game.phase !== 'playing' || victims.some((v) => !game.obstacles.has(v)) - || [...game.obstacles].some((o) => !dodged.has(o) && o.impactAt - performance.now() < 1300)); + || [...game.obstacles].some((o) => !dodged.has(o) && o.impactAt - performance.now() <= 500)); } const aliveSec = Math.round((performance.now() - game.runStart) / 1000); - ctx.status(`保护期结束后撑了 ${aliveSec - 60} 秒、挨了两下还活着(警报也只起一波了),先到这`); + ctx.status(`保护期结束后撑了 ${aliveSec - 60} 秒、挨了两下还活着;每回撞击前半秒都能听到方向呼喊,先到这`); } diff --git a/web/harness/voice_text.json b/web/harness/voice_text.json index 0c99d203..5aac951b 100644 --- a/web/harness/voice_text.json +++ b/web/harness/voice_text.json @@ -129,7 +129,8 @@ "menu_restart": "重新开始。", "menu_home": "回大厅。", "menu_back": "返回游戏。", - "skip_hint": "单击可跳过旁白。" + "skip_hint": "单击可跳过旁白。", + "gd_next_fuse": "保险丝到手。接下来,去找电箱。" }, "simon": { "t0_welcome": "欢迎来到音序回响。先认识六种声音。", @@ -155,7 +156,7 @@ "t_blunt_tap": "用指尖,轻轻点一下屏幕。", "t_blunt_double": "用指尖,快速点两下屏幕。", "t7_ready": "六种声音都记住了。后面的序列,会越来越长。", - "t7_retry": "答错可以消耗机会重听。双击,可以随时重听。", + "t7_retry": "答错可以消耗机会重听。向上滑,可以随时重听。", "t_skip": "跳过教学,直接开始。", "round_01": "第一轮,听好了。", "round_02": "第二轮,听好了。", @@ -201,8 +202,10 @@ "menu_home": "回大厅。", "menu_back": "返回游戏。", "skip_hint": "单击可跳过旁白。", - "gd_relisten": "需要的话,双击可以重新听一遍序列。", - "gd_economy": "记不住就双击重新听,免费机会有两次,用完要扣一次机会。" + "gd_relisten": "需要的话,向上滑可以重新听一遍序列。", + "gd_economy": "记不住就向上滑,重新听一遍。免费机会有两次,用完要扣一次机会。", + "gd_clear": "漂亮,过了。", + "gd_record": "破纪录了。" }, "rhythm": { "welcome": "欢迎来到节拍行者。跟着音乐,我奏一句,你跟一句。", @@ -241,7 +244,9 @@ "gd_miss": "慢了半拍,下一小节跟上我就行。", "gd_miss_early": "抢拍了。等声音落下再滑。", "gd_miss_late": "慢了半拍。跟着节拍走。", - "gd_miss_wrong": "方向不对。跟着音色滑。" + "gd_miss_wrong": "方向不对。跟着音色滑。", + "gd_slow": "我放慢一些,跟着试试。", + "gd_count": "四拍之后,继续。" }, "space": { "drill_welcome": "欢迎登上盲航。你只有一双耳朵。", @@ -298,7 +303,11 @@ "paused": "已暂停。", "skip_hint": "单击可跳过旁白。", "gd_hit_hint": "被撞了。听方位,同向滑动就能拨开。", - "gd_last_life": "这是最后一次机会,撑住。" + "gd_last_life": "这是最后一次机会,撑住。", + "dir_left": "左!", + "dir_right": "右!", + "dir_up": "上!", + "dir_down": "下!" }, "rpg": { "intro_1": "你的眼睛看不见了。但你的耳朵,比谁都灵。", diff --git a/web/rhythm/audio/voice/female/gd_answer.ogg b/web/rhythm/audio/voice/female/gd_answer.ogg index 54cf7c78..3ff19bb7 100644 Binary files a/web/rhythm/audio/voice/female/gd_answer.ogg and b/web/rhythm/audio/voice/female/gd_answer.ogg differ diff --git a/web/rhythm/audio/voice/female/gd_count.m4a b/web/rhythm/audio/voice/female/gd_count.m4a new file mode 100644 index 00000000..967657de Binary files /dev/null and b/web/rhythm/audio/voice/female/gd_count.m4a differ diff --git a/web/rhythm/audio/voice/female/gd_count.ogg b/web/rhythm/audio/voice/female/gd_count.ogg new file mode 100644 index 00000000..74cdf7df Binary files /dev/null and b/web/rhythm/audio/voice/female/gd_count.ogg differ diff --git a/web/rhythm/audio/voice/female/gd_miss.ogg b/web/rhythm/audio/voice/female/gd_miss.ogg index 7088ded8..20b9aee4 100644 Binary files a/web/rhythm/audio/voice/female/gd_miss.ogg and b/web/rhythm/audio/voice/female/gd_miss.ogg differ diff --git a/web/rhythm/audio/voice/female/gd_miss_early.ogg b/web/rhythm/audio/voice/female/gd_miss_early.ogg index a5678913..3cde7f70 100644 Binary files a/web/rhythm/audio/voice/female/gd_miss_early.ogg and b/web/rhythm/audio/voice/female/gd_miss_early.ogg differ diff --git a/web/rhythm/audio/voice/female/gd_miss_late.ogg b/web/rhythm/audio/voice/female/gd_miss_late.ogg index 23670137..41caf75e 100644 Binary files a/web/rhythm/audio/voice/female/gd_miss_late.ogg and b/web/rhythm/audio/voice/female/gd_miss_late.ogg differ diff --git a/web/rhythm/audio/voice/female/gd_miss_wrong.ogg b/web/rhythm/audio/voice/female/gd_miss_wrong.ogg index ada22fea..41bcec64 100644 Binary files a/web/rhythm/audio/voice/female/gd_miss_wrong.ogg and b/web/rhythm/audio/voice/female/gd_miss_wrong.ogg differ diff --git a/web/rhythm/audio/voice/female/gd_slow.m4a b/web/rhythm/audio/voice/female/gd_slow.m4a new file mode 100644 index 00000000..c458a560 Binary files /dev/null and b/web/rhythm/audio/voice/female/gd_slow.m4a differ diff --git a/web/rhythm/audio/voice/female/gd_slow.ogg b/web/rhythm/audio/voice/female/gd_slow.ogg new file mode 100644 index 00000000..2c1d21b6 Binary files /dev/null and b/web/rhythm/audio/voice/female/gd_slow.ogg differ diff --git a/web/rhythm/audio/voice/female/grade_a.ogg b/web/rhythm/audio/voice/female/grade_a.ogg index ab62e5a9..16870f64 100644 Binary files a/web/rhythm/audio/voice/female/grade_a.ogg and b/web/rhythm/audio/voice/female/grade_a.ogg differ diff --git a/web/rhythm/audio/voice/female/grade_b.ogg b/web/rhythm/audio/voice/female/grade_b.ogg index e1ca00e8..a3991f4c 100644 Binary files a/web/rhythm/audio/voice/female/grade_b.ogg and b/web/rhythm/audio/voice/female/grade_b.ogg differ diff --git a/web/rhythm/audio/voice/female/grade_c.ogg b/web/rhythm/audio/voice/female/grade_c.ogg index 73042093..b7e99563 100644 Binary files a/web/rhythm/audio/voice/female/grade_c.ogg and b/web/rhythm/audio/voice/female/grade_c.ogg differ diff --git a/web/rhythm/audio/voice/female/grade_s.ogg b/web/rhythm/audio/voice/female/grade_s.ogg index ca82729a..98481fc3 100644 Binary files a/web/rhythm/audio/voice/female/grade_s.ogg and b/web/rhythm/audio/voice/female/grade_s.ogg differ diff --git a/web/rhythm/audio/voice/female/menu_lobby.ogg b/web/rhythm/audio/voice/female/menu_lobby.ogg index ab937a9d..e417f21e 100644 Binary files a/web/rhythm/audio/voice/female/menu_lobby.ogg and b/web/rhythm/audio/voice/female/menu_lobby.ogg differ diff --git a/web/rhythm/audio/voice/female/menu_main.ogg b/web/rhythm/audio/voice/female/menu_main.ogg index 11f3a76c..a8a6dcc8 100644 Binary files a/web/rhythm/audio/voice/female/menu_main.ogg and b/web/rhythm/audio/voice/female/menu_main.ogg differ diff --git a/web/rhythm/audio/voice/female/menu_resume.ogg b/web/rhythm/audio/voice/female/menu_resume.ogg index 5956079b..89d9e484 100644 Binary files a/web/rhythm/audio/voice/female/menu_resume.ogg and b/web/rhythm/audio/voice/female/menu_resume.ogg differ diff --git a/web/rhythm/audio/voice/female/mid_song.ogg b/web/rhythm/audio/voice/female/mid_song.ogg index fd306797..788c843b 100644 Binary files a/web/rhythm/audio/voice/female/mid_song.ogg and b/web/rhythm/audio/voice/female/mid_song.ogg differ diff --git a/web/rhythm/audio/voice/female/new_best_combo.ogg b/web/rhythm/audio/voice/female/new_best_combo.ogg index b23d0068..bf378a82 100644 Binary files a/web/rhythm/audio/voice/female/new_best_combo.ogg and b/web/rhythm/audio/voice/female/new_best_combo.ogg differ diff --git a/web/rhythm/audio/voice/female/restart.ogg b/web/rhythm/audio/voice/female/restart.ogg index 51869350..71edbf0f 100644 Binary files a/web/rhythm/audio/voice/female/restart.ogg and b/web/rhythm/audio/voice/female/restart.ogg differ diff --git a/web/rhythm/audio/voice/female/retry_early.ogg b/web/rhythm/audio/voice/female/retry_early.ogg index 24f61b10..18e11d75 100644 Binary files a/web/rhythm/audio/voice/female/retry_early.ogg and b/web/rhythm/audio/voice/female/retry_early.ogg differ diff --git a/web/rhythm/audio/voice/female/retry_gesture.ogg b/web/rhythm/audio/voice/female/retry_gesture.ogg index 6ab4308b..0a20dd98 100644 Binary files a/web/rhythm/audio/voice/female/retry_gesture.ogg and b/web/rhythm/audio/voice/female/retry_gesture.ogg differ diff --git a/web/rhythm/audio/voice/female/retry_late.ogg b/web/rhythm/audio/voice/female/retry_late.ogg index b8fe1b6b..fb3cb96e 100644 Binary files a/web/rhythm/audio/voice/female/retry_late.ogg and b/web/rhythm/audio/voice/female/retry_late.ogg differ diff --git a/web/rhythm/audio/voice/female/retry_listen.ogg b/web/rhythm/audio/voice/female/retry_listen.ogg index 01bd0be8..02143167 100644 Binary files a/web/rhythm/audio/voice/female/retry_listen.ogg and b/web/rhythm/audio/voice/female/retry_listen.ogg differ diff --git a/web/rhythm/audio/voice/female/retry_skip.ogg b/web/rhythm/audio/voice/female/retry_skip.ogg index 7e81d586..8b846e56 100644 Binary files a/web/rhythm/audio/voice/female/retry_skip.ogg and b/web/rhythm/audio/voice/female/retry_skip.ogg differ diff --git a/web/rhythm/audio/voice/female/rules.ogg b/web/rhythm/audio/voice/female/rules.ogg index ce34e482..e2c9fd9a 100644 Binary files a/web/rhythm/audio/voice/female/rules.ogg and b/web/rhythm/audio/voice/female/rules.ogg differ diff --git a/web/rhythm/audio/voice/female/select_hint.ogg b/web/rhythm/audio/voice/female/select_hint.ogg index 81bacab7..ebd7808b 100644 Binary files a/web/rhythm/audio/voice/female/select_hint.ogg and b/web/rhythm/audio/voice/female/select_hint.ogg differ diff --git a/web/rhythm/audio/voice/female/settings_hint.ogg b/web/rhythm/audio/voice/female/settings_hint.ogg index 45338c6d..638cd593 100644 Binary files a/web/rhythm/audio/voice/female/settings_hint.ogg and b/web/rhythm/audio/voice/female/settings_hint.ogg differ diff --git a/web/rhythm/audio/voice/female/skip_hint.ogg b/web/rhythm/audio/voice/female/skip_hint.ogg index 1593fa46..10319632 100644 Binary files a/web/rhythm/audio/voice/female/skip_hint.ogg and b/web/rhythm/audio/voice/female/skip_hint.ogg differ diff --git a/web/rhythm/audio/voice/female/song1_name.ogg b/web/rhythm/audio/voice/female/song1_name.ogg index 0c97ae19..69650cbb 100644 Binary files a/web/rhythm/audio/voice/female/song1_name.ogg and b/web/rhythm/audio/voice/female/song1_name.ogg differ diff --git a/web/rhythm/audio/voice/female/song2_name.ogg b/web/rhythm/audio/voice/female/song2_name.ogg index af361943..4c04350f 100644 Binary files a/web/rhythm/audio/voice/female/song2_name.ogg and b/web/rhythm/audio/voice/female/song2_name.ogg differ diff --git a/web/rhythm/audio/voice/female/song3_name.ogg b/web/rhythm/audio/voice/female/song3_name.ogg index a0370148..07ab57f0 100644 Binary files a/web/rhythm/audio/voice/female/song3_name.ogg and b/web/rhythm/audio/voice/female/song3_name.ogg differ diff --git a/web/rhythm/audio/voice/female/song_locked.ogg b/web/rhythm/audio/voice/female/song_locked.ogg index 0183d2d3..1b958238 100644 Binary files a/web/rhythm/audio/voice/female/song_locked.ogg and b/web/rhythm/audio/voice/female/song_locked.ogg differ diff --git a/web/rhythm/audio/voice/female/tut_1.ogg b/web/rhythm/audio/voice/female/tut_1.ogg index 85ffe52b..2ccda92f 100644 Binary files a/web/rhythm/audio/voice/female/tut_1.ogg and b/web/rhythm/audio/voice/female/tut_1.ogg differ diff --git a/web/rhythm/audio/voice/female/tut_2.ogg b/web/rhythm/audio/voice/female/tut_2.ogg index 6626e3fe..5ea6d50d 100644 Binary files a/web/rhythm/audio/voice/female/tut_2.ogg and b/web/rhythm/audio/voice/female/tut_2.ogg differ diff --git a/web/rhythm/audio/voice/female/tut_3.ogg b/web/rhythm/audio/voice/female/tut_3.ogg index eb11d243..33942add 100644 Binary files a/web/rhythm/audio/voice/female/tut_3.ogg and b/web/rhythm/audio/voice/female/tut_3.ogg differ diff --git a/web/rhythm/audio/voice/female/tut_done.ogg b/web/rhythm/audio/voice/female/tut_done.ogg index 854b4adc..9314d5ea 100644 Binary files a/web/rhythm/audio/voice/female/tut_done.ogg and b/web/rhythm/audio/voice/female/tut_done.ogg differ diff --git a/web/rhythm/audio/voice/female/tut_skip.ogg b/web/rhythm/audio/voice/female/tut_skip.ogg index d99131ab..f8ba89d5 100644 Binary files a/web/rhythm/audio/voice/female/tut_skip.ogg and b/web/rhythm/audio/voice/female/tut_skip.ogg differ diff --git a/web/rhythm/audio/voice/female/unlock_song2.ogg b/web/rhythm/audio/voice/female/unlock_song2.ogg index 592e7dfb..c87ff460 100644 Binary files a/web/rhythm/audio/voice/female/unlock_song2.ogg and b/web/rhythm/audio/voice/female/unlock_song2.ogg differ diff --git a/web/rhythm/audio/voice/female/unlock_song3.ogg b/web/rhythm/audio/voice/female/unlock_song3.ogg index 3e16048f..c210cb71 100644 Binary files a/web/rhythm/audio/voice/female/unlock_song3.ogg and b/web/rhythm/audio/voice/female/unlock_song3.ogg differ diff --git a/web/rhythm/audio/voice/female/welcome.ogg b/web/rhythm/audio/voice/female/welcome.ogg index 825570a1..274c0c24 100644 Binary files a/web/rhythm/audio/voice/female/welcome.ogg and b/web/rhythm/audio/voice/female/welcome.ogg differ diff --git a/web/rhythm/audio/voice/female/welcome_back.ogg b/web/rhythm/audio/voice/female/welcome_back.ogg index bdab9883..3b7f009c 100644 Binary files a/web/rhythm/audio/voice/female/welcome_back.ogg and b/web/rhythm/audio/voice/female/welcome_back.ogg differ diff --git a/web/rhythm/audio/voice/male/gd_answer.ogg b/web/rhythm/audio/voice/male/gd_answer.ogg index 106a1050..5ec1ddbf 100644 Binary files a/web/rhythm/audio/voice/male/gd_answer.ogg and b/web/rhythm/audio/voice/male/gd_answer.ogg differ diff --git a/web/rhythm/audio/voice/male/gd_count.m4a b/web/rhythm/audio/voice/male/gd_count.m4a new file mode 100644 index 00000000..0dda9616 Binary files /dev/null and b/web/rhythm/audio/voice/male/gd_count.m4a differ diff --git a/web/rhythm/audio/voice/male/gd_count.ogg b/web/rhythm/audio/voice/male/gd_count.ogg new file mode 100644 index 00000000..d3906913 Binary files /dev/null and b/web/rhythm/audio/voice/male/gd_count.ogg differ diff --git a/web/rhythm/audio/voice/male/gd_miss.ogg b/web/rhythm/audio/voice/male/gd_miss.ogg index 4920033d..e732e7bd 100644 Binary files a/web/rhythm/audio/voice/male/gd_miss.ogg and b/web/rhythm/audio/voice/male/gd_miss.ogg differ diff --git a/web/rhythm/audio/voice/male/gd_miss_early.ogg b/web/rhythm/audio/voice/male/gd_miss_early.ogg index 03c6c473..27dbf890 100644 Binary files a/web/rhythm/audio/voice/male/gd_miss_early.ogg and b/web/rhythm/audio/voice/male/gd_miss_early.ogg differ diff --git a/web/rhythm/audio/voice/male/gd_miss_late.ogg b/web/rhythm/audio/voice/male/gd_miss_late.ogg index 830b08ae..b5b117ae 100644 Binary files a/web/rhythm/audio/voice/male/gd_miss_late.ogg and b/web/rhythm/audio/voice/male/gd_miss_late.ogg differ diff --git a/web/rhythm/audio/voice/male/gd_miss_wrong.ogg b/web/rhythm/audio/voice/male/gd_miss_wrong.ogg index 77bab56f..0a2ef29c 100644 Binary files a/web/rhythm/audio/voice/male/gd_miss_wrong.ogg and b/web/rhythm/audio/voice/male/gd_miss_wrong.ogg differ diff --git a/web/rhythm/audio/voice/male/gd_slow.m4a b/web/rhythm/audio/voice/male/gd_slow.m4a new file mode 100644 index 00000000..fae8e566 Binary files /dev/null and b/web/rhythm/audio/voice/male/gd_slow.m4a differ diff --git a/web/rhythm/audio/voice/male/gd_slow.ogg b/web/rhythm/audio/voice/male/gd_slow.ogg new file mode 100644 index 00000000..81aee20f Binary files /dev/null and b/web/rhythm/audio/voice/male/gd_slow.ogg differ diff --git a/web/rhythm/audio/voice/male/grade_a.ogg b/web/rhythm/audio/voice/male/grade_a.ogg index 49fec51d..755e7990 100644 Binary files a/web/rhythm/audio/voice/male/grade_a.ogg and b/web/rhythm/audio/voice/male/grade_a.ogg differ diff --git a/web/rhythm/audio/voice/male/grade_b.ogg b/web/rhythm/audio/voice/male/grade_b.ogg index 52b0035f..1f51a6cf 100644 Binary files a/web/rhythm/audio/voice/male/grade_b.ogg and b/web/rhythm/audio/voice/male/grade_b.ogg differ diff --git a/web/rhythm/audio/voice/male/grade_c.ogg b/web/rhythm/audio/voice/male/grade_c.ogg index 52b94b44..6358f27d 100644 Binary files a/web/rhythm/audio/voice/male/grade_c.ogg and b/web/rhythm/audio/voice/male/grade_c.ogg differ diff --git a/web/rhythm/audio/voice/male/grade_s.ogg b/web/rhythm/audio/voice/male/grade_s.ogg index 48421749..87c71f27 100644 Binary files a/web/rhythm/audio/voice/male/grade_s.ogg and b/web/rhythm/audio/voice/male/grade_s.ogg differ diff --git a/web/rhythm/audio/voice/male/menu_lobby.ogg b/web/rhythm/audio/voice/male/menu_lobby.ogg index 96d66510..701a0eda 100644 Binary files a/web/rhythm/audio/voice/male/menu_lobby.ogg and b/web/rhythm/audio/voice/male/menu_lobby.ogg differ diff --git a/web/rhythm/audio/voice/male/menu_main.ogg b/web/rhythm/audio/voice/male/menu_main.ogg index 8c2054c2..438138d0 100644 Binary files a/web/rhythm/audio/voice/male/menu_main.ogg and b/web/rhythm/audio/voice/male/menu_main.ogg differ diff --git a/web/rhythm/audio/voice/male/menu_resume.ogg b/web/rhythm/audio/voice/male/menu_resume.ogg index 296c4651..d9ed7930 100644 Binary files a/web/rhythm/audio/voice/male/menu_resume.ogg and b/web/rhythm/audio/voice/male/menu_resume.ogg differ diff --git a/web/rhythm/audio/voice/male/mid_song.ogg b/web/rhythm/audio/voice/male/mid_song.ogg index bef065ff..bb3c3d2b 100644 Binary files a/web/rhythm/audio/voice/male/mid_song.ogg and b/web/rhythm/audio/voice/male/mid_song.ogg differ diff --git a/web/rhythm/audio/voice/male/new_best_combo.ogg b/web/rhythm/audio/voice/male/new_best_combo.ogg index a280fb70..00f25a36 100644 Binary files a/web/rhythm/audio/voice/male/new_best_combo.ogg and b/web/rhythm/audio/voice/male/new_best_combo.ogg differ diff --git a/web/rhythm/audio/voice/male/restart.ogg b/web/rhythm/audio/voice/male/restart.ogg index b5b1bc1f..18445bd7 100644 Binary files a/web/rhythm/audio/voice/male/restart.ogg and b/web/rhythm/audio/voice/male/restart.ogg differ diff --git a/web/rhythm/audio/voice/male/retry_early.ogg b/web/rhythm/audio/voice/male/retry_early.ogg index 5391328a..43127b18 100644 Binary files a/web/rhythm/audio/voice/male/retry_early.ogg and b/web/rhythm/audio/voice/male/retry_early.ogg differ diff --git a/web/rhythm/audio/voice/male/retry_gesture.ogg b/web/rhythm/audio/voice/male/retry_gesture.ogg index a5076f68..4566341c 100644 Binary files a/web/rhythm/audio/voice/male/retry_gesture.ogg and b/web/rhythm/audio/voice/male/retry_gesture.ogg differ diff --git a/web/rhythm/audio/voice/male/retry_late.ogg b/web/rhythm/audio/voice/male/retry_late.ogg index 9fc04bb2..87466c37 100644 Binary files a/web/rhythm/audio/voice/male/retry_late.ogg and b/web/rhythm/audio/voice/male/retry_late.ogg differ diff --git a/web/rhythm/audio/voice/male/retry_listen.ogg b/web/rhythm/audio/voice/male/retry_listen.ogg index 755cb5e2..2b11865e 100644 Binary files a/web/rhythm/audio/voice/male/retry_listen.ogg and b/web/rhythm/audio/voice/male/retry_listen.ogg differ diff --git a/web/rhythm/audio/voice/male/retry_skip.ogg b/web/rhythm/audio/voice/male/retry_skip.ogg index b494fc52..87736d99 100644 Binary files a/web/rhythm/audio/voice/male/retry_skip.ogg and b/web/rhythm/audio/voice/male/retry_skip.ogg differ diff --git a/web/rhythm/audio/voice/male/rules.ogg b/web/rhythm/audio/voice/male/rules.ogg index 3cc74346..15de1e18 100644 Binary files a/web/rhythm/audio/voice/male/rules.ogg and b/web/rhythm/audio/voice/male/rules.ogg differ diff --git a/web/rhythm/audio/voice/male/select_hint.ogg b/web/rhythm/audio/voice/male/select_hint.ogg index 69afb7ea..d01c8594 100644 Binary files a/web/rhythm/audio/voice/male/select_hint.ogg and b/web/rhythm/audio/voice/male/select_hint.ogg differ diff --git a/web/rhythm/audio/voice/male/settings_hint.ogg b/web/rhythm/audio/voice/male/settings_hint.ogg index 23ffed3f..9eb0c70b 100644 Binary files a/web/rhythm/audio/voice/male/settings_hint.ogg and b/web/rhythm/audio/voice/male/settings_hint.ogg differ diff --git a/web/rhythm/audio/voice/male/skip_hint.ogg b/web/rhythm/audio/voice/male/skip_hint.ogg index 453d6edb..84b4f847 100644 Binary files a/web/rhythm/audio/voice/male/skip_hint.ogg and b/web/rhythm/audio/voice/male/skip_hint.ogg differ diff --git a/web/rhythm/audio/voice/male/song1_name.ogg b/web/rhythm/audio/voice/male/song1_name.ogg index 2c75d33d..02967ed6 100644 Binary files a/web/rhythm/audio/voice/male/song1_name.ogg and b/web/rhythm/audio/voice/male/song1_name.ogg differ diff --git a/web/rhythm/audio/voice/male/song2_name.ogg b/web/rhythm/audio/voice/male/song2_name.ogg index cc0edc81..5f404054 100644 Binary files a/web/rhythm/audio/voice/male/song2_name.ogg and b/web/rhythm/audio/voice/male/song2_name.ogg differ diff --git a/web/rhythm/audio/voice/male/song3_name.ogg b/web/rhythm/audio/voice/male/song3_name.ogg index 434d1dda..7100b68c 100644 Binary files a/web/rhythm/audio/voice/male/song3_name.ogg and b/web/rhythm/audio/voice/male/song3_name.ogg differ diff --git a/web/rhythm/audio/voice/male/song_locked.ogg b/web/rhythm/audio/voice/male/song_locked.ogg index 8c3bf39d..f01ccb41 100644 Binary files a/web/rhythm/audio/voice/male/song_locked.ogg and b/web/rhythm/audio/voice/male/song_locked.ogg differ diff --git a/web/rhythm/audio/voice/male/tut_1.ogg b/web/rhythm/audio/voice/male/tut_1.ogg index 2d6d55ca..b5cb3740 100644 Binary files a/web/rhythm/audio/voice/male/tut_1.ogg and b/web/rhythm/audio/voice/male/tut_1.ogg differ diff --git a/web/rhythm/audio/voice/male/tut_2.ogg b/web/rhythm/audio/voice/male/tut_2.ogg index 9e3cb2ca..9413b731 100644 Binary files a/web/rhythm/audio/voice/male/tut_2.ogg and b/web/rhythm/audio/voice/male/tut_2.ogg differ diff --git a/web/rhythm/audio/voice/male/tut_3.ogg b/web/rhythm/audio/voice/male/tut_3.ogg index eae12816..709e7cf3 100644 Binary files a/web/rhythm/audio/voice/male/tut_3.ogg and b/web/rhythm/audio/voice/male/tut_3.ogg differ diff --git a/web/rhythm/audio/voice/male/tut_done.ogg b/web/rhythm/audio/voice/male/tut_done.ogg index fbfb1c91..8c8a2816 100644 Binary files a/web/rhythm/audio/voice/male/tut_done.ogg and b/web/rhythm/audio/voice/male/tut_done.ogg differ diff --git a/web/rhythm/audio/voice/male/tut_skip.ogg b/web/rhythm/audio/voice/male/tut_skip.ogg index 34c76a88..f7f0c4c3 100644 Binary files a/web/rhythm/audio/voice/male/tut_skip.ogg and b/web/rhythm/audio/voice/male/tut_skip.ogg differ diff --git a/web/rhythm/audio/voice/male/unlock_song2.ogg b/web/rhythm/audio/voice/male/unlock_song2.ogg index b9bde096..c6ed5bb1 100644 Binary files a/web/rhythm/audio/voice/male/unlock_song2.ogg and b/web/rhythm/audio/voice/male/unlock_song2.ogg differ diff --git a/web/rhythm/audio/voice/male/unlock_song3.ogg b/web/rhythm/audio/voice/male/unlock_song3.ogg index 8befb271..6cd7d96d 100644 Binary files a/web/rhythm/audio/voice/male/unlock_song3.ogg and b/web/rhythm/audio/voice/male/unlock_song3.ogg differ diff --git a/web/rhythm/audio/voice/male/welcome.ogg b/web/rhythm/audio/voice/male/welcome.ogg index c3c52224..b4dda543 100644 Binary files a/web/rhythm/audio/voice/male/welcome.ogg and b/web/rhythm/audio/voice/male/welcome.ogg differ diff --git a/web/rhythm/audio/voice/male/welcome_back.ogg b/web/rhythm/audio/voice/male/welcome_back.ogg index 36057ad9..38527a84 100644 Binary files a/web/rhythm/audio/voice/male/welcome_back.ogg and b/web/rhythm/audio/voice/male/welcome_back.ogg differ diff --git a/web/rhythm/game.js b/web/rhythm/game.js index c4b2de43..652a5f33 100644 --- a/web/rhythm/game.js +++ b/web/rhythm/game.js @@ -35,13 +35,18 @@ * main 演奏阶段单击是演奏手势不跳(mid_song 短句按裁定不跳)。 * 长按快进豁免(12 文档 §2.2:main 演奏期):audio.setRateBoostEnabled(false) * per-game 开关(引擎已支持),进 main 关、进菜单/结算/退出恢复。 - * 向导层(docs/design/14-guide-layer.md + round2 synthesis F2.1/F3):每曲首次 - * 领奏→应答切换在谱面定时队列直接落 gd_answer(不走 guide queue,保证窗口前 - * 听到)+ turn earcon;教学 Miss 首次即归因分档(gd_miss_early/late/wrong, - * 挂纠正链尾空闲点);连续 2 Miss 播 gd_miss(queue 插播,同曲一次);暂停 - * 断点续播前插 4 拍 count-in(off 档保持即时续播);结算链换 _speakGuarded - * (资产缺失不卡结算 BGM);状态签名 earcon 与状态 BGM 同点 - * (select=menu、main=battle、end=settle)。 + * 向导层(docs/design/14-guide-layer.md + round2 synthesis F2.1/F3 + round3 G1~G3): + * 每曲首次领奏→应答切换在谱面定时队列直接落 gd_answer(不走 guide queue,保证 + * 窗口前听到)+ turn earcon;round3 G1 修正排程点:落在首个应答窗口**前整整 + * 1 小节**(= 领奏小节头;round2 排在窗口起点本身,P4 实测窗口开了才听到), + * 菜单恢复对下一个未判定窗口重排同款标记;教学 Miss 首次即归因分档 + * (gd_miss_early/late/wrong,挂纠正链尾空闲点);连续 2 Miss 播 gd_miss(queue + * 插播,同曲一次);暂停断点续播前插 4 拍 count-in(round3 G3:底鼓 sfx 层可辨 + * 音量 + full 档 gd_count 每局恢复限 1 次 + beat 震;round2 版因 push 后未重排 + * _sched 被队头卡死从未按时响过;off 档保持即时续播);教学 DDA(round3 G2): + * 同一步连 2 次失败该步领奏降速 25% 重演并播 gd_slow(full 档、每教学局 1 次, + * off 档维持 retry_skip 原路径);结算链换 _speakGuarded(资产缺失不卡结算 BGM); + * 状态签名 earcon 与状态 BGM 同点(select=menu、main=battle、end=settle)。 */ import { Game } from '../engine/game.js'; import { Guide } from '../engine/guide.js'; @@ -159,10 +164,15 @@ export class RhythmGame extends Game { this._tutIdx = 0; this._tutFails = 0; this._tutAttempts = []; + this._tutRate = 1.0; // G2:教学领奏速率(0.75 = 降速 25%,做对/离开该步恢复 1.0) + this._tutSlowUsed = false; // G2:降速重演每教学局 1 次封顶 // 菜单/暂停状态 this._menuIdx = 0; this._pauseAt = 0; this._bgmOffset = 0; + this._resumeSeq = 0; // G3:恢复令牌(count-in 语音期间再开菜单时作废旧恢复) + this._gdCountUsed = false; // G3:gd_count 每局(曲)恢复限 1 次 + this._answerArmed = false; // G1:gd_answer+turn 交接标记是否已在 _timed 里待响 this._consecMiss = 0; // 连续 Miss 计数(向导 gd_miss:连 2 次提示一次) } @@ -173,6 +183,9 @@ export class RhythmGame extends Game { 'voice/tut_1', 'voice/select_hint', 'bgm/menu', ...SONGS.map((s) => s.bgm)]); const rid = ++this._runId; this._cleanup(); + this._tutRate = 1.0; + this._tutSlowUsed = false; // G2:每教学局重新封顶 + this._gdCountUsed = false; // G3:每局(曲)恢复限 1 次 if (this._progress.tutorialDone) { // 二周目起:缩减开场 → 选曲 this.phase = 'intro'; @@ -309,10 +322,13 @@ export class RhythmGame extends Game { + Math.max(0, Math.ceil((now + 1.2 - this._bgmT0) / (4 * spb))) * 4 * spb; this._tutAttempts = []; this._cues = []; + // G2(round3):降速只拉伸该步的领奏/应答网格(间隔 ×1/0.75),领奏小节头 + // 仍对齐 BGM 小节;排程照走 _sched 绝对时间 + 40ms 泵,泵与判定无需感知速率。 + const stepSpb = spb / this._tutRate; for (const [beat, g] of TUT_STEPS[this._tutIdx].notes) { - const t = leadBar + (beat - 1) * spb; + const t = leadBar + (beat - 1) * stepSpb; this._sched.push({ time: t, sfx: INST[g], volume: 1 }); - this._cues.push({ gesture: g, expected: t + 4 * spb, judged: false, phrase: -1 }); + this._cues.push({ gesture: g, expected: t + 4 * stepSpb, judged: false, phrase: -1 }); } this._sortSched(); const last = this._cues[this._cues.length - 1]; @@ -332,6 +348,7 @@ export class RhythmGame extends Game { return a && a.correct && Math.abs(a.dt) <= GOOD; }); if (pass) { + this._tutRate = 1.0; // G2:该步做对,恢复正常速度 if (this._tutIdx + 1 < TUT_STEPS.length) { this._beginTutorial(rid, this._tutIdx + 1); } else { @@ -344,6 +361,22 @@ export class RhythmGame extends Game { this._tutFails++; vibrate('error'); if (this._tutFails >= 2) { + // G2(round3 教学降难 DDA):同一步连续 2 次失败 → 该步领奏降速 25% 重演 + // (每教学局 1 次封顶;full 档先播 gd_slow「我放慢一些,跟着试试。」)—— + // P4「六连错无出路」:失败后第一次有变慢的路,而不是直接跳步。封顶用尽 + // 或 off 档(零改动红线)→ 维持 round2 的 retry_skip 跳步原路径。 + if (this.guide.level() !== 'off' && !this._tutSlowUsed) { + this._tutSlowUsed = true; + this._tutRate = 0.75; + this._tutFails = 0; // 降速重演 = 该步重新给两次机会(再连 2 失败才跳步) + if (this.guide.level() === 'full') { + this._speakGuarded(['voice/gd_slow'], () => this._tutLead(rid)); + } else { + this._tutLead(rid); + } + return; + } + this._tutRate = 1.0; // 离开该步(跳步):降速只作用于该步 // 同一步失败 2 次跳过,不卡流程(归因已在首次失败时给过,此处不再叠加) this._speakGuarded(['voice/retry_skip'], () => { if (this._tutIdx + 1 < TUT_STEPS.length) this._beginTutorial(rid, this._tutIdx + 1); @@ -440,17 +473,14 @@ export class RhythmGame extends Game { this._timed.push({ time: leadBarT0, fn: () => this.audio.play('voice/mid_song') }); } if (i === 0) { - // 向导层(round2 F3):每曲首次领奏→应答切换的交接标记。gd_answer 不走 - // guide 的 queue(对白在播时会排到链尾、错过首个应答窗口)——排进曲谱 - // 定时队列、在窗口前直接落下;turn earcon 走向导(full 语音,standard - // 只听提示音,off 全静)。mid_song 同款先例。 - this._timed.push({ - time: leadBarT0 + 4 * spb, - fn: () => { - if (this.guide.level() === 'full') this.audio.play('voice/gd_answer'); - this.guide.turn({}); - }, - }); + // 向导层(round3 G1):每次进 main,首个应答窗口**前整整 1 小节**(= 领奏 + // 小节头)落下 gd_answer+turn 交接标记。round2 F3 的排程点(leadBarT0 + + // 4*spb)其实是窗口起点本身——P4 实测(窗口 t+79~95,gd_answer t+93.7) + // 窗口开了才听到,起不到「快轮到你了」的预警作用。gd_answer 不走 guide + // 的 queue(对白在播时会排到链尾);语音 full 档直达,turn earcon standard + // 也发(off 全静不变)。mid_song 同款先例。 + this._answerArmed = true; + this._timed.push({ time: leadBarT0, fn: () => this._fireAnswerCue() }); } bar += 2 + (this._song.restAfter[i] || 0); }); @@ -460,6 +490,32 @@ export class RhythmGame extends Game { this._startPump(rid); } + /** G1:gd_answer+turn 交接标记(语音 full 档直达,turn earcon standard 也发)。 */ + _fireAnswerCue() { + this._answerArmed = false; + if (this.guide.level() === 'full') this.audio.play('voice/gd_answer'); + this.guide.turn({}); + } + + /** + * G1:为「下一个未判定的应答窗口」排交接标记,落在窗口前整整 1 小节(= 该句 + * 领奏小节头;已迫近则尽早在 0.15s 内补上)。_startSong 已为乐句 0 排过;菜单 + * 恢复(也是一次「进 main」)时若旧标记已消费、且前面还有未判定的窗口,对 + * 恢复后的首个窗口重排同款标记。上一句结束后的下一句不适用(裁定原文)。 + */ + _armAnswerCue(rid) { + if (this._answerArmed) return; // 旧标记仍在 _timed 里,随网格平移照常提前 1 小节响 + if (this._runId !== rid || !this._song || !this.audio.ctx) return; + const now = this.audio.ctx.currentTime; + const next = this._cues.find((c) => !c.judged && c.expected > now); + if (!next) return; + const spb = 60 / this._song.bpm; + const t = Math.max(now + 0.15, next.expected - 4 * spb); + this._answerArmed = true; + this._timed.push({ time: t, fn: () => this._fireAnswerCue() }); + this._sortSched(); + } + // ---------------- 手势与判定 ---------------- onGesture(g) { @@ -619,8 +675,11 @@ export class RhythmGame extends Game { this.guide.state('menu'); // 状态签名:菜单(模态暂停) // 暂停:停泵、停 BGM(记断点),已排程的 ≤0.6s 音符自然播完 if (this._timer) { clearInterval(this._timer); this._timer = null; } + this._resumeSeq++; // G3:作废还在等 gd_count 播完的旧恢复 this._pauseAt = this.audio.ctx.currentTime; - this._bgmOffset = this._pauseAt - this._bgmT0; + // 断点续播偏移只在 BGM 真在播时刷新(count-in 语音期间再开菜单时 BGM 未起, + // 沿用首次开的偏移,避免把暂停时长算进播放位置) + if (this._bgmSrc) this._bgmOffset = this._pauseAt - this._bgmT0; this._stopBgmSrc(); this._speak(['voice/menu_main', MENU_ITEMS[0]]); } @@ -641,27 +700,43 @@ export class RhythmGame extends Game { _closeMenu(rid) { if (this._runId !== rid) return; - const resumeAt = this.audio.ctx.currentTime + 0.1; - // F3(round2):断点续播前插一整小节 4 拍 count-in(复用底鼓节拍音,走既有 - // _sched 网格排程 = 每拍一个 inst_kick + beat 轻震),网格与 BGM 整体后移一小节, - // 杜绝 P1/P2/P3 实测的「回来 5 秒死寂、第一句报废」。off 档保持原即时续播 - // (向导层 off = 零改动路径)。 - const countIn = this.guide.level() !== 'off' ? 4 * (60 / this._song.bpm) : 0; - const bgmAt = resumeAt + countIn; - const shift = bgmAt - this._pauseAt; - // 全部绝对时刻平移(暂停时长 + count-in 小节),节拍网格与 BGM 断点续播保持同步 - for (const ev of this._sched) ev.time += shift; - for (const ev of this._timed) ev.time += shift; - for (const cue of this._cues) cue.expected += shift; - this._phaseEnd += shift; - for (let i = 0; i < 4 && countIn > 0; i++) { - this._sched.push({ time: resumeAt + i * (countIn / 4), sfx: INST.tap, volume: 0.7 }); - } - // _startBgm 内部重算 _bgmT0 = bgmAt - offset = 旧网格 + shift(负偏移保护同款成立) - this._startBgm(this._song, bgmAt, this._bgmOffset); this.phase = 'main'; this.audio.setRateBoostEnabled(false); // 回到演奏期 - this._startPump(rid); + const token = ++this._resumeSeq; // G3:恢复令牌(语音等待期间再开菜单则作废) + const resume = () => { + if (this._runId !== rid || token !== this._resumeSeq) return; + const resumeAt = this.audio.ctx.currentTime + 0.1; + // G3(round3):断点续播前插一整小节 4 拍 count-in——底鼓走 sfx 层独立于 + // BGM、音量提到可辨(0.7→1.0),每拍带 beat 轻震(_sched 泵同步排),网格 + // 与 BGM 整体后移一小节,杜绝 P3 实测的「回来 5 秒死寂、第一句报废」。 + // round2 F3 的 count-in 实际从未按时响过:底鼓 push 进 _sched 后没重排, + // 队头是数秒外的领奏音符,40ms 泵的 0.6s 前瞻窗口永远轮不到它——本次修复 + // push 后 _sortSched()。off 档保持原即时续播(零改动路径)。 + const countIn = this.guide.level() !== 'off' ? 4 * (60 / this._song.bpm) : 0; + const bgmAt = resumeAt + countIn; + const shift = bgmAt - this._pauseAt; + // 全部绝对时刻平移(暂停时长 + count-in 小节),节拍网格与 BGM 断点续播保持同步 + for (const ev of this._sched) ev.time += shift; + for (const ev of this._timed) ev.time += shift; + for (const cue of this._cues) cue.expected += shift; + this._phaseEnd += shift; + for (let i = 0; i < 4 && countIn > 0; i++) { + this._sched.push({ time: resumeAt + i * (countIn / 4), sfx: INST.tap, volume: 1.0 }); + } + this._sortSched(); // G3 修复:count-in 必须重排入队,否则被队头阻塞整段迟到 + // _startBgm 内部重算 _bgmT0 = bgmAt - offset = 旧网格 + shift(负偏移保护同款成立) + this._startBgm(this._song, bgmAt, this._bgmOffset); + this._startPump(rid); + this._armAnswerCue(rid); // G1:菜单恢复也是一次「进 main」,给下一个窗口补交接标记 + }; + // G3:gd_count「四拍之后,继续。」full 档、每局(曲)恢复限 1 次,在 count-in + // 之前经语音链串行播出(链完或缺失看门狗兜底后才开始数拍)。 + if (this.guide.level() === 'full' && !this._gdCountUsed) { + this._gdCountUsed = true; + this._speakGuarded(['voice/gd_count'], resume); + } else { + resume(); + } } _goHome() { diff --git a/web/simon/audio/voice/female/chance_plus.ogg b/web/simon/audio/voice/female/chance_plus.ogg index 1080246e..10270922 100644 Binary files a/web/simon/audio/voice/female/chance_plus.ogg and b/web/simon/audio/voice/female/chance_plus.ogg differ diff --git a/web/simon/audio/voice/female/chances_out.ogg b/web/simon/audio/voice/female/chances_out.ogg index 88ee3d24..4cfd823b 100644 Binary files a/web/simon/audio/voice/female/chances_out.ogg and b/web/simon/audio/voice/female/chances_out.ogg differ diff --git a/web/simon/audio/voice/female/correct.ogg b/web/simon/audio/voice/female/correct.ogg index bfc96079..98a6494c 100644 Binary files a/web/simon/audio/voice/female/correct.ogg and b/web/simon/audio/voice/female/correct.ogg differ diff --git a/web/simon/audio/voice/female/gameover.ogg b/web/simon/audio/voice/female/gameover.ogg index d64ffc9e..9fa11bb6 100644 Binary files a/web/simon/audio/voice/female/gameover.ogg and b/web/simon/audio/voice/female/gameover.ogg differ diff --git a/web/simon/audio/voice/female/gd_clear.m4a b/web/simon/audio/voice/female/gd_clear.m4a new file mode 100644 index 00000000..f27a7659 Binary files /dev/null and b/web/simon/audio/voice/female/gd_clear.m4a differ diff --git a/web/simon/audio/voice/female/gd_clear.ogg b/web/simon/audio/voice/female/gd_clear.ogg new file mode 100644 index 00000000..54e96d31 Binary files /dev/null and b/web/simon/audio/voice/female/gd_clear.ogg differ diff --git a/web/simon/audio/voice/female/gd_economy.m4a b/web/simon/audio/voice/female/gd_economy.m4a index 51091466..9df26486 100644 Binary files a/web/simon/audio/voice/female/gd_economy.m4a and b/web/simon/audio/voice/female/gd_economy.m4a differ diff --git a/web/simon/audio/voice/female/gd_economy.ogg b/web/simon/audio/voice/female/gd_economy.ogg index 42f6eaef..319cdee6 100644 Binary files a/web/simon/audio/voice/female/gd_economy.ogg and b/web/simon/audio/voice/female/gd_economy.ogg differ diff --git a/web/simon/audio/voice/female/gd_record.m4a b/web/simon/audio/voice/female/gd_record.m4a new file mode 100644 index 00000000..93d3ba66 Binary files /dev/null and b/web/simon/audio/voice/female/gd_record.m4a differ diff --git a/web/simon/audio/voice/female/gd_record.ogg b/web/simon/audio/voice/female/gd_record.ogg new file mode 100644 index 00000000..c008bcbe Binary files /dev/null and b/web/simon/audio/voice/female/gd_record.ogg differ diff --git a/web/simon/audio/voice/female/gd_relisten.m4a b/web/simon/audio/voice/female/gd_relisten.m4a index 4e845aa9..a67f33e4 100644 Binary files a/web/simon/audio/voice/female/gd_relisten.m4a and b/web/simon/audio/voice/female/gd_relisten.m4a differ diff --git a/web/simon/audio/voice/female/gd_relisten.ogg b/web/simon/audio/voice/female/gd_relisten.ogg index 21c803d6..ca936de6 100644 Binary files a/web/simon/audio/voice/female/gd_relisten.ogg and b/web/simon/audio/voice/female/gd_relisten.ogg differ diff --git a/web/simon/audio/voice/female/menu_back.ogg b/web/simon/audio/voice/female/menu_back.ogg index 9e7ac47f..0fdcff23 100644 Binary files a/web/simon/audio/voice/female/menu_back.ogg and b/web/simon/audio/voice/female/menu_back.ogg differ diff --git a/web/simon/audio/voice/female/menu_home.ogg b/web/simon/audio/voice/female/menu_home.ogg index 992f9383..ca22d7c8 100644 Binary files a/web/simon/audio/voice/female/menu_home.ogg and b/web/simon/audio/voice/female/menu_home.ogg differ diff --git a/web/simon/audio/voice/female/menu_open.ogg b/web/simon/audio/voice/female/menu_open.ogg index 4152646a..bb93f07e 100644 Binary files a/web/simon/audio/voice/female/menu_open.ogg and b/web/simon/audio/voice/female/menu_open.ogg differ diff --git a/web/simon/audio/voice/female/menu_restart.ogg b/web/simon/audio/voice/female/menu_restart.ogg index db7397e6..f464a7b4 100644 Binary files a/web/simon/audio/voice/female/menu_restart.ogg and b/web/simon/audio/voice/female/menu_restart.ogg differ diff --git a/web/simon/audio/voice/female/new_record.ogg b/web/simon/audio/voice/female/new_record.ogg index 4d56f345..099ea85d 100644 Binary files a/web/simon/audio/voice/female/new_record.ogg and b/web/simon/audio/voice/female/new_record.ogg differ diff --git a/web/simon/audio/voice/female/relisten.ogg b/web/simon/audio/voice/female/relisten.ogg index 1776be21..c64d5462 100644 Binary files a/web/simon/audio/voice/female/relisten.ogg and b/web/simon/audio/voice/female/relisten.ogg differ diff --git a/web/simon/audio/voice/female/replay.ogg b/web/simon/audio/voice/female/replay.ogg index 1696d5ce..37835ec2 100644 Binary files a/web/simon/audio/voice/female/replay.ogg and b/web/simon/audio/voice/female/replay.ogg differ diff --git a/web/simon/audio/voice/female/retry_use.ogg b/web/simon/audio/voice/female/retry_use.ogg index e46ac8c5..27a64e98 100644 Binary files a/web/simon/audio/voice/female/retry_use.ogg and b/web/simon/audio/voice/female/retry_use.ogg differ diff --git a/web/simon/audio/voice/female/round_01.ogg b/web/simon/audio/voice/female/round_01.ogg index dcc29bd2..8b337505 100644 Binary files a/web/simon/audio/voice/female/round_01.ogg and b/web/simon/audio/voice/female/round_01.ogg differ diff --git a/web/simon/audio/voice/female/round_02.ogg b/web/simon/audio/voice/female/round_02.ogg index c26c0ccf..73e16fd5 100644 Binary files a/web/simon/audio/voice/female/round_02.ogg and b/web/simon/audio/voice/female/round_02.ogg differ diff --git a/web/simon/audio/voice/female/round_03.ogg b/web/simon/audio/voice/female/round_03.ogg index 36271908..03103b58 100644 Binary files a/web/simon/audio/voice/female/round_03.ogg and b/web/simon/audio/voice/female/round_03.ogg differ diff --git a/web/simon/audio/voice/female/round_04.ogg b/web/simon/audio/voice/female/round_04.ogg index fb3cea5b..83398a87 100644 Binary files a/web/simon/audio/voice/female/round_04.ogg and b/web/simon/audio/voice/female/round_04.ogg differ diff --git a/web/simon/audio/voice/female/round_05.ogg b/web/simon/audio/voice/female/round_05.ogg index ae4aa79d..15deedfa 100644 Binary files a/web/simon/audio/voice/female/round_05.ogg and b/web/simon/audio/voice/female/round_05.ogg differ diff --git a/web/simon/audio/voice/female/round_06.ogg b/web/simon/audio/voice/female/round_06.ogg index 3a6279a3..a22d0e3c 100644 Binary files a/web/simon/audio/voice/female/round_06.ogg and b/web/simon/audio/voice/female/round_06.ogg differ diff --git a/web/simon/audio/voice/female/round_07.ogg b/web/simon/audio/voice/female/round_07.ogg index baa3c667..c71f811d 100644 Binary files a/web/simon/audio/voice/female/round_07.ogg and b/web/simon/audio/voice/female/round_07.ogg differ diff --git a/web/simon/audio/voice/female/round_08.ogg b/web/simon/audio/voice/female/round_08.ogg index 5ad51db8..0a308fed 100644 Binary files a/web/simon/audio/voice/female/round_08.ogg and b/web/simon/audio/voice/female/round_08.ogg differ diff --git a/web/simon/audio/voice/female/round_09.ogg b/web/simon/audio/voice/female/round_09.ogg index a8dc27da..4978d709 100644 Binary files a/web/simon/audio/voice/female/round_09.ogg and b/web/simon/audio/voice/female/round_09.ogg differ diff --git a/web/simon/audio/voice/female/round_10.ogg b/web/simon/audio/voice/female/round_10.ogg index 8602592c..28b06590 100644 Binary files a/web/simon/audio/voice/female/round_10.ogg and b/web/simon/audio/voice/female/round_10.ogg differ diff --git a/web/simon/audio/voice/female/round_11.ogg b/web/simon/audio/voice/female/round_11.ogg index f918199a..55645b94 100644 Binary files a/web/simon/audio/voice/female/round_11.ogg and b/web/simon/audio/voice/female/round_11.ogg differ diff --git a/web/simon/audio/voice/female/round_12.ogg b/web/simon/audio/voice/female/round_12.ogg index 1547f3d7..fc3ea4fb 100644 Binary files a/web/simon/audio/voice/female/round_12.ogg and b/web/simon/audio/voice/female/round_12.ogg differ diff --git a/web/simon/audio/voice/female/round_13.ogg b/web/simon/audio/voice/female/round_13.ogg index 89a0d4a1..90ff5e53 100644 Binary files a/web/simon/audio/voice/female/round_13.ogg and b/web/simon/audio/voice/female/round_13.ogg differ diff --git a/web/simon/audio/voice/female/round_14.ogg b/web/simon/audio/voice/female/round_14.ogg index c0b4e3cb..6244cab5 100644 Binary files a/web/simon/audio/voice/female/round_14.ogg and b/web/simon/audio/voice/female/round_14.ogg differ diff --git a/web/simon/audio/voice/female/round_15.ogg b/web/simon/audio/voice/female/round_15.ogg index 5d01ec8b..a71fb82e 100644 Binary files a/web/simon/audio/voice/female/round_15.ogg and b/web/simon/audio/voice/female/round_15.ogg differ diff --git a/web/simon/audio/voice/female/round_16.ogg b/web/simon/audio/voice/female/round_16.ogg index e43a0329..e48194e0 100644 Binary files a/web/simon/audio/voice/female/round_16.ogg and b/web/simon/audio/voice/female/round_16.ogg differ diff --git a/web/simon/audio/voice/female/round_17.ogg b/web/simon/audio/voice/female/round_17.ogg index 627f28ed..4e79e4a5 100644 Binary files a/web/simon/audio/voice/female/round_17.ogg and b/web/simon/audio/voice/female/round_17.ogg differ diff --git a/web/simon/audio/voice/female/round_18.ogg b/web/simon/audio/voice/female/round_18.ogg index f3f2dd17..0bb7f5c8 100644 Binary files a/web/simon/audio/voice/female/round_18.ogg and b/web/simon/audio/voice/female/round_18.ogg differ diff --git a/web/simon/audio/voice/female/round_19.ogg b/web/simon/audio/voice/female/round_19.ogg index 79412da7..d9e82f77 100644 Binary files a/web/simon/audio/voice/female/round_19.ogg and b/web/simon/audio/voice/female/round_19.ogg differ diff --git a/web/simon/audio/voice/female/round_20.ogg b/web/simon/audio/voice/female/round_20.ogg index 8bb41064..c34fe040 100644 Binary files a/web/simon/audio/voice/female/round_20.ogg and b/web/simon/audio/voice/female/round_20.ogg differ diff --git a/web/simon/audio/voice/female/round_more.ogg b/web/simon/audio/voice/female/round_more.ogg index ee078a6f..fb0ba481 100644 Binary files a/web/simon/audio/voice/female/round_more.ogg and b/web/simon/audio/voice/female/round_more.ogg differ diff --git a/web/simon/audio/voice/female/rules.ogg b/web/simon/audio/voice/female/rules.ogg index 8246a015..551e7ee4 100644 Binary files a/web/simon/audio/voice/female/rules.ogg and b/web/simon/audio/voice/female/rules.ogg differ diff --git a/web/simon/audio/voice/female/rules_prompt.ogg b/web/simon/audio/voice/female/rules_prompt.ogg index 0d3dcbbf..053e3f4e 100644 Binary files a/web/simon/audio/voice/female/rules_prompt.ogg and b/web/simon/audio/voice/female/rules_prompt.ogg differ diff --git a/web/simon/audio/voice/female/score_band1.ogg b/web/simon/audio/voice/female/score_band1.ogg index df38ac5f..0791b9f9 100644 Binary files a/web/simon/audio/voice/female/score_band1.ogg and b/web/simon/audio/voice/female/score_band1.ogg differ diff --git a/web/simon/audio/voice/female/score_band2.ogg b/web/simon/audio/voice/female/score_band2.ogg index b59d274d..213729da 100644 Binary files a/web/simon/audio/voice/female/score_band2.ogg and b/web/simon/audio/voice/female/score_band2.ogg differ diff --git a/web/simon/audio/voice/female/score_band3.ogg b/web/simon/audio/voice/female/score_band3.ogg index d1af20df..7aa1a2b8 100644 Binary files a/web/simon/audio/voice/female/score_band3.ogg and b/web/simon/audio/voice/female/score_band3.ogg differ diff --git a/web/simon/audio/voice/female/score_band4.ogg b/web/simon/audio/voice/female/score_band4.ogg index 0a83c08b..3fce656d 100644 Binary files a/web/simon/audio/voice/female/score_band4.ogg and b/web/simon/audio/voice/female/score_band4.ogg differ diff --git a/web/simon/audio/voice/female/score_band5.ogg b/web/simon/audio/voice/female/score_band5.ogg index 8d52d208..cc18fcfd 100644 Binary files a/web/simon/audio/voice/female/score_band5.ogg and b/web/simon/audio/voice/female/score_band5.ogg differ diff --git a/web/simon/audio/voice/female/score_band6.ogg b/web/simon/audio/voice/female/score_band6.ogg index 4b903167..dcef4a94 100644 Binary files a/web/simon/audio/voice/female/score_band6.ogg and b/web/simon/audio/voice/female/score_band6.ogg differ diff --git a/web/simon/audio/voice/female/skip_hint.ogg b/web/simon/audio/voice/female/skip_hint.ogg index a43d3658..9de67061 100644 Binary files a/web/simon/audio/voice/female/skip_hint.ogg and b/web/simon/audio/voice/female/skip_hint.ogg differ diff --git a/web/simon/audio/voice/female/t0_goal.ogg b/web/simon/audio/voice/female/t0_goal.ogg index 5e4876f4..6234b875 100644 Binary files a/web/simon/audio/voice/female/t0_goal.ogg and b/web/simon/audio/voice/female/t0_goal.ogg differ diff --git a/web/simon/audio/voice/female/t0_welcome.ogg b/web/simon/audio/voice/female/t0_welcome.ogg index ecce46fc..ff4a21e1 100644 Binary files a/web/simon/audio/voice/female/t0_welcome.ogg and b/web/simon/audio/voice/female/t0_welcome.ogg differ diff --git a/web/simon/audio/voice/female/t1_up.ogg b/web/simon/audio/voice/female/t1_up.ogg index 5ae0b352..1c4bad2a 100644 Binary files a/web/simon/audio/voice/female/t1_up.ogg and b/web/simon/audio/voice/female/t1_up.ogg differ diff --git a/web/simon/audio/voice/female/t2_down.ogg b/web/simon/audio/voice/female/t2_down.ogg index fa2e2a15..cc117b22 100644 Binary files a/web/simon/audio/voice/female/t2_down.ogg and b/web/simon/audio/voice/female/t2_down.ogg differ diff --git a/web/simon/audio/voice/female/t3_left.ogg b/web/simon/audio/voice/female/t3_left.ogg index 28f1a285..aba84232 100644 Binary files a/web/simon/audio/voice/female/t3_left.ogg and b/web/simon/audio/voice/female/t3_left.ogg differ diff --git a/web/simon/audio/voice/female/t4_right.ogg b/web/simon/audio/voice/female/t4_right.ogg index af9b24dc..9e5b547a 100644 Binary files a/web/simon/audio/voice/female/t4_right.ogg and b/web/simon/audio/voice/female/t4_right.ogg differ diff --git a/web/simon/audio/voice/female/t5_tap.ogg b/web/simon/audio/voice/female/t5_tap.ogg index 42eccd42..e7d14452 100644 Binary files a/web/simon/audio/voice/female/t5_tap.ogg and b/web/simon/audio/voice/female/t5_tap.ogg differ diff --git a/web/simon/audio/voice/female/t6_double.ogg b/web/simon/audio/voice/female/t6_double.ogg index c808a0df..6534832e 100644 Binary files a/web/simon/audio/voice/female/t6_double.ogg and b/web/simon/audio/voice/female/t6_double.ogg differ diff --git a/web/simon/audio/voice/female/t7_ready.ogg b/web/simon/audio/voice/female/t7_ready.ogg index 3a080b9f..34d09dfa 100644 Binary files a/web/simon/audio/voice/female/t7_ready.ogg and b/web/simon/audio/voice/female/t7_ready.ogg differ diff --git a/web/simon/audio/voice/female/t7_retry.m4a b/web/simon/audio/voice/female/t7_retry.m4a index 1b092096..f8698820 100644 Binary files a/web/simon/audio/voice/female/t7_retry.m4a and b/web/simon/audio/voice/female/t7_retry.m4a differ diff --git a/web/simon/audio/voice/female/t7_retry.ogg b/web/simon/audio/voice/female/t7_retry.ogg index 3b78c941..9aac7679 100644 Binary files a/web/simon/audio/voice/female/t7_retry.ogg and b/web/simon/audio/voice/female/t7_retry.ogg differ diff --git a/web/simon/audio/voice/female/t_blunt_double.ogg b/web/simon/audio/voice/female/t_blunt_double.ogg index 7d2b6d2c..27d4209d 100644 Binary files a/web/simon/audio/voice/female/t_blunt_double.ogg and b/web/simon/audio/voice/female/t_blunt_double.ogg differ diff --git a/web/simon/audio/voice/female/t_blunt_down.ogg b/web/simon/audio/voice/female/t_blunt_down.ogg index 7b592852..ae182c0c 100644 Binary files a/web/simon/audio/voice/female/t_blunt_down.ogg and b/web/simon/audio/voice/female/t_blunt_down.ogg differ diff --git a/web/simon/audio/voice/female/t_blunt_left.ogg b/web/simon/audio/voice/female/t_blunt_left.ogg index 9a60b472..66aa2613 100644 Binary files a/web/simon/audio/voice/female/t_blunt_left.ogg and b/web/simon/audio/voice/female/t_blunt_left.ogg differ diff --git a/web/simon/audio/voice/female/t_blunt_right.ogg b/web/simon/audio/voice/female/t_blunt_right.ogg index e185b228..c4674246 100644 Binary files a/web/simon/audio/voice/female/t_blunt_right.ogg and b/web/simon/audio/voice/female/t_blunt_right.ogg differ diff --git a/web/simon/audio/voice/female/t_blunt_tap.ogg b/web/simon/audio/voice/female/t_blunt_tap.ogg index 13f2f237..c54c7059 100644 Binary files a/web/simon/audio/voice/female/t_blunt_tap.ogg and b/web/simon/audio/voice/female/t_blunt_tap.ogg differ diff --git a/web/simon/audio/voice/female/t_blunt_up.ogg b/web/simon/audio/voice/female/t_blunt_up.ogg index 98ab5965..45c1d066 100644 Binary files a/web/simon/audio/voice/female/t_blunt_up.ogg and b/web/simon/audio/voice/female/t_blunt_up.ogg differ diff --git a/web/simon/audio/voice/female/t_ok.ogg b/web/simon/audio/voice/female/t_ok.ogg index 927f5c21..20c6e1be 100644 Binary files a/web/simon/audio/voice/female/t_ok.ogg and b/web/simon/audio/voice/female/t_ok.ogg differ diff --git a/web/simon/audio/voice/female/t_skip.ogg b/web/simon/audio/voice/female/t_skip.ogg index 80bc1d13..5fba831c 100644 Binary files a/web/simon/audio/voice/female/t_skip.ogg and b/web/simon/audio/voice/female/t_skip.ogg differ diff --git a/web/simon/audio/voice/female/t_try.ogg b/web/simon/audio/voice/female/t_try.ogg index 01ad1fe0..f48a80f2 100644 Binary files a/web/simon/audio/voice/female/t_try.ogg and b/web/simon/audio/voice/female/t_try.ogg differ diff --git a/web/simon/audio/voice/female/t_wrong_double.ogg b/web/simon/audio/voice/female/t_wrong_double.ogg index d5c0cb1f..4abe591c 100644 Binary files a/web/simon/audio/voice/female/t_wrong_double.ogg and b/web/simon/audio/voice/female/t_wrong_double.ogg differ diff --git a/web/simon/audio/voice/female/t_wrong_down.ogg b/web/simon/audio/voice/female/t_wrong_down.ogg index 208c0380..2a8812e0 100644 Binary files a/web/simon/audio/voice/female/t_wrong_down.ogg and b/web/simon/audio/voice/female/t_wrong_down.ogg differ diff --git a/web/simon/audio/voice/female/t_wrong_left.ogg b/web/simon/audio/voice/female/t_wrong_left.ogg index fd50571a..99bb089b 100644 Binary files a/web/simon/audio/voice/female/t_wrong_left.ogg and b/web/simon/audio/voice/female/t_wrong_left.ogg differ diff --git a/web/simon/audio/voice/female/t_wrong_right.ogg b/web/simon/audio/voice/female/t_wrong_right.ogg index 59bb5667..2e80ae60 100644 Binary files a/web/simon/audio/voice/female/t_wrong_right.ogg and b/web/simon/audio/voice/female/t_wrong_right.ogg differ diff --git a/web/simon/audio/voice/female/t_wrong_tap.ogg b/web/simon/audio/voice/female/t_wrong_tap.ogg index a16047c0..f7cafbf9 100644 Binary files a/web/simon/audio/voice/female/t_wrong_tap.ogg and b/web/simon/audio/voice/female/t_wrong_tap.ogg differ diff --git a/web/simon/audio/voice/female/t_wrong_up.ogg b/web/simon/audio/voice/female/t_wrong_up.ogg index ed0fb739..93e9945a 100644 Binary files a/web/simon/audio/voice/female/t_wrong_up.ogg and b/web/simon/audio/voice/female/t_wrong_up.ogg differ diff --git a/web/simon/audio/voice/female/wrong.ogg b/web/simon/audio/voice/female/wrong.ogg index 0991be65..fc11ae8e 100644 Binary files a/web/simon/audio/voice/female/wrong.ogg and b/web/simon/audio/voice/female/wrong.ogg differ diff --git a/web/simon/audio/voice/female/your_turn.ogg b/web/simon/audio/voice/female/your_turn.ogg index 7b92bfad..d99582c6 100644 Binary files a/web/simon/audio/voice/female/your_turn.ogg and b/web/simon/audio/voice/female/your_turn.ogg differ diff --git a/web/simon/audio/voice/male/chance_plus.ogg b/web/simon/audio/voice/male/chance_plus.ogg index 72ce4424..a2cff8ae 100644 Binary files a/web/simon/audio/voice/male/chance_plus.ogg and b/web/simon/audio/voice/male/chance_plus.ogg differ diff --git a/web/simon/audio/voice/male/chances_out.ogg b/web/simon/audio/voice/male/chances_out.ogg index a464cf76..44fc5e8d 100644 Binary files a/web/simon/audio/voice/male/chances_out.ogg and b/web/simon/audio/voice/male/chances_out.ogg differ diff --git a/web/simon/audio/voice/male/correct.ogg b/web/simon/audio/voice/male/correct.ogg index 51a1db86..8e70e849 100644 Binary files a/web/simon/audio/voice/male/correct.ogg and b/web/simon/audio/voice/male/correct.ogg differ diff --git a/web/simon/audio/voice/male/gameover.ogg b/web/simon/audio/voice/male/gameover.ogg index 8a32a619..37435f90 100644 Binary files a/web/simon/audio/voice/male/gameover.ogg and b/web/simon/audio/voice/male/gameover.ogg differ diff --git a/web/simon/audio/voice/male/gd_clear.m4a b/web/simon/audio/voice/male/gd_clear.m4a new file mode 100644 index 00000000..e676f302 Binary files /dev/null and b/web/simon/audio/voice/male/gd_clear.m4a differ diff --git a/web/simon/audio/voice/male/gd_clear.ogg b/web/simon/audio/voice/male/gd_clear.ogg new file mode 100644 index 00000000..c846e28c Binary files /dev/null and b/web/simon/audio/voice/male/gd_clear.ogg differ diff --git a/web/simon/audio/voice/male/gd_economy.m4a b/web/simon/audio/voice/male/gd_economy.m4a index f28c527c..32538c43 100644 Binary files a/web/simon/audio/voice/male/gd_economy.m4a and b/web/simon/audio/voice/male/gd_economy.m4a differ diff --git a/web/simon/audio/voice/male/gd_economy.ogg b/web/simon/audio/voice/male/gd_economy.ogg index c933519a..673cf749 100644 Binary files a/web/simon/audio/voice/male/gd_economy.ogg and b/web/simon/audio/voice/male/gd_economy.ogg differ diff --git a/web/simon/audio/voice/male/gd_record.m4a b/web/simon/audio/voice/male/gd_record.m4a new file mode 100644 index 00000000..bd5f2ac6 Binary files /dev/null and b/web/simon/audio/voice/male/gd_record.m4a differ diff --git a/web/simon/audio/voice/male/gd_record.ogg b/web/simon/audio/voice/male/gd_record.ogg new file mode 100644 index 00000000..c8d4a7c5 Binary files /dev/null and b/web/simon/audio/voice/male/gd_record.ogg differ diff --git a/web/simon/audio/voice/male/gd_relisten.m4a b/web/simon/audio/voice/male/gd_relisten.m4a index 658671dd..406944a3 100644 Binary files a/web/simon/audio/voice/male/gd_relisten.m4a and b/web/simon/audio/voice/male/gd_relisten.m4a differ diff --git a/web/simon/audio/voice/male/gd_relisten.ogg b/web/simon/audio/voice/male/gd_relisten.ogg index d587953c..5b78e09d 100644 Binary files a/web/simon/audio/voice/male/gd_relisten.ogg and b/web/simon/audio/voice/male/gd_relisten.ogg differ diff --git a/web/simon/audio/voice/male/menu_back.ogg b/web/simon/audio/voice/male/menu_back.ogg index 0873b642..109a5114 100644 Binary files a/web/simon/audio/voice/male/menu_back.ogg and b/web/simon/audio/voice/male/menu_back.ogg differ diff --git a/web/simon/audio/voice/male/menu_home.ogg b/web/simon/audio/voice/male/menu_home.ogg index 7db24e5f..40995013 100644 Binary files a/web/simon/audio/voice/male/menu_home.ogg and b/web/simon/audio/voice/male/menu_home.ogg differ diff --git a/web/simon/audio/voice/male/menu_open.ogg b/web/simon/audio/voice/male/menu_open.ogg index 55a72c44..f3819dd2 100644 Binary files a/web/simon/audio/voice/male/menu_open.ogg and b/web/simon/audio/voice/male/menu_open.ogg differ diff --git a/web/simon/audio/voice/male/menu_restart.ogg b/web/simon/audio/voice/male/menu_restart.ogg index 248bf972..4679aca4 100644 Binary files a/web/simon/audio/voice/male/menu_restart.ogg and b/web/simon/audio/voice/male/menu_restart.ogg differ diff --git a/web/simon/audio/voice/male/new_record.ogg b/web/simon/audio/voice/male/new_record.ogg index c219e5aa..2d9c1f90 100644 Binary files a/web/simon/audio/voice/male/new_record.ogg and b/web/simon/audio/voice/male/new_record.ogg differ diff --git a/web/simon/audio/voice/male/relisten.ogg b/web/simon/audio/voice/male/relisten.ogg index 87d92e17..0541fe5c 100644 Binary files a/web/simon/audio/voice/male/relisten.ogg and b/web/simon/audio/voice/male/relisten.ogg differ diff --git a/web/simon/audio/voice/male/replay.ogg b/web/simon/audio/voice/male/replay.ogg index 60a29314..2d695a3b 100644 Binary files a/web/simon/audio/voice/male/replay.ogg and b/web/simon/audio/voice/male/replay.ogg differ diff --git a/web/simon/audio/voice/male/retry_use.ogg b/web/simon/audio/voice/male/retry_use.ogg index 38caa9a0..a83384e0 100644 Binary files a/web/simon/audio/voice/male/retry_use.ogg and b/web/simon/audio/voice/male/retry_use.ogg differ diff --git a/web/simon/audio/voice/male/round_01.ogg b/web/simon/audio/voice/male/round_01.ogg index fee020c0..37520e90 100644 Binary files a/web/simon/audio/voice/male/round_01.ogg and b/web/simon/audio/voice/male/round_01.ogg differ diff --git a/web/simon/audio/voice/male/round_02.ogg b/web/simon/audio/voice/male/round_02.ogg index 033bc970..6ebc6fbc 100644 Binary files a/web/simon/audio/voice/male/round_02.ogg and b/web/simon/audio/voice/male/round_02.ogg differ diff --git a/web/simon/audio/voice/male/round_03.ogg b/web/simon/audio/voice/male/round_03.ogg index 20f10eca..ffda4a5c 100644 Binary files a/web/simon/audio/voice/male/round_03.ogg and b/web/simon/audio/voice/male/round_03.ogg differ diff --git a/web/simon/audio/voice/male/round_04.ogg b/web/simon/audio/voice/male/round_04.ogg index 2041327a..82efd421 100644 Binary files a/web/simon/audio/voice/male/round_04.ogg and b/web/simon/audio/voice/male/round_04.ogg differ diff --git a/web/simon/audio/voice/male/round_05.ogg b/web/simon/audio/voice/male/round_05.ogg index b1212862..f434b091 100644 Binary files a/web/simon/audio/voice/male/round_05.ogg and b/web/simon/audio/voice/male/round_05.ogg differ diff --git a/web/simon/audio/voice/male/round_06.ogg b/web/simon/audio/voice/male/round_06.ogg index c8aff54c..004cad7a 100644 Binary files a/web/simon/audio/voice/male/round_06.ogg and b/web/simon/audio/voice/male/round_06.ogg differ diff --git a/web/simon/audio/voice/male/round_07.ogg b/web/simon/audio/voice/male/round_07.ogg index 6e56d886..187efe46 100644 Binary files a/web/simon/audio/voice/male/round_07.ogg and b/web/simon/audio/voice/male/round_07.ogg differ diff --git a/web/simon/audio/voice/male/round_08.ogg b/web/simon/audio/voice/male/round_08.ogg index b6a4966c..09eadb25 100644 Binary files a/web/simon/audio/voice/male/round_08.ogg and b/web/simon/audio/voice/male/round_08.ogg differ diff --git a/web/simon/audio/voice/male/round_09.ogg b/web/simon/audio/voice/male/round_09.ogg index 5e71c0b8..0c50ce89 100644 Binary files a/web/simon/audio/voice/male/round_09.ogg and b/web/simon/audio/voice/male/round_09.ogg differ diff --git a/web/simon/audio/voice/male/round_10.ogg b/web/simon/audio/voice/male/round_10.ogg index 3a4d35cc..9d3f5662 100644 Binary files a/web/simon/audio/voice/male/round_10.ogg and b/web/simon/audio/voice/male/round_10.ogg differ diff --git a/web/simon/audio/voice/male/round_11.ogg b/web/simon/audio/voice/male/round_11.ogg index 5f1f713e..bd08e47d 100644 Binary files a/web/simon/audio/voice/male/round_11.ogg and b/web/simon/audio/voice/male/round_11.ogg differ diff --git a/web/simon/audio/voice/male/round_12.ogg b/web/simon/audio/voice/male/round_12.ogg index d1137d2c..13607b1e 100644 Binary files a/web/simon/audio/voice/male/round_12.ogg and b/web/simon/audio/voice/male/round_12.ogg differ diff --git a/web/simon/audio/voice/male/round_13.ogg b/web/simon/audio/voice/male/round_13.ogg index 382d1ed0..3a2f49a3 100644 Binary files a/web/simon/audio/voice/male/round_13.ogg and b/web/simon/audio/voice/male/round_13.ogg differ diff --git a/web/simon/audio/voice/male/round_14.ogg b/web/simon/audio/voice/male/round_14.ogg index 2698db17..f12ecbbc 100644 Binary files a/web/simon/audio/voice/male/round_14.ogg and b/web/simon/audio/voice/male/round_14.ogg differ diff --git a/web/simon/audio/voice/male/round_15.ogg b/web/simon/audio/voice/male/round_15.ogg index 7ed795d6..0fc902ef 100644 Binary files a/web/simon/audio/voice/male/round_15.ogg and b/web/simon/audio/voice/male/round_15.ogg differ diff --git a/web/simon/audio/voice/male/round_16.ogg b/web/simon/audio/voice/male/round_16.ogg index 6b6a9817..c48e9fa0 100644 Binary files a/web/simon/audio/voice/male/round_16.ogg and b/web/simon/audio/voice/male/round_16.ogg differ diff --git a/web/simon/audio/voice/male/round_17.ogg b/web/simon/audio/voice/male/round_17.ogg index ac41bd17..b6137e5a 100644 Binary files a/web/simon/audio/voice/male/round_17.ogg and b/web/simon/audio/voice/male/round_17.ogg differ diff --git a/web/simon/audio/voice/male/round_18.ogg b/web/simon/audio/voice/male/round_18.ogg index 32343bc6..94a9f900 100644 Binary files a/web/simon/audio/voice/male/round_18.ogg and b/web/simon/audio/voice/male/round_18.ogg differ diff --git a/web/simon/audio/voice/male/round_19.ogg b/web/simon/audio/voice/male/round_19.ogg index 8a92a07a..f96f7846 100644 Binary files a/web/simon/audio/voice/male/round_19.ogg and b/web/simon/audio/voice/male/round_19.ogg differ diff --git a/web/simon/audio/voice/male/round_20.ogg b/web/simon/audio/voice/male/round_20.ogg index f988904d..07687c88 100644 Binary files a/web/simon/audio/voice/male/round_20.ogg and b/web/simon/audio/voice/male/round_20.ogg differ diff --git a/web/simon/audio/voice/male/round_more.ogg b/web/simon/audio/voice/male/round_more.ogg index 9af6eb6d..cd1d27aa 100644 Binary files a/web/simon/audio/voice/male/round_more.ogg and b/web/simon/audio/voice/male/round_more.ogg differ diff --git a/web/simon/audio/voice/male/rules.ogg b/web/simon/audio/voice/male/rules.ogg index fee626cd..de512408 100644 Binary files a/web/simon/audio/voice/male/rules.ogg and b/web/simon/audio/voice/male/rules.ogg differ diff --git a/web/simon/audio/voice/male/rules_prompt.ogg b/web/simon/audio/voice/male/rules_prompt.ogg index 82ffa506..34f02709 100644 Binary files a/web/simon/audio/voice/male/rules_prompt.ogg and b/web/simon/audio/voice/male/rules_prompt.ogg differ diff --git a/web/simon/audio/voice/male/score_band1.ogg b/web/simon/audio/voice/male/score_band1.ogg index 6dab0a5e..492e41d1 100644 Binary files a/web/simon/audio/voice/male/score_band1.ogg and b/web/simon/audio/voice/male/score_band1.ogg differ diff --git a/web/simon/audio/voice/male/score_band2.ogg b/web/simon/audio/voice/male/score_band2.ogg index 1f0abe7d..198e0d8b 100644 Binary files a/web/simon/audio/voice/male/score_band2.ogg and b/web/simon/audio/voice/male/score_band2.ogg differ diff --git a/web/simon/audio/voice/male/score_band3.ogg b/web/simon/audio/voice/male/score_band3.ogg index 4b3fef01..c70509ec 100644 Binary files a/web/simon/audio/voice/male/score_band3.ogg and b/web/simon/audio/voice/male/score_band3.ogg differ diff --git a/web/simon/audio/voice/male/score_band4.ogg b/web/simon/audio/voice/male/score_band4.ogg index aca33c52..60b6ac16 100644 Binary files a/web/simon/audio/voice/male/score_band4.ogg and b/web/simon/audio/voice/male/score_band4.ogg differ diff --git a/web/simon/audio/voice/male/score_band5.ogg b/web/simon/audio/voice/male/score_band5.ogg index 8975c710..281f8ff0 100644 Binary files a/web/simon/audio/voice/male/score_band5.ogg and b/web/simon/audio/voice/male/score_band5.ogg differ diff --git a/web/simon/audio/voice/male/score_band6.ogg b/web/simon/audio/voice/male/score_band6.ogg index a1bc22de..b712697d 100644 Binary files a/web/simon/audio/voice/male/score_band6.ogg and b/web/simon/audio/voice/male/score_band6.ogg differ diff --git a/web/simon/audio/voice/male/skip_hint.ogg b/web/simon/audio/voice/male/skip_hint.ogg index 7149fc95..e45121c0 100644 Binary files a/web/simon/audio/voice/male/skip_hint.ogg and b/web/simon/audio/voice/male/skip_hint.ogg differ diff --git a/web/simon/audio/voice/male/t0_goal.ogg b/web/simon/audio/voice/male/t0_goal.ogg index 3b4840f1..fa989c84 100644 Binary files a/web/simon/audio/voice/male/t0_goal.ogg and b/web/simon/audio/voice/male/t0_goal.ogg differ diff --git a/web/simon/audio/voice/male/t0_welcome.ogg b/web/simon/audio/voice/male/t0_welcome.ogg index c1584adb..9d201494 100644 Binary files a/web/simon/audio/voice/male/t0_welcome.ogg and b/web/simon/audio/voice/male/t0_welcome.ogg differ diff --git a/web/simon/audio/voice/male/t1_up.ogg b/web/simon/audio/voice/male/t1_up.ogg index e20da5ac..4d177bf7 100644 Binary files a/web/simon/audio/voice/male/t1_up.ogg and b/web/simon/audio/voice/male/t1_up.ogg differ diff --git a/web/simon/audio/voice/male/t2_down.ogg b/web/simon/audio/voice/male/t2_down.ogg index 4932af6b..14d16d02 100644 Binary files a/web/simon/audio/voice/male/t2_down.ogg and b/web/simon/audio/voice/male/t2_down.ogg differ diff --git a/web/simon/audio/voice/male/t3_left.ogg b/web/simon/audio/voice/male/t3_left.ogg index b14342ef..59adbe81 100644 Binary files a/web/simon/audio/voice/male/t3_left.ogg and b/web/simon/audio/voice/male/t3_left.ogg differ diff --git a/web/simon/audio/voice/male/t4_right.ogg b/web/simon/audio/voice/male/t4_right.ogg index 476ad566..08e5c18a 100644 Binary files a/web/simon/audio/voice/male/t4_right.ogg and b/web/simon/audio/voice/male/t4_right.ogg differ diff --git a/web/simon/audio/voice/male/t5_tap.ogg b/web/simon/audio/voice/male/t5_tap.ogg index ebc24eb4..7962305f 100644 Binary files a/web/simon/audio/voice/male/t5_tap.ogg and b/web/simon/audio/voice/male/t5_tap.ogg differ diff --git a/web/simon/audio/voice/male/t6_double.ogg b/web/simon/audio/voice/male/t6_double.ogg index dc431a26..017a030c 100644 Binary files a/web/simon/audio/voice/male/t6_double.ogg and b/web/simon/audio/voice/male/t6_double.ogg differ diff --git a/web/simon/audio/voice/male/t7_ready.ogg b/web/simon/audio/voice/male/t7_ready.ogg index a7fd5330..7f60c2f8 100644 Binary files a/web/simon/audio/voice/male/t7_ready.ogg and b/web/simon/audio/voice/male/t7_ready.ogg differ diff --git a/web/simon/audio/voice/male/t7_retry.m4a b/web/simon/audio/voice/male/t7_retry.m4a index 1f855fc7..fb414c06 100644 Binary files a/web/simon/audio/voice/male/t7_retry.m4a and b/web/simon/audio/voice/male/t7_retry.m4a differ diff --git a/web/simon/audio/voice/male/t7_retry.ogg b/web/simon/audio/voice/male/t7_retry.ogg index 8553cfe2..018f5937 100644 Binary files a/web/simon/audio/voice/male/t7_retry.ogg and b/web/simon/audio/voice/male/t7_retry.ogg differ diff --git a/web/simon/audio/voice/male/t_blunt_double.ogg b/web/simon/audio/voice/male/t_blunt_double.ogg index 5b21303e..382994ff 100644 Binary files a/web/simon/audio/voice/male/t_blunt_double.ogg and b/web/simon/audio/voice/male/t_blunt_double.ogg differ diff --git a/web/simon/audio/voice/male/t_blunt_down.ogg b/web/simon/audio/voice/male/t_blunt_down.ogg index d008663e..4198ceaf 100644 Binary files a/web/simon/audio/voice/male/t_blunt_down.ogg and b/web/simon/audio/voice/male/t_blunt_down.ogg differ diff --git a/web/simon/audio/voice/male/t_blunt_left.ogg b/web/simon/audio/voice/male/t_blunt_left.ogg index 60929c28..c389b668 100644 Binary files a/web/simon/audio/voice/male/t_blunt_left.ogg and b/web/simon/audio/voice/male/t_blunt_left.ogg differ diff --git a/web/simon/audio/voice/male/t_blunt_right.ogg b/web/simon/audio/voice/male/t_blunt_right.ogg index c51609b2..68360df0 100644 Binary files a/web/simon/audio/voice/male/t_blunt_right.ogg and b/web/simon/audio/voice/male/t_blunt_right.ogg differ diff --git a/web/simon/audio/voice/male/t_blunt_tap.ogg b/web/simon/audio/voice/male/t_blunt_tap.ogg index 98611729..6ad4d39d 100644 Binary files a/web/simon/audio/voice/male/t_blunt_tap.ogg and b/web/simon/audio/voice/male/t_blunt_tap.ogg differ diff --git a/web/simon/audio/voice/male/t_blunt_up.ogg b/web/simon/audio/voice/male/t_blunt_up.ogg index 716969bd..4931c2b8 100644 Binary files a/web/simon/audio/voice/male/t_blunt_up.ogg and b/web/simon/audio/voice/male/t_blunt_up.ogg differ diff --git a/web/simon/audio/voice/male/t_ok.ogg b/web/simon/audio/voice/male/t_ok.ogg index a49b4679..f0fc9d62 100644 Binary files a/web/simon/audio/voice/male/t_ok.ogg and b/web/simon/audio/voice/male/t_ok.ogg differ diff --git a/web/simon/audio/voice/male/t_skip.ogg b/web/simon/audio/voice/male/t_skip.ogg index b360034b..ab05564d 100644 Binary files a/web/simon/audio/voice/male/t_skip.ogg and b/web/simon/audio/voice/male/t_skip.ogg differ diff --git a/web/simon/audio/voice/male/t_try.ogg b/web/simon/audio/voice/male/t_try.ogg index c27b6ba8..3de46b1a 100644 Binary files a/web/simon/audio/voice/male/t_try.ogg and b/web/simon/audio/voice/male/t_try.ogg differ diff --git a/web/simon/audio/voice/male/t_wrong_double.ogg b/web/simon/audio/voice/male/t_wrong_double.ogg index 25016ba7..7740cd5d 100644 Binary files a/web/simon/audio/voice/male/t_wrong_double.ogg and b/web/simon/audio/voice/male/t_wrong_double.ogg differ diff --git a/web/simon/audio/voice/male/t_wrong_down.ogg b/web/simon/audio/voice/male/t_wrong_down.ogg index 1a2a9be0..e3921484 100644 Binary files a/web/simon/audio/voice/male/t_wrong_down.ogg and b/web/simon/audio/voice/male/t_wrong_down.ogg differ diff --git a/web/simon/audio/voice/male/t_wrong_left.ogg b/web/simon/audio/voice/male/t_wrong_left.ogg index c40f4a76..e849c60b 100644 Binary files a/web/simon/audio/voice/male/t_wrong_left.ogg and b/web/simon/audio/voice/male/t_wrong_left.ogg differ diff --git a/web/simon/audio/voice/male/t_wrong_right.ogg b/web/simon/audio/voice/male/t_wrong_right.ogg index 436a36de..df1d191c 100644 Binary files a/web/simon/audio/voice/male/t_wrong_right.ogg and b/web/simon/audio/voice/male/t_wrong_right.ogg differ diff --git a/web/simon/audio/voice/male/t_wrong_tap.ogg b/web/simon/audio/voice/male/t_wrong_tap.ogg index 25c9c6b3..702bdbf0 100644 Binary files a/web/simon/audio/voice/male/t_wrong_tap.ogg and b/web/simon/audio/voice/male/t_wrong_tap.ogg differ diff --git a/web/simon/audio/voice/male/t_wrong_up.ogg b/web/simon/audio/voice/male/t_wrong_up.ogg index 71178c1c..334a502b 100644 Binary files a/web/simon/audio/voice/male/t_wrong_up.ogg and b/web/simon/audio/voice/male/t_wrong_up.ogg differ diff --git a/web/simon/audio/voice/male/wrong.ogg b/web/simon/audio/voice/male/wrong.ogg index f5292173..db75742d 100644 Binary files a/web/simon/audio/voice/male/wrong.ogg and b/web/simon/audio/voice/male/wrong.ogg differ diff --git a/web/simon/audio/voice/male/your_turn.ogg b/web/simon/audio/voice/male/your_turn.ogg index 740bf0c0..64704a57 100644 Binary files a/web/simon/audio/voice/male/your_turn.ogg and b/web/simon/audio/voice/male/your_turn.ogg differ diff --git a/web/simon/game.js b/web/simon/game.js index fa674e85..472f8b7d 100644 --- a/web/simon/game.js +++ b/web/simon/game.js @@ -19,10 +19,12 @@ * - 反馈全部改震动:对/错 SUCCESS/ERROR,sfx/correct、wrong、newrecord 已删除; * sfx/gameover 保留为内容性结束音。 * - * 设计冲突的处理(02 文档 §4.2 与 §6.3):双击既是六种音色之一(序列可出现 - * doubletap)又是"主动重听"手势。本实现按**上下文**判定:输入阶段若当前期望 - * 输入恰为 doubletap,双击视为答题;否则视为重听(有机会时)。两者不会同时 - * 歧义落空——序列永远可答,重听仅在"不期望双击"时可用。 + * 设计冲突的处理(round3 synthesis G5 裁定,替代 round2 的双击语境判定):双击是 + * 六种音色之一(序列可出现 doubletap),历史上又兼「主动重听」。round3 改全局规则: + * **input 阶段双击永远=作答(第 6 音色)**——期望恰为 doubletap 判对,否则照常判错, + * 不再承担重听;主动重听改绑**上滑**(期望输入恰为 up 时上滑=作答,六手势全是 + * 答题输入的 00 §5.3 豁免同款)。非输入阶段行为不变(gameover/菜单上滑仍是规则/ + * 帮助)。同一手势在 input 阶段不再有第二种含义(P1 round2 P0 根治)。 * * 手势 → 音色映射: * up 上行琶音 / down 下行低音 / left 左声道弹拨 / right 右声道弹拨 / @@ -87,6 +89,9 @@ export class SimonGame extends Game { this._menuIdx = 0; this._session = 0; // 会话令牌:重开后使旧计时器/语音链回调失效 this._timers = []; + // G6(round3):轮结算链尾轻量反馈每局各限 1 次 + this._clearSaid = false; + this._recordSaid = false; } start() { @@ -205,8 +210,9 @@ export class SimonGame extends Game { if (this.teachIdx + 1 < GESTURES.length) { this._teachStep(this.teachIdx + 1); } else { - // T7:收尾两句 + 机会经济一句(round2 F5:记不住就双击重听、免费两次、 - // 用完扣机会——P1「经济不透明」开局一句话讲清)→ 正式对局 + // T7:收尾两句 + 机会经济一句(round2 F5 → round3 G5 重录:记不住就 + // 向上滑重新听、免费两次、用完扣机会——P1「经济不透明」开局一句话 + // 讲清,且与新手势映射一致)→ 正式对局 this._speakGuarded(['voice/t7_ready', 'voice/t7_retry', 'voice/gd_economy'], () => this._beginGame(), 20000); } @@ -234,6 +240,8 @@ export class SimonGame extends Game { this.sequence = []; this.round = 0; this.chances = 1; + this._clearSaid = false; // G6:每局重新封顶 + this._recordSaid = false; this._nextRound(); } @@ -346,9 +354,10 @@ export class SimonGame extends Game { } _onInput(g) { - // 双击的上下文判定(见文件头"设计冲突的处理"): - // 期望输入是 doubletap → 答题;否则 → 主动重听(耗机会) - if (g === 'doubletap' && this.sequence[this.inputIdx] !== 'doubletap') { + // G5(round3):双击永远=作答(第 6 音色)——期望恰为 doubletap 判对,否则 + // 照常判错,不再承担重听。主动重听改绑上滑:期望输入恰为 up 时上滑=作答 + // (六手势全是答题输入,00 §5.3 豁免同款),其余时刻上滑=主动重听(耗机会)。 + if (g === 'up' && this.sequence[this.inputIdx] !== 'up') { this._relisten(); return; } @@ -390,6 +399,18 @@ export class SimonGame extends Game { vibrate('pickup'); ids.push('voice/chance_plus'); } + // G6(round3):轮结算链尾轻量反馈——gd_clear「漂亮,过了。」每局 1 次; + // 本轮完成数超过历史最佳(且确有旧纪录可破)时追加 gd_record「破纪录了。」 + // 每局 1 次(结算另有 new_record,此处是局中破纪录的即时一刻)。游戏规则句 + // 随链播(全档位,gd_economy 先例),不走向导通道。 + if (!this._clearSaid) { + this._clearSaid = true; + ids.push('voice/gd_clear'); + } + if (!this._recordSaid && this.best > 0 && this.round > this.best) { + this._recordSaid = true; + ids.push('voice/gd_record'); + } this._speakGuarded(ids, () => { if (s !== this._session) return; this._timer(() => this._nextRound(), 300); diff --git a/web/simon/test/playtest.mjs b/web/simon/test/playtest.mjs index 798c15e5..d5f496cf 100644 --- a/web/simon/test/playtest.mjs +++ b/web/simon/test/playtest.mjs @@ -375,6 +375,13 @@ async function answerPastDoubletaps() { } } +/** 把前缀里连续的 up 答掉,直到期望输入非 up(round3 G5:期望恰为 up 时上滑=作答)。 */ +async function answerPastUps() { + while (game.phase === 'input' && game.sequence[game.inputIdx] === 'up') { + await gesture('up'); // 期望即 up → 答题 + } +} + // ---------------------------------------------------------------- 第 1-3 轮 section('第 1-3 轮(含单击跳播报、playback 忽略、看门狗)'); assert(game._interval() === 700, '第 1 轮播放间隔 700ms'); @@ -398,7 +405,8 @@ assert(game.chances === 1, '初始 1 次重听机会'); { const prevSeq = game.sequence; const exp = game.sequence[0]; - const wrong = GESTURES.find((g) => g !== exp && g !== 'doubletap'); + // round3 G5:up=重听键,注入错手势时避开(否则触发重听而非判错) + const wrong = GESTURES.find((g) => g !== exp && g !== 'doubletap' && g !== 'up'); await gesture(wrong); assert(game.chances === 0, '答错自动消耗复活:chances 1→0'); assert(game.phase === 'roundend' && played('voice/retry_use'), '播 retry_use'); @@ -415,26 +423,29 @@ assert(game.chances === 1, '每完成 4 轮 chances +1(回到 1)'); assert(played('voice/chance_plus'), '播 chance_plus'); // ---------------------------------------------------------------- 第 5 轮:主动重听 + 边界 -section('第 5 轮:主动重听 / chances=0 双击 / 双击冲突裁定'); +section('第 5 轮:主动重听(上滑)/ chances=0 上滑 / 双击=作答(round3 G5,13 号文档 §8 变更记录)'); await toInputViaSkip(5); { + // round3 G5:input 阶段双击永远=作答,主动重听改绑上滑(期望恰为 up 时上滑=作答) await answerPastDoubletaps(); + await answerPastUps(); // 先把期望恰为 up 的音答掉 const relistenCount = playCount('voice/relisten'); - await gesture('doubletap'); // 期望非 doubletap → 主动重听 + await gesture('up'); // 期望非 up → 主动重听 assert(game.chances === 0, '主动重听耗机会:chances 1→0'); assert(playCount('voice/relisten') === relistenCount + 1 && game.phase === 'roundend', '播 relisten 并重播'); await advanceUntil(() => game.phase === 'input', { desc: '重听重播后回输入' }); assert(game.inputIdx === 0, '重听后输入进度清零'); } { - // chances=0 时双击非期望手势:不判错、播 chances_out + // chances=0 时上滑非期望手势:不判错、播 chances_out await answerPastDoubletaps(); + await answerPastUps(); const round = game.round; const idx = game.inputIdx; const coCount = playCount('voice/chances_out'); - await gesture('doubletap'); - assert(game.phase === 'input' && game.round === round && game.inputIdx === idx, 'chances=0 双击非期望:不判错(round/inputIdx 不变)'); - assert(playCount('voice/chances_out') === coCount + 1, 'chances=0 双击播 chances_out'); + await gesture('up'); + assert(game.phase === 'input' && game.round === round && game.inputIdx === idx, 'chances=0 上滑非期望:不判错(round/inputIdx 不变)'); + assert(playCount('voice/chances_out') === coCount + 1, 'chances=0 上滑播 chances_out'); assert(game.chances === 0, 'chances 不变(不为负)'); } // 答完第 5 轮(途中验证双击=答题);若本轮没遇到 doubletap 则继续往下轮找 @@ -459,7 +470,8 @@ assert(game.chances === 0, '复活已耗尽'); const finalRound = game.round; { const exp = game.sequence[game.inputIdx]; - const wrong = GESTURES.find((g) => g !== exp && g !== 'doubletap'); + // round3 G5:up=重听键,注入错手势时避开 + const wrong = GESTURES.find((g) => g !== exp && g !== 'doubletap' && g !== 'up'); await gesture(wrong); } assert(game.phase === 'gameover', 'chances=0 答错 → gameover'); diff --git a/web/space/audio/voice/female/dir_down.m4a b/web/space/audio/voice/female/dir_down.m4a new file mode 100644 index 00000000..b954baa2 Binary files /dev/null and b/web/space/audio/voice/female/dir_down.m4a differ diff --git a/web/space/audio/voice/female/dir_down.ogg b/web/space/audio/voice/female/dir_down.ogg new file mode 100644 index 00000000..21399ebe Binary files /dev/null and b/web/space/audio/voice/female/dir_down.ogg differ diff --git a/web/space/audio/voice/female/dir_left.m4a b/web/space/audio/voice/female/dir_left.m4a new file mode 100644 index 00000000..6d4d5946 Binary files /dev/null and b/web/space/audio/voice/female/dir_left.m4a differ diff --git a/web/space/audio/voice/female/dir_left.ogg b/web/space/audio/voice/female/dir_left.ogg new file mode 100644 index 00000000..1d6fe2a9 Binary files /dev/null and b/web/space/audio/voice/female/dir_left.ogg differ diff --git a/web/space/audio/voice/female/dir_right.m4a b/web/space/audio/voice/female/dir_right.m4a new file mode 100644 index 00000000..a2d62873 Binary files /dev/null and b/web/space/audio/voice/female/dir_right.m4a differ diff --git a/web/space/audio/voice/female/dir_right.ogg b/web/space/audio/voice/female/dir_right.ogg new file mode 100644 index 00000000..ea2e7874 Binary files /dev/null and b/web/space/audio/voice/female/dir_right.ogg differ diff --git a/web/space/audio/voice/female/dir_up.m4a b/web/space/audio/voice/female/dir_up.m4a new file mode 100644 index 00000000..b688fde1 Binary files /dev/null and b/web/space/audio/voice/female/dir_up.m4a differ diff --git a/web/space/audio/voice/female/dir_up.ogg b/web/space/audio/voice/female/dir_up.ogg new file mode 100644 index 00000000..cecf0769 Binary files /dev/null and b/web/space/audio/voice/female/dir_up.ogg differ diff --git a/web/space/audio/voice/female/dodge_1.ogg b/web/space/audio/voice/female/dodge_1.ogg index 3c8d808d..0756b9d4 100644 Binary files a/web/space/audio/voice/female/dodge_1.ogg and b/web/space/audio/voice/female/dodge_1.ogg differ diff --git a/web/space/audio/voice/female/dodge_2.ogg b/web/space/audio/voice/female/dodge_2.ogg index fd2a7963..5dd841bf 100644 Binary files a/web/space/audio/voice/female/dodge_2.ogg and b/web/space/audio/voice/female/dodge_2.ogg differ diff --git a/web/space/audio/voice/female/dodge_3.ogg b/web/space/audio/voice/female/dodge_3.ogg index 9adfd7e7..dcf080a9 100644 Binary files a/web/space/audio/voice/female/dodge_3.ogg and b/web/space/audio/voice/female/dodge_3.ogg differ diff --git a/web/space/audio/voice/female/dodge_4.ogg b/web/space/audio/voice/female/dodge_4.ogg index 3999b115..ee02e1c9 100644 Binary files a/web/space/audio/voice/female/dodge_4.ogg and b/web/space/audio/voice/female/dodge_4.ogg differ diff --git a/web/space/audio/voice/female/drill_done.ogg b/web/space/audio/voice/female/drill_done.ogg index d438685d..79c7753b 100644 Binary files a/web/space/audio/voice/female/drill_done.ogg and b/web/space/audio/voice/female/drill_done.ogg differ diff --git a/web/space/audio/voice/female/drill_down.ogg b/web/space/audio/voice/female/drill_down.ogg index 003f991f..c8afe457 100644 Binary files a/web/space/audio/voice/female/drill_down.ogg and b/web/space/audio/voice/female/drill_down.ogg differ diff --git a/web/space/audio/voice/female/drill_good.ogg b/web/space/audio/voice/female/drill_good.ogg index 7226008d..58b2b8f7 100644 Binary files a/web/space/audio/voice/female/drill_good.ogg and b/web/space/audio/voice/female/drill_good.ogg differ diff --git a/web/space/audio/voice/female/drill_left.ogg b/web/space/audio/voice/female/drill_left.ogg index 451e229b..91104ed0 100644 Binary files a/web/space/audio/voice/female/drill_left.ogg and b/web/space/audio/voice/female/drill_left.ogg differ diff --git a/web/space/audio/voice/female/drill_moveon.ogg b/web/space/audio/voice/female/drill_moveon.ogg index 2062de2c..127515de 100644 Binary files a/web/space/audio/voice/female/drill_moveon.ogg and b/web/space/audio/voice/female/drill_moveon.ogg differ diff --git a/web/space/audio/voice/female/drill_retry_down.ogg b/web/space/audio/voice/female/drill_retry_down.ogg index ce54e446..5e3dbb4c 100644 Binary files a/web/space/audio/voice/female/drill_retry_down.ogg and b/web/space/audio/voice/female/drill_retry_down.ogg differ diff --git a/web/space/audio/voice/female/drill_retry_left.ogg b/web/space/audio/voice/female/drill_retry_left.ogg index bd16a2b3..8d12aaa0 100644 Binary files a/web/space/audio/voice/female/drill_retry_left.ogg and b/web/space/audio/voice/female/drill_retry_left.ogg differ diff --git a/web/space/audio/voice/female/drill_retry_right.ogg b/web/space/audio/voice/female/drill_retry_right.ogg index 3f621d5e..192a6d03 100644 Binary files a/web/space/audio/voice/female/drill_retry_right.ogg and b/web/space/audio/voice/female/drill_retry_right.ogg differ diff --git a/web/space/audio/voice/female/drill_retry_up.ogg b/web/space/audio/voice/female/drill_retry_up.ogg index f561d914..c61ae6f3 100644 Binary files a/web/space/audio/voice/female/drill_retry_up.ogg and b/web/space/audio/voice/female/drill_retry_up.ogg differ diff --git a/web/space/audio/voice/female/drill_right.ogg b/web/space/audio/voice/female/drill_right.ogg index 8fabfbd8..e46e6368 100644 Binary files a/web/space/audio/voice/female/drill_right.ogg and b/web/space/audio/voice/female/drill_right.ogg differ diff --git a/web/space/audio/voice/female/drill_rule.ogg b/web/space/audio/voice/female/drill_rule.ogg index bfd917b0..690a3b61 100644 Binary files a/web/space/audio/voice/female/drill_rule.ogg and b/web/space/audio/voice/female/drill_rule.ogg differ diff --git a/web/space/audio/voice/female/drill_skip.ogg b/web/space/audio/voice/female/drill_skip.ogg index 1226adde..96223092 100644 Binary files a/web/space/audio/voice/female/drill_skip.ogg and b/web/space/audio/voice/female/drill_skip.ogg differ diff --git a/web/space/audio/voice/female/drill_up.ogg b/web/space/audio/voice/female/drill_up.ogg index eea2746a..298df44a 100644 Binary files a/web/space/audio/voice/female/drill_up.ogg and b/web/space/audio/voice/female/drill_up.ogg differ diff --git a/web/space/audio/voice/female/drill_welcome.ogg b/web/space/audio/voice/female/drill_welcome.ogg index c6315b91..0d81edac 100644 Binary files a/web/space/audio/voice/female/drill_welcome.ogg and b/web/space/audio/voice/female/drill_welcome.ogg differ diff --git a/web/space/audio/voice/female/feat_boost.ogg b/web/space/audio/voice/female/feat_boost.ogg index a261fe48..7391b27a 100644 Binary files a/web/space/audio/voice/female/feat_boost.ogg and b/web/space/audio/voice/female/feat_boost.ogg differ diff --git a/web/space/audio/voice/female/feat_boost_done.ogg b/web/space/audio/voice/female/feat_boost_done.ogg index ef6c3e83..d7adcd0a 100644 Binary files a/web/space/audio/voice/female/feat_boost_done.ogg and b/web/space/audio/voice/female/feat_boost_done.ogg differ diff --git a/web/space/audio/voice/female/feat_shield.ogg b/web/space/audio/voice/female/feat_shield.ogg index f7c9c128..82fdd707 100644 Binary files a/web/space/audio/voice/female/feat_shield.ogg and b/web/space/audio/voice/female/feat_shield.ogg differ diff --git a/web/space/audio/voice/female/feat_shield_done.ogg b/web/space/audio/voice/female/feat_shield_done.ogg index 8e9434b1..eade815c 100644 Binary files a/web/space/audio/voice/female/feat_shield_done.ogg and b/web/space/audio/voice/female/feat_shield_done.ogg differ diff --git a/web/space/audio/voice/female/gd_hit_hint.ogg b/web/space/audio/voice/female/gd_hit_hint.ogg index 250a1280..5c459a10 100644 Binary files a/web/space/audio/voice/female/gd_hit_hint.ogg and b/web/space/audio/voice/female/gd_hit_hint.ogg differ diff --git a/web/space/audio/voice/female/gd_last_life.ogg b/web/space/audio/voice/female/gd_last_life.ogg index 6162f036..6d7aa831 100644 Binary files a/web/space/audio/voice/female/gd_last_life.ogg and b/web/space/audio/voice/female/gd_last_life.ogg differ diff --git a/web/space/audio/voice/female/help_recap.ogg b/web/space/audio/voice/female/help_recap.ogg index 58fb6e56..ef64883c 100644 Binary files a/web/space/audio/voice/female/help_recap.ogg and b/web/space/audio/voice/female/help_recap.ogg differ diff --git a/web/space/audio/voice/female/hit_down.ogg b/web/space/audio/voice/female/hit_down.ogg index e6b7cf53..6b390ffc 100644 Binary files a/web/space/audio/voice/female/hit_down.ogg and b/web/space/audio/voice/female/hit_down.ogg differ diff --git a/web/space/audio/voice/female/hit_last.ogg b/web/space/audio/voice/female/hit_last.ogg index 787db9b7..0ea48763 100644 Binary files a/web/space/audio/voice/female/hit_last.ogg and b/web/space/audio/voice/female/hit_last.ogg differ diff --git a/web/space/audio/voice/female/hit_left.ogg b/web/space/audio/voice/female/hit_left.ogg index beb4ca55..95fa0614 100644 Binary files a/web/space/audio/voice/female/hit_left.ogg and b/web/space/audio/voice/female/hit_left.ogg differ diff --git a/web/space/audio/voice/female/hit_right.ogg b/web/space/audio/voice/female/hit_right.ogg index 9d2b0aef..989339f2 100644 Binary files a/web/space/audio/voice/female/hit_right.ogg and b/web/space/audio/voice/female/hit_right.ogg differ diff --git a/web/space/audio/voice/female/hit_up.ogg b/web/space/audio/voice/female/hit_up.ogg index 2efcb3e9..63854da7 100644 Binary files a/web/space/audio/voice/female/hit_up.ogg and b/web/space/audio/voice/female/hit_up.ogg differ diff --git a/web/space/audio/voice/female/menu_help.ogg b/web/space/audio/voice/female/menu_help.ogg index f26b4c7b..70133436 100644 Binary files a/web/space/audio/voice/female/menu_help.ogg and b/web/space/audio/voice/female/menu_help.ogg differ diff --git a/web/space/audio/voice/female/menu_lobby.ogg b/web/space/audio/voice/female/menu_lobby.ogg index 4decea35..bd82b38c 100644 Binary files a/web/space/audio/voice/female/menu_lobby.ogg and b/web/space/audio/voice/female/menu_lobby.ogg differ diff --git a/web/space/audio/voice/female/menu_main.ogg b/web/space/audio/voice/female/menu_main.ogg index 40336488..cc88d134 100644 Binary files a/web/space/audio/voice/female/menu_main.ogg and b/web/space/audio/voice/female/menu_main.ogg differ diff --git a/web/space/audio/voice/female/menu_resume.ogg b/web/space/audio/voice/female/menu_resume.ogg index e486aeb1..6c1d9cea 100644 Binary files a/web/space/audio/voice/female/menu_resume.ogg and b/web/space/audio/voice/female/menu_resume.ogg differ diff --git a/web/space/audio/voice/female/ms_10.ogg b/web/space/audio/voice/female/ms_10.ogg index 60f01dfb..babd8f43 100644 Binary files a/web/space/audio/voice/female/ms_10.ogg and b/web/space/audio/voice/female/ms_10.ogg differ diff --git a/web/space/audio/voice/female/ms_100.ogg b/web/space/audio/voice/female/ms_100.ogg index fae5e6e3..9c19f688 100644 Binary files a/web/space/audio/voice/female/ms_100.ogg and b/web/space/audio/voice/female/ms_100.ogg differ diff --git a/web/space/audio/voice/female/ms_25.ogg b/web/space/audio/voice/female/ms_25.ogg index 472456d8..3617bc10 100644 Binary files a/web/space/audio/voice/female/ms_25.ogg and b/web/space/audio/voice/female/ms_25.ogg differ diff --git a/web/space/audio/voice/female/ms_50.ogg b/web/space/audio/voice/female/ms_50.ogg index 51832307..b8b5fb37 100644 Binary files a/web/space/audio/voice/female/ms_50.ogg and b/web/space/audio/voice/female/ms_50.ogg differ diff --git a/web/space/audio/voice/female/new_record.ogg b/web/space/audio/voice/female/new_record.ogg index 684aca5f..e3873b88 100644 Binary files a/web/space/audio/voice/female/new_record.ogg and b/web/space/audio/voice/female/new_record.ogg differ diff --git a/web/space/audio/voice/female/paused.ogg b/web/space/audio/voice/female/paused.ogg index e6b5c25c..abaa864e 100644 Binary files a/web/space/audio/voice/female/paused.ogg and b/web/space/audio/voice/female/paused.ogg differ diff --git a/web/space/audio/voice/female/protect_down.ogg b/web/space/audio/voice/female/protect_down.ogg index e8def423..d4220e1f 100644 Binary files a/web/space/audio/voice/female/protect_down.ogg and b/web/space/audio/voice/female/protect_down.ogg differ diff --git a/web/space/audio/voice/female/protect_end.ogg b/web/space/audio/voice/female/protect_end.ogg index 610c58a5..a2aa8360 100644 Binary files a/web/space/audio/voice/female/protect_end.ogg and b/web/space/audio/voice/female/protect_end.ogg differ diff --git a/web/space/audio/voice/female/protect_left.ogg b/web/space/audio/voice/female/protect_left.ogg index 98db3d18..e8626ee6 100644 Binary files a/web/space/audio/voice/female/protect_left.ogg and b/web/space/audio/voice/female/protect_left.ogg differ diff --git a/web/space/audio/voice/female/protect_right.ogg b/web/space/audio/voice/female/protect_right.ogg index 619ccab6..06fdd071 100644 Binary files a/web/space/audio/voice/female/protect_right.ogg and b/web/space/audio/voice/female/protect_right.ogg differ diff --git a/web/space/audio/voice/female/protect_up.ogg b/web/space/audio/voice/female/protect_up.ogg index 74c9bb2b..1b719c91 100644 Binary files a/web/space/audio/voice/female/protect_up.ogg and b/web/space/audio/voice/female/protect_up.ogg differ diff --git a/web/space/audio/voice/female/restart_hint.ogg b/web/space/audio/voice/female/restart_hint.ogg index b654115a..41679109 100644 Binary files a/web/space/audio/voice/female/restart_hint.ogg and b/web/space/audio/voice/female/restart_hint.ogg differ diff --git a/web/space/audio/voice/female/second_run_ask.ogg b/web/space/audio/voice/female/second_run_ask.ogg index 0914b5a5..d11bae89 100644 Binary files a/web/space/audio/voice/female/second_run_ask.ogg and b/web/space/audio/voice/female/second_run_ask.ogg differ diff --git a/web/space/audio/voice/female/settings_hint.ogg b/web/space/audio/voice/female/settings_hint.ogg index 60957db3..4b105570 100644 Binary files a/web/space/audio/voice/female/settings_hint.ogg and b/web/space/audio/voice/female/settings_hint.ogg differ diff --git a/web/space/audio/voice/female/shield_block.ogg b/web/space/audio/voice/female/shield_block.ogg index 169b22d6..304b824c 100644 Binary files a/web/space/audio/voice/female/shield_block.ogg and b/web/space/audio/voice/female/shield_block.ogg differ diff --git a/web/space/audio/voice/female/shield_ready.ogg b/web/space/audio/voice/female/shield_ready.ogg index bfeedc65..1fbddc39 100644 Binary files a/web/space/audio/voice/female/shield_ready.ogg and b/web/space/audio/voice/female/shield_ready.ogg differ diff --git a/web/space/audio/voice/female/skip_hint.ogg b/web/space/audio/voice/female/skip_hint.ogg index d83298cb..dc3fbb0c 100644 Binary files a/web/space/audio/voice/female/skip_hint.ogg and b/web/space/audio/voice/female/skip_hint.ogg differ diff --git a/web/space/audio/voice/female/time_1.ogg b/web/space/audio/voice/female/time_1.ogg index cadd4ea2..684d3718 100644 Binary files a/web/space/audio/voice/female/time_1.ogg and b/web/space/audio/voice/female/time_1.ogg differ diff --git a/web/space/audio/voice/female/time_2.ogg b/web/space/audio/voice/female/time_2.ogg index 164136bf..3d30fa1d 100644 Binary files a/web/space/audio/voice/female/time_2.ogg and b/web/space/audio/voice/female/time_2.ogg differ diff --git a/web/space/audio/voice/female/time_3.ogg b/web/space/audio/voice/female/time_3.ogg index 35a3dd4b..5925aceb 100644 Binary files a/web/space/audio/voice/female/time_3.ogg and b/web/space/audio/voice/female/time_3.ogg differ diff --git a/web/space/audio/voice/female/time_4.ogg b/web/space/audio/voice/female/time_4.ogg index 68715cfb..cc6ba83d 100644 Binary files a/web/space/audio/voice/female/time_4.ogg and b/web/space/audio/voice/female/time_4.ogg differ diff --git a/web/space/audio/voice/male/dir_down.m4a b/web/space/audio/voice/male/dir_down.m4a new file mode 100644 index 00000000..618bdda0 Binary files /dev/null and b/web/space/audio/voice/male/dir_down.m4a differ diff --git a/web/space/audio/voice/male/dir_down.ogg b/web/space/audio/voice/male/dir_down.ogg new file mode 100644 index 00000000..df1698a1 Binary files /dev/null and b/web/space/audio/voice/male/dir_down.ogg differ diff --git a/web/space/audio/voice/male/dir_left.m4a b/web/space/audio/voice/male/dir_left.m4a new file mode 100644 index 00000000..ce78fb16 Binary files /dev/null and b/web/space/audio/voice/male/dir_left.m4a differ diff --git a/web/space/audio/voice/male/dir_left.ogg b/web/space/audio/voice/male/dir_left.ogg new file mode 100644 index 00000000..5b304bf1 Binary files /dev/null and b/web/space/audio/voice/male/dir_left.ogg differ diff --git a/web/space/audio/voice/male/dir_right.m4a b/web/space/audio/voice/male/dir_right.m4a new file mode 100644 index 00000000..45d7cb54 Binary files /dev/null and b/web/space/audio/voice/male/dir_right.m4a differ diff --git a/web/space/audio/voice/male/dir_right.ogg b/web/space/audio/voice/male/dir_right.ogg new file mode 100644 index 00000000..a6aca1c3 Binary files /dev/null and b/web/space/audio/voice/male/dir_right.ogg differ diff --git a/web/space/audio/voice/male/dir_up.m4a b/web/space/audio/voice/male/dir_up.m4a new file mode 100644 index 00000000..cad4085f Binary files /dev/null and b/web/space/audio/voice/male/dir_up.m4a differ diff --git a/web/space/audio/voice/male/dir_up.ogg b/web/space/audio/voice/male/dir_up.ogg new file mode 100644 index 00000000..09855ca9 Binary files /dev/null and b/web/space/audio/voice/male/dir_up.ogg differ diff --git a/web/space/audio/voice/male/dodge_1.ogg b/web/space/audio/voice/male/dodge_1.ogg index 508e21b8..0bd11396 100644 Binary files a/web/space/audio/voice/male/dodge_1.ogg and b/web/space/audio/voice/male/dodge_1.ogg differ diff --git a/web/space/audio/voice/male/dodge_2.ogg b/web/space/audio/voice/male/dodge_2.ogg index 8165a201..47e1435d 100644 Binary files a/web/space/audio/voice/male/dodge_2.ogg and b/web/space/audio/voice/male/dodge_2.ogg differ diff --git a/web/space/audio/voice/male/dodge_3.ogg b/web/space/audio/voice/male/dodge_3.ogg index 963d0c73..71dbf169 100644 Binary files a/web/space/audio/voice/male/dodge_3.ogg and b/web/space/audio/voice/male/dodge_3.ogg differ diff --git a/web/space/audio/voice/male/dodge_4.ogg b/web/space/audio/voice/male/dodge_4.ogg index 60f77a8d..9513208f 100644 Binary files a/web/space/audio/voice/male/dodge_4.ogg and b/web/space/audio/voice/male/dodge_4.ogg differ diff --git a/web/space/audio/voice/male/drill_done.ogg b/web/space/audio/voice/male/drill_done.ogg index c48ec145..61944ed0 100644 Binary files a/web/space/audio/voice/male/drill_done.ogg and b/web/space/audio/voice/male/drill_done.ogg differ diff --git a/web/space/audio/voice/male/drill_down.ogg b/web/space/audio/voice/male/drill_down.ogg index 65562882..ae219e75 100644 Binary files a/web/space/audio/voice/male/drill_down.ogg and b/web/space/audio/voice/male/drill_down.ogg differ diff --git a/web/space/audio/voice/male/drill_good.ogg b/web/space/audio/voice/male/drill_good.ogg index 1ebb8adb..59c55ab3 100644 Binary files a/web/space/audio/voice/male/drill_good.ogg and b/web/space/audio/voice/male/drill_good.ogg differ diff --git a/web/space/audio/voice/male/drill_left.ogg b/web/space/audio/voice/male/drill_left.ogg index 910e6fae..eaf35a0a 100644 Binary files a/web/space/audio/voice/male/drill_left.ogg and b/web/space/audio/voice/male/drill_left.ogg differ diff --git a/web/space/audio/voice/male/drill_moveon.ogg b/web/space/audio/voice/male/drill_moveon.ogg index a00dca76..14cfa727 100644 Binary files a/web/space/audio/voice/male/drill_moveon.ogg and b/web/space/audio/voice/male/drill_moveon.ogg differ diff --git a/web/space/audio/voice/male/drill_retry_down.ogg b/web/space/audio/voice/male/drill_retry_down.ogg index 81628924..74ba6aa7 100644 Binary files a/web/space/audio/voice/male/drill_retry_down.ogg and b/web/space/audio/voice/male/drill_retry_down.ogg differ diff --git a/web/space/audio/voice/male/drill_retry_left.ogg b/web/space/audio/voice/male/drill_retry_left.ogg index be57cf6b..3ecddf8a 100644 Binary files a/web/space/audio/voice/male/drill_retry_left.ogg and b/web/space/audio/voice/male/drill_retry_left.ogg differ diff --git a/web/space/audio/voice/male/drill_retry_right.ogg b/web/space/audio/voice/male/drill_retry_right.ogg index 7403e3e6..87547481 100644 Binary files a/web/space/audio/voice/male/drill_retry_right.ogg and b/web/space/audio/voice/male/drill_retry_right.ogg differ diff --git a/web/space/audio/voice/male/drill_retry_up.ogg b/web/space/audio/voice/male/drill_retry_up.ogg index e1274df3..a053458d 100644 Binary files a/web/space/audio/voice/male/drill_retry_up.ogg and b/web/space/audio/voice/male/drill_retry_up.ogg differ diff --git a/web/space/audio/voice/male/drill_right.ogg b/web/space/audio/voice/male/drill_right.ogg index 2432dc92..b24e2613 100644 Binary files a/web/space/audio/voice/male/drill_right.ogg and b/web/space/audio/voice/male/drill_right.ogg differ diff --git a/web/space/audio/voice/male/drill_rule.ogg b/web/space/audio/voice/male/drill_rule.ogg index eb180b73..d15c62c6 100644 Binary files a/web/space/audio/voice/male/drill_rule.ogg and b/web/space/audio/voice/male/drill_rule.ogg differ diff --git a/web/space/audio/voice/male/drill_skip.ogg b/web/space/audio/voice/male/drill_skip.ogg index f31b7417..3dea61b6 100644 Binary files a/web/space/audio/voice/male/drill_skip.ogg and b/web/space/audio/voice/male/drill_skip.ogg differ diff --git a/web/space/audio/voice/male/drill_up.ogg b/web/space/audio/voice/male/drill_up.ogg index a69bdc18..5085d9a2 100644 Binary files a/web/space/audio/voice/male/drill_up.ogg and b/web/space/audio/voice/male/drill_up.ogg differ diff --git a/web/space/audio/voice/male/drill_welcome.ogg b/web/space/audio/voice/male/drill_welcome.ogg index f2cc3d0f..ddef8d9c 100644 Binary files a/web/space/audio/voice/male/drill_welcome.ogg and b/web/space/audio/voice/male/drill_welcome.ogg differ diff --git a/web/space/audio/voice/male/feat_boost.ogg b/web/space/audio/voice/male/feat_boost.ogg index ca853946..9f02fa03 100644 Binary files a/web/space/audio/voice/male/feat_boost.ogg and b/web/space/audio/voice/male/feat_boost.ogg differ diff --git a/web/space/audio/voice/male/feat_boost_done.ogg b/web/space/audio/voice/male/feat_boost_done.ogg index 8ea1f830..5577a69e 100644 Binary files a/web/space/audio/voice/male/feat_boost_done.ogg and b/web/space/audio/voice/male/feat_boost_done.ogg differ diff --git a/web/space/audio/voice/male/feat_shield.ogg b/web/space/audio/voice/male/feat_shield.ogg index cb4fdc3b..26d83819 100644 Binary files a/web/space/audio/voice/male/feat_shield.ogg and b/web/space/audio/voice/male/feat_shield.ogg differ diff --git a/web/space/audio/voice/male/feat_shield_done.ogg b/web/space/audio/voice/male/feat_shield_done.ogg index 6e615885..44779aba 100644 Binary files a/web/space/audio/voice/male/feat_shield_done.ogg and b/web/space/audio/voice/male/feat_shield_done.ogg differ diff --git a/web/space/audio/voice/male/gd_hit_hint.ogg b/web/space/audio/voice/male/gd_hit_hint.ogg index 569ba9ee..53bc6629 100644 Binary files a/web/space/audio/voice/male/gd_hit_hint.ogg and b/web/space/audio/voice/male/gd_hit_hint.ogg differ diff --git a/web/space/audio/voice/male/gd_last_life.ogg b/web/space/audio/voice/male/gd_last_life.ogg index 9c184d63..595348d0 100644 Binary files a/web/space/audio/voice/male/gd_last_life.ogg and b/web/space/audio/voice/male/gd_last_life.ogg differ diff --git a/web/space/audio/voice/male/help_recap.ogg b/web/space/audio/voice/male/help_recap.ogg index eb13ed7c..f672a85c 100644 Binary files a/web/space/audio/voice/male/help_recap.ogg and b/web/space/audio/voice/male/help_recap.ogg differ diff --git a/web/space/audio/voice/male/hit_down.ogg b/web/space/audio/voice/male/hit_down.ogg index f26c03e6..f9f10e25 100644 Binary files a/web/space/audio/voice/male/hit_down.ogg and b/web/space/audio/voice/male/hit_down.ogg differ diff --git a/web/space/audio/voice/male/hit_last.ogg b/web/space/audio/voice/male/hit_last.ogg index e3608264..b791372f 100644 Binary files a/web/space/audio/voice/male/hit_last.ogg and b/web/space/audio/voice/male/hit_last.ogg differ diff --git a/web/space/audio/voice/male/hit_left.ogg b/web/space/audio/voice/male/hit_left.ogg index d3fa8520..c9f8d163 100644 Binary files a/web/space/audio/voice/male/hit_left.ogg and b/web/space/audio/voice/male/hit_left.ogg differ diff --git a/web/space/audio/voice/male/hit_right.ogg b/web/space/audio/voice/male/hit_right.ogg index 751e4813..e9172264 100644 Binary files a/web/space/audio/voice/male/hit_right.ogg and b/web/space/audio/voice/male/hit_right.ogg differ diff --git a/web/space/audio/voice/male/hit_up.ogg b/web/space/audio/voice/male/hit_up.ogg index 2b093264..ea748f29 100644 Binary files a/web/space/audio/voice/male/hit_up.ogg and b/web/space/audio/voice/male/hit_up.ogg differ diff --git a/web/space/audio/voice/male/menu_help.ogg b/web/space/audio/voice/male/menu_help.ogg index 4f6046f5..6d6dd74d 100644 Binary files a/web/space/audio/voice/male/menu_help.ogg and b/web/space/audio/voice/male/menu_help.ogg differ diff --git a/web/space/audio/voice/male/menu_lobby.ogg b/web/space/audio/voice/male/menu_lobby.ogg index 2a02eb9b..4b13cdef 100644 Binary files a/web/space/audio/voice/male/menu_lobby.ogg and b/web/space/audio/voice/male/menu_lobby.ogg differ diff --git a/web/space/audio/voice/male/menu_main.ogg b/web/space/audio/voice/male/menu_main.ogg index b65c374e..5d2d515b 100644 Binary files a/web/space/audio/voice/male/menu_main.ogg and b/web/space/audio/voice/male/menu_main.ogg differ diff --git a/web/space/audio/voice/male/menu_resume.ogg b/web/space/audio/voice/male/menu_resume.ogg index d5ffeda5..6c156aec 100644 Binary files a/web/space/audio/voice/male/menu_resume.ogg and b/web/space/audio/voice/male/menu_resume.ogg differ diff --git a/web/space/audio/voice/male/ms_10.ogg b/web/space/audio/voice/male/ms_10.ogg index d33513fa..0b9cd3cb 100644 Binary files a/web/space/audio/voice/male/ms_10.ogg and b/web/space/audio/voice/male/ms_10.ogg differ diff --git a/web/space/audio/voice/male/ms_100.ogg b/web/space/audio/voice/male/ms_100.ogg index 1737162d..d38bad99 100644 Binary files a/web/space/audio/voice/male/ms_100.ogg and b/web/space/audio/voice/male/ms_100.ogg differ diff --git a/web/space/audio/voice/male/ms_25.ogg b/web/space/audio/voice/male/ms_25.ogg index 11f462a2..825d7c76 100644 Binary files a/web/space/audio/voice/male/ms_25.ogg and b/web/space/audio/voice/male/ms_25.ogg differ diff --git a/web/space/audio/voice/male/ms_50.ogg b/web/space/audio/voice/male/ms_50.ogg index 44efbd00..aad4c049 100644 Binary files a/web/space/audio/voice/male/ms_50.ogg and b/web/space/audio/voice/male/ms_50.ogg differ diff --git a/web/space/audio/voice/male/new_record.ogg b/web/space/audio/voice/male/new_record.ogg index cf4b7ded..9f6b5c4e 100644 Binary files a/web/space/audio/voice/male/new_record.ogg and b/web/space/audio/voice/male/new_record.ogg differ diff --git a/web/space/audio/voice/male/paused.ogg b/web/space/audio/voice/male/paused.ogg index 7e00000c..458eb57b 100644 Binary files a/web/space/audio/voice/male/paused.ogg and b/web/space/audio/voice/male/paused.ogg differ diff --git a/web/space/audio/voice/male/protect_down.ogg b/web/space/audio/voice/male/protect_down.ogg index 5d07eed0..8f5ef0ae 100644 Binary files a/web/space/audio/voice/male/protect_down.ogg and b/web/space/audio/voice/male/protect_down.ogg differ diff --git a/web/space/audio/voice/male/protect_end.ogg b/web/space/audio/voice/male/protect_end.ogg index 37ce4d49..57c35c01 100644 Binary files a/web/space/audio/voice/male/protect_end.ogg and b/web/space/audio/voice/male/protect_end.ogg differ diff --git a/web/space/audio/voice/male/protect_left.ogg b/web/space/audio/voice/male/protect_left.ogg index bdda8cdd..edef54fd 100644 Binary files a/web/space/audio/voice/male/protect_left.ogg and b/web/space/audio/voice/male/protect_left.ogg differ diff --git a/web/space/audio/voice/male/protect_right.ogg b/web/space/audio/voice/male/protect_right.ogg index c1903a7d..55f2f3b1 100644 Binary files a/web/space/audio/voice/male/protect_right.ogg and b/web/space/audio/voice/male/protect_right.ogg differ diff --git a/web/space/audio/voice/male/protect_up.ogg b/web/space/audio/voice/male/protect_up.ogg index 9ba3eb76..125f71c8 100644 Binary files a/web/space/audio/voice/male/protect_up.ogg and b/web/space/audio/voice/male/protect_up.ogg differ diff --git a/web/space/audio/voice/male/restart_hint.ogg b/web/space/audio/voice/male/restart_hint.ogg index 84fcaf66..e793eb6b 100644 Binary files a/web/space/audio/voice/male/restart_hint.ogg and b/web/space/audio/voice/male/restart_hint.ogg differ diff --git a/web/space/audio/voice/male/second_run_ask.ogg b/web/space/audio/voice/male/second_run_ask.ogg index 6a0cdd62..34a6717b 100644 Binary files a/web/space/audio/voice/male/second_run_ask.ogg and b/web/space/audio/voice/male/second_run_ask.ogg differ diff --git a/web/space/audio/voice/male/settings_hint.ogg b/web/space/audio/voice/male/settings_hint.ogg index 14e209bc..4c30cb0f 100644 Binary files a/web/space/audio/voice/male/settings_hint.ogg and b/web/space/audio/voice/male/settings_hint.ogg differ diff --git a/web/space/audio/voice/male/shield_block.ogg b/web/space/audio/voice/male/shield_block.ogg index fb44e807..7bd8f5a5 100644 Binary files a/web/space/audio/voice/male/shield_block.ogg and b/web/space/audio/voice/male/shield_block.ogg differ diff --git a/web/space/audio/voice/male/shield_ready.ogg b/web/space/audio/voice/male/shield_ready.ogg index 949b82bf..38cb2ac6 100644 Binary files a/web/space/audio/voice/male/shield_ready.ogg and b/web/space/audio/voice/male/shield_ready.ogg differ diff --git a/web/space/audio/voice/male/skip_hint.ogg b/web/space/audio/voice/male/skip_hint.ogg index 57c6a401..2e2bbff4 100644 Binary files a/web/space/audio/voice/male/skip_hint.ogg and b/web/space/audio/voice/male/skip_hint.ogg differ diff --git a/web/space/audio/voice/male/time_1.ogg b/web/space/audio/voice/male/time_1.ogg index 53bbf3a3..6a43f5f9 100644 Binary files a/web/space/audio/voice/male/time_1.ogg and b/web/space/audio/voice/male/time_1.ogg differ diff --git a/web/space/audio/voice/male/time_2.ogg b/web/space/audio/voice/male/time_2.ogg index 7e0b88be..87e68127 100644 Binary files a/web/space/audio/voice/male/time_2.ogg and b/web/space/audio/voice/male/time_2.ogg differ diff --git a/web/space/audio/voice/male/time_3.ogg b/web/space/audio/voice/male/time_3.ogg index 11c26009..8bb18247 100644 Binary files a/web/space/audio/voice/male/time_3.ogg and b/web/space/audio/voice/male/time_3.ogg differ diff --git a/web/space/audio/voice/male/time_4.ogg b/web/space/audio/voice/male/time_4.ogg index b47e5fc0..9f17ab54 100644 Binary files a/web/space/audio/voice/male/time_4.ogg and b/web/space/audio/voice/male/time_4.ogg differ diff --git a/web/space/game.js b/web/space/game.js index 22888167..6bbd2060 100644 --- a/web/space/game.js +++ b/web/space/game.js @@ -31,11 +31,12 @@ * 语音 id 权威清单:docs/design/04-space-voice-ids.md(52 句双性别); * 旧 num 拼接件、n_ 前缀件、intro1-4/hit1/hit2/gameover/restart 全部弃用。 * - * 向导层(docs/design/14-guide-layer.md + round2 synthesis F2.2/F6):对局第 1 次 - * 受击(保护期外)在归因链播完后补指令式 gd_hit_hint、第 2 次补 gd_last_life - * (idle-only:挂在语音空闲点);警报音效 600ms 去重、danger 震 ≥400ms 去抖; - * 结算链换 _speakGuarded(资产缺失不卡结算 BGM);对局期长按快进豁免 - * (setRateBoostEnabled);状态签名 earcon 与状态 BGM 同点。 + * 向导层(docs/design/14-guide-layer.md + round2 synthesis F2.2/F6 + round3 G7): + * 对局第 1 次受击(保护期外)在归因链播完后补指令式 gd_hit_hint、第 2 次补 + * gd_last_life(idle-only:挂在语音空闲点);警报音效 600ms 去重、danger 震 + * ≥400ms 去抖;loud 警报档(撞击前 500ms)同窗播 dir_ 超短方向呼喊 + * (voice 层直达、全档位,G7);结算链换 _speakGuarded(资产缺失不卡结算 BGM); + * 对局期长按快进豁免(setRateBoostEnabled);状态签名 earcon 与状态 BGM 同点。 */ import { Game } from '../engine/game.js'; import { Guide } from '../engine/guide.js'; @@ -461,7 +462,15 @@ export class SpaceGame extends Game { if (this.obstacles.has(ob)) this._alarm(0.5); }); this._after(impactAt - ALARM_LEAD_MS / 2 - now, () => { - if (this.obstacles.has(ob)) this._alarm(1); + if (this.obstacles.has(ob)) { + this._alarm(1); + // G7(round3):loud 档(撞击前 500ms)同窗超短方向呼喊 dir_——与 + // 警报分属 voice/sfx 两通道,天然同时不互顶(引擎 duck 压 BGM 保证可闻), + // 噪音环境下方位不再只装在呼啸单通道(P3 round2 P0)。游戏反馈层全档位 + // (gd_economy 先例);直达式播放不排队——呼喊必须赶在撞击前,宁可顶掉 + // 里程/充能类短句,也不排到链尾迟到。 + this.audio.play(`voice/dir_${ob.dir}`); + } }); this._after(impactAt - now, () => this._resolve(ob)); }