Files
SoundGame/docs/design/04-space-rebuild.md
T
xsl ddada6980c fix(space): 盲航刺耳音效重制 + 状态/反馈盲区修复(玩家代理取证迭代)
- F1 程序合成重制5件刺耳音效(alarm≥3kHz能量82%→0,全件≤-3.4dBFS)+新增挥空音
- F2 P0:撞击方位语音防顶断补播(保护期结束死亡窗 hit_* 零毫秒被杀根因)
- F3 保护期教学句7连互截去重;F4 新句 protect_soon 50s预告;F5 boost_not_ready 冷却拒绝回音;F6 激活补CONFIRM震;F7 whiff
- 验证:playtest 172/172 + guide 122 + 终检全绿 + 14游戏回归零回退 + live两轮复跑坐实
- 档案 research/space-polish/round1-2(取证+修复证据);04号文档追加R5修订记录
2026-09-14 20:16:58 +08:00

12 KiB
Raw Blame History

04 · 《盲航》重构方案(space rebuild)

给开发者的实现要点摘要

  1. 47 秒连续旁白教学(intro1-4 链播)改为交互式演练:每次只教一件事,玩家立刻实操一颗慢速陨石,做错不惩罚、当场重教。四个方向各练一次,单击/双击在开局后第 20s / 45s 分批引入。
  2. 闪避方向改为同向:听到左边的呼啸就向左滑——"把陨石拨开"。反向映射(现版左来右滑)是"没搞懂就死了"的最大认知负担,同向映射让方位声直接映射到同侧手势。
  3. 前 60 秒保护期:陨石慢(逼近 4s)、稀(间隔 4s)、撞了不掉血(训练护盾吸收,语音解释)。60s 后语音宣告"保护解除",难度曲线从现版起点再降一档重新爬坡。
  4. 死亡即教学:每次被撞,语音说清陨石从哪来、该怎么做;坠毁结算播报分因果。
  5. 数字拼接全部改整句:里程碑 5 句固定整句,存活时间分 4 段整句。撞击/护盾等反馈改震动。

1. 现版诊断:"没搞懂就死了"

读 web/space/game.js:

  1. 教学是 4 句连播旁白(voice/intro1..4, game.js:84-87),约 47 秒。玩家零操作听完,然后第一颗陨石 1.2 秒后就来(_scheduleSpawn(1200), game.js:111)。方位声→反向手势的映射只在旁白里说过一遍,没有任何一次实操验证。
  2. 反向闪避违反直觉(ESCAPE_SWIPE = {left:'right',...}, game.js:26)。声音从左边来,手却要往右滑——玩家在前几秒的生存窗口里要完成"定位→取反→出手"三步推理,取反这一步是死亡率主因。
  3. 三个机制同时压上来:闪避、单击加速、双击护盾,47 秒旁白里全部讲完,开局全部可用。玩家还没分清 whoosh 的方位,护盾冷却的播报已经来了。
  4. 难度起点过高:首颗逼近时长 2.8s、刷怪间隔 3.2s(game.js:42-44),对没建立映射的新手等于即死。
  5. 撞击无教学价值:voice/hit1/hit2 只报损,不说陨石从哪来、该怎么躲。玩家死了都不知道为什么。

2. 核心决策:同向闪避

听到哪边来,就向哪边滑(PUSH_SWIPE = {left:'left', right:'right', up:'up', down:'down'}),叙事包装为"挥手把陨石拨开/推引擎避开"。

  • 方位声(左声道)→ 同侧手势(左滑):零推理,反射直达,这是盲玩能成立的前提。
  • 上=高频呼啸→上滑,下=低频轰隆→下滑,保留现有 sfx 方位设计(whoosh_* 四个资产全部复用,只改映射表和文案)。
  • 判定窗口沿用现版结构(撞击前 1.5s 内滑动有效 + 250ms 宽限),仅 need 从 ESCAPE_SWIPE[dir] 改为 dir 本身。
  • 单击加速、双击护盾机制保留(现版"持续增益规避 tap 延迟"的设计是对的,game.js:146-153 注释写得很清楚),只是引入时机后移(§3.3)。

3. 新开场:交互式演练(DRILL 阶段)

3.1 演练流程

每步 = 一句短旁白 → 一颗演练陨石(逼近 4.5s,撞了不掉血)→ 玩家操作 → 反馈。做错/超时:ERROR 震动 + 一句纠正 + 同一颗重来,最多重教 2 次后自动演示通过(不卡流程)。

步 旁白(整句,≤20字/句) 演练内容
D0 "欢迎登上盲航。你只有一双耳朵。" + "陨石来了,会有声音告诉你方位。" 无陨石,建立预期
D1 "听,左边有陨石。向左滑,把它拨开!" 左来,需左滑
D2 "这次在右边。" 右来,需右滑
D3 "上面有东西,声音又尖又高。向上滑!" 上来,需上滑
D4 "下面是低频的轰隆。向下滑!" 下来,需下滑
D5 "四个方向你都会了。引擎点火,出发!" 进保护期
  • 每次成功拨开:dodge 音 + SWIPE_OK 震动 + 短肯定("漂亮。"仅 D1/D3 播,避免啰嗦)。
  • 每步旁白在演练陨石的 whoosh 响起之前播完(语音先、音效后,不叠放),whoosh 响起时玩家已知该做什么。
  • 教学期间下滑=跳过演练(二周目直接问"上滑重听演练,单击出发")。

3.2 前 60 秒保护期

演练结束进入 playing 后启动保护期(protectionUntil = runStart + 60s):

参数 保护期 保护期后
逼近时长 4.0s(恒定) 3.2s → 2.0s 爬坡(比现版 2.8→1.8 各抬 0.4s)
刷怪间隔 4.0s(恒定) 3.2s → 1.4s 爬坡
撞击 不掉血:训练护盾吸收,播 shield_block 音 + WARNING 震动 + 语音解释("护盾接住了。那颗在左边,听到左声道的呼啸就向左滑。"按实际方位选句) 正常掉血
单击/双击 第 20s / 45s 才解锁(见 §3.3) 可用

第 60s 播:"训练护盾关闭,接下来靠你自己了。" + WARNING 震动。之后难度从低档开始 120s 爬满(沿用 RAMP_MS=120s)。

3.3 单击/双击分批引入

  • 第 20 秒(保护期内):暂停刷怪 6 秒,旁白:"试试单击,引擎会短促加速,直接冲过空隙。" → 玩家单击 → boost 音 + CONFIRM 震动 + "感觉到了吗?加速期间撞不上你。" → 恢复刷怪。
  • 第 45 秒:同样暂停 6 秒:"双击展开护盾,能挡一次撞击,用完要 30 秒充能。" → 玩家双击 → shield 音 + CONFIRM 震动 → 恢复。
  • 若玩家 8 秒内没做,不等待直接继续(机制仍在,之后用上也正常生效)。
  • 护盾充能完毕语音(voice/shield_ready)保留。

4. 死亡即教学 + 结算

4.1 撞击反馈(保护期后)

每次被撞:sfx/hit + HIT 震动 + 一句归因语音(按方位 4 句预生成:"左边撞上的。听到左声道呼啸,向左滑。"),替换现版 voice/hit1/hit2 的纯报损。第二次被撞额外加半句船体状态:"船体只剩最后一次了。"

4.2 坠毁结算(整句化)

删除 numClips 拼接体系(voice/num*/n_time/n_sec/n_dodge/n_ge, game.js:47-65):

  • 存活时间 4 段整句:"不到三十秒,再试一次。""超过三十秒,有进步。""超过一分钟,合格的飞行员。""超过两分钟,王牌飞行员。"
  • 躲避数 4 段整句(合并进上句的第二句):"只拨开几颗。""拨开了十来颗。""拨开了几十颗。""拨开了一大群,漂亮。"
  • 每局结算 = 时间段整句 + 躲避段整句 + "单击再飞一次,下滑回大厅。"
  • 里程碑播报:dodges % 10 的数字拼接改为 5 句固定整句(10/20/30/40/50 颗各一句:"十颗了,稳。"…"五十颗,传奇。"),超出 50 不再播报。

4.3 最高分

存活时间最高纪录存进度(data = { bestSec: n, totalRuns: n }),结算时若破纪录加一句"新纪录!"(SUCCESS 震动)。

5. 震动映射(对齐 00 文档)

事件 震动
成功闪避 SWIPE_OK(dodge 音保留)
警报渐强(撞击前 1s / 0.5s 两段) DANGER 渐强脉冲(随 alarm 两档,第二档更密)
撞击 HIT
护盾挡下 CONFIRM
加速/护盾激活 CONFIRM
坠毁 ERROR + HIT(间隔 300ms)
演练做对 SWIPE_OK;演练做错 ERROR

现版 sfx/alarm 两档警报音保留(它是方位+距离的内容信息,不是反馈提示音),震动 DANGER 与其同步叠加。

6. 实现要点(给开发 agent)

  1. ESCAPE_SWIPE 改同向映射(一行改动),DODGE_WINDOW_MS/DODGE_GRACE_MS 判定结构不动。
  2. 新增 phase='drill':复用 _spawnObstacle 但参数化(approachMs/spawnInterval/harmless 标志),演练陨石带 harmless: true 与指定 dir。
  3. _resolve() 增加保护期分支:now < protectionUntil 时撞击走"训练护盾"路径(不掉血、播归因语音)。
  4. 暂停刷怪:_clearTimers() 后重排 _scheduleSpawn(现版已有清晰的 timer 管理,game.js:250-261)。
  5. 归因语音按方位选句:voice/hit_left/hit_right/hit_up/hit_down + voice/hit_last。
  6. 语音全部整句重录:演练 8 句、保护期 3 句、单击/双击引入 4 句、归因 5 句、结算 10 句(时间段 4 + 躲避段 4 + 新纪录 + 重开)、里程碑 5 句 ≈ 35 句 × 2 音色。删除全部 num 拼接件。
  7. 教学语音与 whoosh 的时序:语音 onComplete 后再 spawn 演练陨石,保证不叠放。
  8. 更新 web/space/README.md 手势表(同向闪避是玩家可见的最大变化,README 必须同步)。

修订记录 R5(space polish:刺耳 + 状态/动作反馈盲区,research/space-polish/)

取证(round1):live 两会话(research/space-polish/round1/live-{A,B}-transcript.md)+ 4 人设评审(同目录 p1-blind/p2-student/p3-office/p4-worker)+ 全 sfx 客观频谱 (同目录 sfx-spectrum-analysis.txt)。核心事实:

  1. 刺耳(客观):alarm 每颗陨石响两遍且 ≥3kHz 能量 82.3%/≥5kHz 63.9%/峰值 16kHz; dodge 真峰值 -2.30dBFS + 63.6%≥3kHz;shield_block -2.60+52.2%;boost -2.70+53.0%; shield -2.90 超标。四件最高暴露音效全部违反 one-shot 标准(≤-3dBFS)。
  2. 保护期结束死亡窗(P0,live A t+151-163 与 t+300-310 两轮复现):裸飞期逼近 4.0s = 刷怪 4.0s,每颗撞击与下一颗 spawn 同窗——呼喊维持生存优先(顶断归因)的代价是 hit_left/hit_down 零毫秒被杀,玩家 8 秒三连撞至死不知方位;protect_end 亦被顶得 只剩 0.5-3.5s。
  3. 保护期 protect_ 七连截断*:6.96s 教学句对 4.0s 刷怪间隔,每句播 4.0s 就被 下一句顶断(live A 7 连 TRUNCATED),信息重复又残缺。
  4. 动作反馈盲区:加速冷却中单击全静默(护盾拒绝有回音、加速没有——归因真话不均); 挥空/滑错方向与成功闪避同静默(dodge 音只在判定时才响);boost/shield 激活无 CONFIRM 震(§5 承诺未兑现)。

R5 裁定与实现(逐条对应 playtest.mjs 新断言):

  • R5-1 刺耳重合成:alarm/dodge/shield_block/boost/shield 五件程序合成重制 (tools/gen_space_syn.py,低谐波设计:alarm 双音 700/560Hz、dodge 中频气声扫频, 真峰值 ≤-3.4dBFS、编码后 ≥3kHz 能量 0%,解码回读校验)。SA3 非必需,程序合成达标。 新增 sfx/whiff(挥空轻叹,0.55 音量)。
  • R5-2 归因真话·防顶断 replay:呼喊生存优先裁定不变(呼喊照常同窗直出、照常 顶断归因);但 hit_/protect_end 起播经 _defendVoice 登记,被顶断时登记残留, 呼喊播完的 onComplete 走 _replayDefended queue 接 replay(不顶新威胁信息), 保证每句归因/保护结束宣告完整送达至少一次;归因 replay 播完仍接 hit_last(先因后果)。
  • R5-3 protect_ 去重*:上一句 protect_ 在播时新吸收只发 shield_block 音 + WARNING 震、跳过语音,每句教学完整播完(不再 7 连截断同一句开头)。
  • R5-4 加速冷却拒绝:_deny(now, voiceId) 共用 4s 去抖(护盾拒绝同路径、原句 feat_shield_done 不变);加速冷却单击 → HEARTBEAT 震 + 新句 boost_not_ready 「引擎还在冷却,稍等一下。」。
  • R5-5 protect_soon:开局第 50s 播报「训练护盾还剩十秒。」(queue 不顶句; 菜单/分批引入打断由 _rearmRunTimers 补播),给反应慢的玩家 10s 提前量。
  • R5-6 激活确认:boost/shield 激活(对局期与 feature 期)补 CONFIRM 震(兑现 §5)。
  • R5-7 挥空反馈:playing 期滑向无悬置陨石的方向 → sfx/whiff 轻叹(引擎 swipe 震动已有"收到",whiff 补"无用"),与 dodge 成功音形成对偶。
  • 状态查询手势:维持 00 §5 豁免表裁定(四向滑=闪避,space 无对局期 status key; 坠毁结算后上滑=重听教学要点)。状态透明全部由事件反馈句承担(本 R5 已补齐 保护期倒计时/冷却拒绝/归因可达性),不新增手势。