延迟补偿
Lag Compensation
服务器在执行玩家开火等用户命令前,把其他玩家(及必要状态)回拨到「该命令在客户端生成时」所对应的世界时刻——扣除包延迟与客户端视图插值——再做命中判定,然后恢复。这样玩家可以对着自己屏幕上看到的目标直接开火,而不必凭感觉提前量;代价是可能出现「拐角后仍被击中」等时间悖论。
要解决的问题
客户端在本地时间 10.5 对准目标开火;命令在服务器 10.6 才到达,目标已走开,明明准星正确却判空。客户端预测只解决自己的移动手感,不解决「别人在你屏幕上的位置」与服务器当前位的时间差;视图还被 快照插值 故意画在过去。(Source Multiplayer Networking)
算法(Source / Bernier)
服务器保留约 1 秒的玩家位姿历史。执行 usercmd 前:
把其他玩家(通常仅玩家)移到 的历史位姿(可在两份历史间插值;需含蹲下、生死等),执行命令(射线检测等),再恢复。(Source Multiplayer Networking;Latency Compensating Methods in Client/Server In-game Protocol Design and Optimization)
Half-Life 把客户端插值毫秒数放进 usercmd 的 lerp_msec,服务器必须计入;关掉实体插值会导致补偿方程失真。(Latency Compensating Methods in Client/Server In-game Protocol Design and Optimization)
sequenceDiagram participant Shooter as 射击者客户端 participant S as 服务器 participant Target as 目标(历史) Shooter->>Shooter: 在插值后的画面上瞄准并开火 Shooter->>S: usercmd(含开火) S->>Target: 回拨到 t_cmd 位姿 S->>S: 射线命中检测 S->>Target: 恢复当前位置 S->>Shooter: 确认命中 / 伤害结果
上图:命中在「射击者当时看见的世界」里结算,而非服务器当前帧的裸状态。
为何不做客户端权威命中
让客户端发「我打中了谁」更简单且可像素级,但无法信任:即使用 VAC,中间人仍可注入 hit。权威判定必须留在服务器。(Source Multiplayer Networking)
设计取舍与悖论
- 收益:即时命中武器可「指哪打哪」,降低延迟带来的瞄准负担。
- 代价:高延迟射击者可能打中已经拐进掩体的低延迟玩家——受害者感觉「被拐角枪」;射击者视角则是合理正中。Valve 在 HL/CS/TFC 选择偏向本地响应。(Latency Compensating Methods in Client/Server In-game Protocol Design and Optimization)
- 对冲场景(迎面开枪、目标看不见你)时,悖论不易被察觉。
- 投射物:HL 不对独立存在的投射物实体做滞后补偿(它们该活在谁的时间线里是开放问题);开火音效仍可预测。(Latency Compensating Methods in Client/Server In-game Protocol Design and Optimization)
- 精度受 tickrate 与目标速度限制,不是像素完美。
运维注意
不要为「更准」关掉插值或延迟补偿。sv_showimpacts / sv_showhitboxes 可用于对照客户端红盒与服务器蓝盒的时间差。旁观第一人称看到的不是带补偿的射击者视图。(Source Multiplayer Networking)
与 UE5
UE 射击游戏需在服务器命中检测中自行实现历史回放或使用引擎/插件提供的补偿;概念上与 CMC 预测、复制时间戳配合。见 网络复制与 RPC、角色移动组件与 Mover、专用服务器。
出处
- Source Multiplayer Networking
- Latency Compensating Methods in Client/Server In-game Protocol Design and Optimization
- web.archive.org/web/20200910022723/developer.valvesoftware.com/wiki/Source_Multiplayer_Networking
- Yahn W. Bernier, Latency Compensating Methods… (Valve, 2001)