校准把不属于你的延迟先减掉
第 2 章量到的那个「偏移」,其实是好几样东西加在一起的:音频从算出来到抵达喇叭要走一段路,画面要刷新,而你的身体本来就习惯提前一点出发。
这几样里,只有最后一样是你的。其余的都是常数,而常数可以被减掉 —— 一次减掉,永久生效,一秒都不用练。
这一章会把浏览器自己承认的延迟读给你看,量出你的常数,再验证一遍减掉之后的效果。这是全书投入产出比最高的十分钟。
那个偏移是好几样东西加起来的
你按下按键的那一刻,和你听到声音的那一刻,中间隔着一条不短的链路。把它摊开:
从「游戏决定发声」到「你听见」
1. 音频引擎把这一段样本算出来 几毫秒
2. 样本进入输出缓冲区 取决于缓冲大小
3. 声卡 / DAC 把它变成模拟信号 几毫秒
4. 传到你的耳朵 几乎瞬时(有线)
从「你决定要动」到「游戏收到输入」
5. 神经传导 + 肌肉收缩 几十毫秒(这是你的)
6. 按键行程 + 扫描 几毫秒
7. 游戏在下一帧才读到这个输入 最多 16.7ms
这七项里,只有第 5 项是「你」。其余六项全是设备和软件的常数,跟你练得多好一点关系都没有。
而第 2 章那个偏移,量到的是这七项的总和。所以当你看到「我偏早 40ms」的时候,很可能其中一半以上根本不是你的习惯,是链路。
这就是校准这件事的全部意义:把链路那部分挪回原点,让剩下的那部分(你的习惯)成为唯一的变量。
它不会让你的手变稳 —— 抖动一点都不会变,第 3 章那个积分里,校准只动了中心,没动宽度。
但它会把你分布的中心搬回窗口正中间,于是分布的两条尾巴同时缩回来。这是免费的。
一个类比:这跟给秤去皮是一回事
如果上面那张链路表看着有点抽象,换个说法。
你在厨房用电子秤称面粉,先放一个碗上去,秤显示 240 克。这 240 克是碗的,不是面粉的。你不会因为「我称出来 240 克」就以为自己倒了 240 克面粉 —— 你会按一下「去皮」,让它归零,然后再倒。
校准就是按那个「去皮」键。链路的延迟是碗的重量:它一直在那里,稳定、可测、跟你要称的东西无关。没去皮之前,你测到的每一个数都掺着它。
这个类比还能说明另外两件事:
- 换个碗就要重新去皮 —— 这就是「换设备要重校」。
- 去皮不会让你倒得更准 —— 秤的精度(对应你的抖动)跟去不去皮毫无关系。
先读一读机器自己承认的部分
有意思的是,你不需要猜链路里的第 1–3 项 —— 浏览器自己会报。
Web Audio 这套接口提供两个数:baseLatency 是音频图处理本身引入的,outputLatency 是从「你安排一个声音」到「它真的从喇叭出来」的全程估计。下面这台机器会把它们读出来,还有一个更重要的东西 —— 量你自己的那个常数。
1. 点「读设备」,看这台机器承认多少延迟。
2. 点「量我的偏移」,跟着敲 24 拍。按你平时的手感来,不要刻意修正 —— 一修正就量不到那个常数了。
3. 点「带校准值再量一次」,验证效果。注意看抖动那个数:它应该几乎不变。如果它变了,说明你在第二步刻意修正了。
一个工程细节:两个时钟必须先对齐
这台 demo 里藏着一个不做就全错的步骤,值得单独说,因为它也是所有音游、所有节拍器应用都必须处理的事。
声音由音频硬件的时钟播出,而你的鼠标和键盘事件盖的是另一个时钟的时间戳。这两个时钟原点不同,走速也不完全一致。如果直接拿事件的时间戳去减「我以为声音响的时刻」,量到的就不是你的手,而是两个时钟之间那个毫无意义的差值。
// 错的:用墙上时钟去量音频事件
const err = Date.now() - expectedBeatWallTime; // 掺进了调度抖动
// 对的:把事件戳换算到音频时钟轴上,再比
function eventTime(ev) {
// syncOffset = performance.now() − ctx.currentTime * 1000,取一次存起来
return (ev.timeStamp - syncOffset) / 1000; // 单位:音频时钟的秒
}
const err = eventTime(ev) - scheduledAudioTime;
还有一层:判定要不要减掉 outputLatency,取决于你想量什么。如果你想量「用户对听到的声音反应得多准」,就该减 —— 因为声音真正到达耳朵的时刻,比你安排它的时刻要晚。本书的引擎把这个换算和这个选择都写在一个地方(clock.js 的 eventTime 与 latency),这样每个 demo 都不会各写各的。
还有一个更常见的错误:用 setInterval 直接触发发声。
定时器的抖动是几十毫秒量级的 —— 也就是说,节拍器自己就在晃,晃得比你的手还厉害。你量到的抖动里,有一大半是它的。
正确做法是「前瞻调度」:定时器只负责往前看一小段,把这段里该响的音符提前排进音频时钟,真正的发声时刻精确到采样点。本书所有会出声的 demo 都走这条路径 —— 否则这本书里所有的测量都不成立。
校准值怎么用到游戏里
量出来的偏移是负的(你偏早),校准值就是它的相反数。具体到操作:
| 你量到的 | 含义 | 该往哪调 |
|---|---|---|
| 负数,比如 −35ms | 你总是抢在前面 | 把判定时刻提前,或把你的输入视为延后 35ms |
| 正数,比如 +28ms | 你总是拖在后面 | 反方向,28ms |
| 绝对值小于两倍误差棒 | 在噪声之内 | 什么都别调 |
各家游戏对这个设置项的正负号定义不一样,有的叫「判定偏移」,有的叫「音频延迟」,方向还可能相反。所以不要背符号,改完之后回到游戏里试一遍 —— 如果评价变差了,就是符号反了,取个负号再来。
如果你玩的这一作压根没有偏移设置项,这一章依然有用,只是用法变了:
你要把校准值装进自己的身体,而不是装进设置菜单。知道自己「习惯早 35ms」之后,做法不是每次刻意去数「晚一点点」—— 那会把它变成一个需要临场判断的零件,反而更不稳。
正确的做法是:在这本书的 demo 里,用带反馈的方式练几十下。每一下都告诉你早了多少,几十下之后你的身体会自己把中心挪过去,而且是无意识地挪。这比在游戏里瞎调有效得多,因为游戏不告诉你毫秒。
还有一件事:这个系列有一类小游戏是用手写节奏或者需要长按的,它们的输入判定和普通点击未必一样。那类关卡值得单独重新校准一次。
这个方法分不开的两样东西 —— 以及为什么没关系
诚实地说一句:上面这套办法量到的是一个总和,它没办法告诉你其中多少来自设备、多少来自你的身体。
要真的分开,你得在这台机器之外再架一套测量(比如用麦克风录下「声音」和「按键的咔哒声」,看它们的波形差多少)。那属于另一件事,这本书不做。
而幸运的是,你根本不需要分开。因为这两部分在使用上是完全等价的:它们都是常数,都会被同一个校准值一并减掉。你要减的是那个总和,不是它的成分表。
只有一种情况下你会需要分开:当你想把校准值从一台设备搬到另一台的时候。那时候设备那部分变了,你那部分没变,所以整个值不能直接搬。这也正是「换设备要重校」这条规矩的来源 —— 与其分开量,不如换了就重来一次,反正只要十分钟。
你的那一部分,为什么天生是提前的
链路的那几项好理解。但为什么你的那一部分也常常是提前的?
第 1 章的 demo 多半已经让你看到了这个现象:跟着稳定节拍敲的时候,人的偏移往往是负的。这不是失误,是预判系统在正常工作 —— 你的运动系统不是在「等拍」,它是在「赶拍」,而它宁可赶早一点点,也不愿意赶晚。
为什么宁可早?一个直观的解释是:晚是不可挽回的,早还有余地。如果你的目标是「让动作落在那个点上」,那么提前出发、留一点余量,比卡着点出发要稳健得多 —— 后者只要有任何一点意外,就必然迟到。
这个提前量还有个有趣的性质:它会随速度变化。慢的时候提前得更多,快的时候提前得少。第 17 章会用一个 demo 让你在四个速度上各量一遍,把这条曲线画出来。
这就带来了一个实际的麻烦:如果你只在一个速度上校准过,换到差很多的速度就又偏了。所以第 17 章会给一个更实用的建议 —— 在你最常玩的那个速度区间上校准,而不是在最舒服的那个速度上。
校准之后,你会先变差一阵子
最后一个必须提醒的坑,因为很多人会在这里放弃。
改完校准值之后,你有很大概率会觉得手感变差了。这不是你调错了方向,而是一个几乎必然发生的过渡期。
原因很简单:在你不知道自己偏早 35ms 的那些日子里,你的身体已经悄悄适应了这个偏差 —— 它一直在用「感觉早了一点才对」的方式打,而游戏也一直按这个偏差给你反馈。现在你把那 35ms 从系统里拿掉,你的身体还在按老习惯补偿,于是它反而偏到另一边去了。
校准之后的三个阶段
第 1 天 感觉更别扭。你的身体还在补偿一个已经不存在的偏差。
第 2-3 天 补偿开始消退。命中率回到校准前的水平。
之后 补偿完全消失。这时候你才拿到那几个百分点。
所以:校准之后不要立刻根据手感再去改一次。那是这一章最容易毁掉的一步 —— 你会在第 1 天把它改回去,然后永远拿不到那个收益。
正确的做法是:改一次,用三天,第四天再用这本书的 demo 复测一次。如果那时候偏移接近零,说明成了;如果还偏,再调剩下的那部分。
什么时候需要重校,什么时候不需要
校准的价值在于「一次搞定」。如果你每天都在调,那说明你在追噪声(第 2 章那张误差棒的表已经说明了原因)。
需要重校的场合只有四种:
- 换设备:换了耳机、换了主机、换了显示器。链路变了。
- 换显示模式:掌机 ↔ 电视、电视的画质模式变了。链路又变了。
- 换了差很多的速度:第 17 章会量给你看,人的提前量会随速度变化 —— 在 60 BPM 校准好的值,搬到 160 BPM 未必还对。
- 换了输入方式:从按键换成触屏、从点击换成长按。
不需要重校的场合:今天手感不好、这一关老是过不去、连续两天量到的值差了 5ms。这些都是噪声,或者是别的病(抖动、走位、认错格),改校准值一点用都没有。
这是这一章最重要的一句话,也是最容易被忽略的一句。
demo 的第三步会把它演示给你看:把校准值套上去之后,命中率涨了,抖动那个数一点没动。
所以如果你的问题主要是抖动(第 2 章量到的那个数很大),校准能给你的收益是有限的,而且很快就到顶。那时候就该合上这一章,去卷 II。
反过来,如果你的抖动已经很小、偏移却很大 —— 那你是这本书里最幸运的那种读者:你今天就能变强,而且不用练。
1. 用有线设备。(无线的延迟量级比你要测的东西还大。)
2. 电视切到游戏模式;能用掌机模式就用掌机模式。
3. 上面那台 demo,量 24 拍以上,记下偏移和它的误差棒。
4. 偏移绝对值 > 两倍误差棒 → 去游戏设置里调;调完试一关,变差了就取反。
5. 把这个值和「在什么设备、什么模式、什么速度下量的」一起记下来。
6. 然后忘掉它,去练抖动。
卷 I 收尾
到这里,诊断这一卷结束了。你手上应该有这些东西:
- 你的反应时和预判误差,以及它们之间那个倍数(第 1 章);
- 你的三个数:偏移、抖动、走位,还有「敲到隔壁格」的次数(第 2 章);
- 这三个数能换算成多少命中率和连击长度(第 3 章);
- 你在用耳朵还是用眼睛打(第 4 章);
- 一个已经减掉了链路延迟的校准值(第 5 章)。
其中前四项是知识,最后一项是已经到手的收益。剩下二十章要做的,是把「抖动」这个数往下压,把「走位」和「认错格」这两件事消灭掉。
下一卷从最底层开始:拍。那个必须由你自己发出来、音乐停了也不能停的东西。
而卷 II 的第一句话,会把这一卷的逻辑推到底:如果说校准是把「不属于你的部分」减掉,那么拍就是把「本来就该属于你的部分」拿回来。音乐并不负责给你拍 —— 音乐只是提供线索,那个网格从头到尾都是你自己架起来的。第 7 章有一个专门的自测,会在音乐消失的时候,把这句话变成一个你能看见的数字。
本章只治一种:偏移。而且是彻底治好、不会复发的那种 —— 只要你别去动它。
带走一句话:校准挪的是分布的中心,不是宽度。它一秒都不能帮你练稳,但它免费。