前两篇解决了"连得上"和"谁说了算",还剩最后一关,也是最影响体验的一关:等。如果每一次开火都要等子弹"飞"到房主、结算完再飞回来显示结果,半秒的延迟足够把空战手感毁得干干净净——你明明瞄得很准,画面却像在水下开枪。《苍穹对决》采用与 CS、守望先锋同一思想的方案:本地预判 + 权威回溯——先给结果,再对账,错了就悄悄改回来。
一、问题:半秒延迟毁掉所有手感
设想最"守规矩"的做法:扣扳机 → 上报房主 → 房主判定命中 → 快照回传 → 本地显示命中特效。这条链路要跑完一个完整的网络往返(RTT)。50ms 的 RTT 也许还行;可一旦对方在另一个城市,100~300ms 的延迟下,从开火到看见命中要等四分之一个秒——空战里足够让敌机飞出半个屏幕。核心矛盾在于:正确性要求等权威,手感要求零等待。两者表面不可兼得,破局思路是——不等,先给。
二、预判:先给爽快感
实时性最强的伤害与碰撞,你的浏览器本地先行结算:子弹命中瞬间立刻扣血、立刻出命中特效、立刻播打击音效,零等待。与此同时,这次命中会上报房主待裁定。也就是说,你看到的血条变化其实是"预判值"——本地基于自己看到的世界做出的最合理猜测。
猜就要记账。《苍穹对决》为每个实体维护两个数:predTotal(尚未被权威确认的预判伤害量)和 lastAuth(最近一次权威快照里的血量)。预判与权威两条账本分开记,随时可以合并、随时可以拆开重算。这是整套机制能"错了改回来"而不出乱子的关键。
为什么不直接改血条、记一个"预计血量"了事?因为一次预判的"有效期"横跨好几个快照周期:你连开三炮,第一发的裁决还没回来,第二发、第三发的预判已经叠上去了。如果只有一锅粥式的总血量,任何一次回溯都会把"还没裁决的伤害"一并冲掉;分成两本账后,回溯只动 predTotal 里对应的那一笔,权威部分岿然不动。能不能优雅地撤销,取决于一开始有没有把账记对。
三、对账:权威说了算
房主的 sync 快照到达时,本地并不粗暴覆盖血条,而是做一次合并:显示血量 = 权威血量 − 未确认预判量。你打中的那几发如果房主也判定命中,预判量会随快照逐步"转正",血条纹丝不动——你完全感觉不到对账的发生。
如果房主裁定你其实没打中(子弹提前坠海、被掩体挡住、目标恰好规避),会立即下发 dmgReject 回溯消息,本地把预判扣掉的血如数补回。整个过程在一次网络往返内完成,玩家的感受只是"这次好像没打实了"——而这本来就是事实。
一个自然的担心是:血条加回去,会不会看起来很假?实践中几乎不会。原因是回溯的窗口极短(通常一两百毫秒)且幅度很小(一两发机炮的伤害),而玩家的注意力正集中在缠斗本身——这个量级的视觉修正会被大脑自然归类为"目标擦过去了"。真正让人出戏的从来不是小幅修正,而是长时间的对不上账:血条明明掉了却不死,或者命中特效出来了却没伤害。预判 + 回溯恰恰消灭的是后者。
四、被打的一方:快照直接覆盖
打人是预判,挨打却是另一套逻辑。你被打掉血时,本地不做任何"预判抵抗"——你的血条由房主快照直接覆盖。原因很实际:挨打方自己根本不知道对方是否真的命中(子弹从背后飞来,你无从判定),做预测只会制造矛盾。权威快照说你剩多少血,你就剩多少血,方向、伤害全部以快照为准,无需任何回滚消息。
五、哪些事情坚决不预判?
死亡。击杀是比赛最敏感的裁定:本地预测死亡极易出现"我明明打死了他,他却还在飞"的争议画面——两边各执一词,谁都不服。所以死亡一律等房主权威宣判,本地只负责演出。唯一的例外是撞海、撞地这类确定性环境坠毁:物理规律在本地同样可算,预判结果绝不会与权威矛盾,做了也不撕账。
这条边界线背后是一个普适原则:预判的前提是"可复现"。确定性物理(撞地、撞海)在两台设备上算出同一个结果,预判就永远安全;涉及对手意图与权威裁定的结果(被击落),本地没有任何信息优势,预判就是赌博。划分"哪些可以猜、哪些必须等",比预判算法本身更考验设计功力。
六、延迟补偿:专治"幽灵弹"
预判解决了"我的操作反馈慢",还有个对称问题:"别人的状态到我这里也是旧的"。高延迟玩家上报的状态可能严重过期——他开枪时瞄的是几百毫秒前的残影。如果房主照单全收,就会出现"对着早已飞走的影子却被判命中"的幽灵弹。《苍穹对决》的对策是在房主侧做新鲜度检查:
- 飞机状态过期超过 350ms 的开火,跳过命中判定;
- 防空车状态过期超过 400ms 的开火,同样跳过。
配合 firePred 对账表——每条本地预判开火记录在表,收到房主裁决后销账,5 秒未裁决自动过期清理——预判与权威的账永远对得清清楚楚,不会越滚越多。
细心的人会问:为什么飞机 350ms、防空车 400ms,阈值不一样?因为防空车是固定地面单位,它的"状态过期"只影响炮塔指向,不影响位置判定——晚一点的状态依然大体可信;而飞机高速机动,350ms 足以飞出好几个机身位,过期状态的"可信半径"小得多。阈值的宽严,本质上是在为不同目标的机动性定价。
结语:手感的本质
这套组合拳的效果可以总结成一句话:操作反馈永远零延迟,权威结果永远正确,两者的短暂不一致会在几百毫秒内静默修复。玩家不需要理解 predTotal、dmgReject 这些名词——他只需要觉得,这游戏跟单机一样跟手。而这正是"市售网游级网络同步"的全部含义:不是没有延迟,而是让延迟隐形。