← ALL ARTICLES
游戏网络8 MIN READ

延迟补偿命中

全库目录221
本文目录16

射手看到目标还在门外,服务器收到射击时,目标已经走进门里。两端看到的是不同时间的目标。延迟补偿让服务器按射手所见时刻查询有限窗口内的碰撞历史,再把命中结果应用到当前权威状态。

全文跟踪同一发射击:输入会话C的17号输入由射手实例S7、武器W3发出;服务器在Tick600消费它,此时服务器时间为10.000秒,射手开火画面采用的远端时刻为9.820秒。W3原有2发弹药,开火画面中的目标实例T4还在门外。显示时间决定查哪份历史,Tick600决定使用哪个枪口和何时扣弹,后续结算Tick决定伤害作用于哪份当前状态。这三个边界分别保存,才能解释异步等待与恢复。

射击与显示时间

客户端预测本地角色,远端角色却在历史快照间插值。因此射击请求至少要关联输入序号、射击朝向和该帧使用的远端显示时间。客户端记录开火帧实际采用的远端播放时刻r及服务器纪元,服务器用时钟映射估计射击生成时刻,核对画面年龄与许可插值窗口。稳定播放时可写成下面的关系,目标查询使用通过校验的实际r:

tq=rfire,dactual=tfire,server−rfiret_q=r_{fire},\qquad d_{actual}=t_{fire,server}-r_{fire}

例如服务器当前10.000秒,估计请求在9.920秒生成,远端插值延迟为0.100秒,实际r为9.820秒时查询该时刻的目标碰撞体。这里的80毫秒已经体现在射击生成时刻里,不能再次减去一次单程延迟。

服务器核对序号、开火间隔、弹药、枪口位置和朝向变化,再检查查询时间是否落在允许窗口及实际历史范围。客户端时间戳是请求数据;服务端按会话样本、最大补偿窗口和配置允许的插值延迟限制它。过旧请求可明确拒绝,不能悄悄把任意旧时间夹到最早一帧并声称重建了原画面。

快照页的播放时间r有独立速率控制,缓冲恢复期间未必等于估计服务器时间减去目标延迟。因而服务器读取请求报告的开火帧r,并按下述许可范围核验。请求记录(输入会话,输入号,显示纪元,呈现段,播放状态,viewReady,r,关键实体样本引用),并把d_actual限制在会话协商的画面年龄范围内。

呈现状态决定这份时间能否使用。Playing的r按许可速率推进;Frozen保持r不动,仍受最大画面年龄限制;Waiting与viewReady=false均拒绝依赖该视图的历史命中。Frozen是一段暂停的时间轴,视图过旧就暂停请求。否则客户端可以一直朝旧位置射击,让有限补偿变成无限追溯。

缓冲重建或缺失的新运动段补齐后,会话先登记新呈现段及重同步标记,重新检查画面年龄与有效状态,再建立r的推进锚点。旧段的速率比较到此结束。超窗、纪元不符或缺少历史均明确拒绝;客户端声明只提供候选视图,许可范围由服务器确定。

实体新鲜度与视图校验

全局r递增不能证明每个目标都在这个时刻有有效样本。快照页的实体求值器返回段ID、实际取样时间和validAtR;某个低频目标已超过自己的外推上限时,全局仍可能Playing。客户端从玩法定义的查询关键集合聚合viewReady,集合包括可受击体与潜在遮挡物。集合中存在Stale或Missing就暂停依赖该视图的开火请求,装饰实体可独立降级。

服务器不把这个布尔值当作证明。它保存该观察者已确认生成身份、已发送运动样本ID及时间,按配置的最大外推与画面年龄核对请求引用的样本是否足以支持r,并检查关键对象的覆盖集合。客户端可以报告丢包导致无法显示,服务器却不能仅凭客户端自称有效便接受任意旧目标。发送日志也不能证明客户端实际收到,因此规则只限制可接受视图的范围;精确重建客户端采用的轨迹还需要下一节的样本引用方案。权威历史策略始终保留估计姿态与权威姿态之间的误差边界。

显示估计与权威历史

实际r解决查询哪一个时刻,并不保证客户端在r显示的位置等于服务器该时刻的权威位置。本文采用同一r查询权威历史的规则:命中以权威轨迹为准,客户端插值与有限外推的误差仍可能造成所见偏差。两份快照之间的线性插值会省略中间曲线,加速期间的速度外推也没有未来信息,给它一个准确时间戳不能补回这份轨迹。

把门口的T4改为加速运动:最新快照在9.720秒给出x=0米、速度1米/秒,随后服务器沿X以20米/秒²加速。客户端外推到r=9.820秒显示x=0.1米;权威历史此时为1*0.1+0.5*20*0.1²=0.2米。若小目标半宽0.04米,朝客户端所见x=0.1开出的射线可能错过历史中心x=0.2。在r=9.820秒恰好达到该实体的外推上限时,这份估计仍处于允许窗口。若之后全局r继续推进,该实体进入Stale并保留x=0.1,validAtR变为假,关键集合门控拒绝相关命中请求。若包时间轴也恰好在r=9.820秒进入Frozen,允许的查询仍使用权威9.820秒的x=0.2,误差不会因为全局r停止推进而自动消失;恢复时在相同r重新求显示姿态。

年龄窗口限制可请求多旧的视图,外推上限限制估计持续多久,二者都不等同于精确重建所见几何。

若玩法要求复现允许的客户端展示轨迹,服务器还需保留发给该客户端的快照版本和相同插值/外推规则,请求引用左右快照ID或外推源ID、呈现段、模式与r;服务端检查这些快照确已发送、相容且处于许可窗口,再按同一规则重建展示碰撞体。客户端自报位置不能代替这份重建。本文的权威历史策略不采用这条展示轨迹判定,两种规则的公平性与误差由明确场景比较,结果记录采用的策略版本。

射手枪口与远端目标采用不同边界。按 客户端预测 的输入协议,服务器在实际消费开火输入的Tick先执行本步移动,再从该步权威角色姿态计算枪口并判射击;朝向也来自该输入并受变化速率与动作状态校验。客户端采样时刻的映射用于年龄和反重放检查,不把射手退回那个墙钟时刻。目标和可回溯遮挡物查询实际t_q,与射手当时采用的远端显示时刻对应;碰撞姿态依照上述权威历史规则求得。若输入在服务端队列多等了一步,枪口仍使用该输入实际消费步,而不是误取早一步的射手历史。此双边界规则不把本地预测射手和远端插值目标强行放在同一个历史时刻。

历史碰撞体

每个服务器 Tick 保存可受击实体的稳定ID与代次、碰撞体位置、旋转、尺寸和有效状态。查询时间落在两帧之间时,连续运动可插值;传送、生成和销毁把历史分段,跨段时按玩法规则处理,不能在不存在的位置生成中间碰撞体。

历史查询可使用独立碰撞场景,也可暂时替换实时碰撞体后在作用域退出时恢复。独立场景避免查询期间触发实时物理回调,代价是额外存储和索引。历史长度为 WW 秒、频率为 ff、实体数为 NN、每实体记录 BB 字节时,原始存储约为 WfNBWfNB,还要计入索引和分配成本。

动态门和平台也会改变遮挡。把角色退回过去、门却留在现在,是一套混合时间规则。本文选择角色、可移动门与平台全部在t_q查询,静态场景用固定几何。门开关等离散变化保存事件时间,查询时取不晚于t_q的最近状态;角色传送也按事件切段。服务器接纳输入时记录采用的补偿时间和策略版本,并固定查询所需的历史样本版本。异步查询持有这些样本直到结果进入模拟提交队列,环形历史缓冲不能在此期间覆写它们;可复制所需区间,或按引用计数延迟槽位复用。仅固定时间而未保留对应样本,等待中的查询仍可能遇到历史淘汰。查询任务退出后释放内存历史持有;持久查询包还受Pending恢复保护,终态和回执按射击身份保存。

最小射线查询

用球形受击体可以先验证时间插值与命中算法。设单位射线方向为 dd,起点为 oo,历史球心为 cc,半径为 rr。代入 ∣o+td−c∣2=r2|o+td-c|^2=r^2,令 m=o−cm=o-c,则 b=m⋅db=m\cdot d、q=m⋅m−r2q=m\cdot m-r^2,判别式为 b2−qb^2-q。

python
disc = b*b - q
if disc < 0:
    return None
enter = -b - sqrt(disc)
leave = -b + sqrt(disc)
if leave < 0:
    return None
return max(0, enter)

这是求交机制片段,输出射线前方距离,所有位置与半径使用米;起点在球内时输出0。完整参考函数见参考实现。把T4在9.820秒的球心设为(5,0,0)、半径1,S7的枪口为原点,射线沿正X,命中距离应为4;把球心改到(-5,0,0)时不应命中。真实角色需要胶囊或骨骼碰撞体,并比较所有有效遮挡的最近命中。武器射程为R_max时,外层查询仅接纳[0,R_max]内的距离;本片段只求无限射线的前向交点。

历史遮挡与实时状态隔离

继续改变同一发射击的历史输入:T4球心在9.800秒为(5,0,0)、9.840秒为(5,2,0),查询9.820秒得到(5,1,0)。射线沿X轴、半径0.5米时不命中;若误用9.80秒记录就会命中。门在9.81秒关闭时,门的历史状态也必须在9.82秒参与最近交点比较,否则角色虽然回溯正确,遮挡规则仍混用了时间。

临时替换实时碰撞体的实现必须覆盖所有退出路径:进入查询前保存每个被改对象的变换和启用状态,在禁止实时物理步进与回调的查询范围内安装历史状态,执行查询后用作用域清理恢复,异常和提前返回也走恢复。记录对象代次,避免把已经销毁重建的新对象恢复成旧对象位置。独立历史场景则将查询数据与实时世界隔离,后续只把命中ID和距离交回权威逻辑。

命中提交与验证

参见异步命中结算与恢复。

接纳与弹药所有权

参见异步命中结算与恢复。

查询完成与结算顺序

参见异步命中结算与恢复。

权威决策与Tick日志

参见异步命中结算与恢复。

查询包与崩溃恢复

参见异步命中结算与恢复。

恢复记录与有序回放

参见异步命中结算与恢复。

观察与反例

参见异步命中结算与恢复。

实现与证据

2026-10-22,以本机 Python 3.11 运行 python 知识库/examples/revision_16_21/test_reference.py,17项检查通过。参考实现与测试输入可复现本页注明的机制。 本页验证历史线性插值的窗口拒绝及球形射线正反向求交;尚未运行骨骼碰撞场景、真实网络故障或公平性测试。

相关主题

参考资料