【笔记】状态同步笔记

状态同步位置和技能(适用于fps和mmorpg类游戏)
客户端A的同步阀值(减少同步量)
    客户端A本地会存储一份对其他客户端看到的A的预测状态,当本地真实状态和预测状态偏差超过阀值时,则发起同步,同时更新客户端A本地的预测状态
    玩家运动的关键点也会同步,例如起跳坐标点,起跳最高坐标点,落地坐标点,开始跑步的速度方向,停止跑步时的坐标点
插值算法的选择
    客户端插值 和 航位推测的选择
    航位推测只用于预测位移
    客户端插值(线性插值,3次样条插值,曲线的寻路(寻路这个可能会在同步频率低的游戏中使用))
    使用航位推测:不做服务端的延迟补偿时,可以对客户端A上的第三方代理对象做航位预测
        客户端A上看到的玩家B的移动
            客户端A看到的第三方玩家B一直向着A接收到的服务端发来的B的数据包的最新状态插值,当客户端B走到最新状态,还是没有再次接收到服务器的数据包时,会按上一个移动操作包进行运动,直到再次收到B的数据包,则去检测是否有错误
        客户端A上玩家B的移动预测错误时的纠正
            A接收到服务端的数据包时检测到B在客户端A上的模拟有错误时,有以下处理方法
                1.距离远则瞬移表现层,适用于快节奏的游戏
                2.距离近则插值,可以用3次样条插值,适用于快节奏的游戏
                3.如果是突然加速这种,可以加二阶参数(例如加速度)去处理,例如插值时增大加速度,接近航位推测近似值时降低加速度
    使用插值:做了服务端延迟补偿时,服务端需要精确的计算出被射击的玩家的位置,需要通过帧数和插值进度去计算,所以此时不能用航位预测        
        一般类似fps需要优化射击方体验的游戏中需要延迟补偿,此时远程玩家使用客户端插值,而不是用航位推测
        在客户端A看到的第三方对象B,例如B此时从第3帧的状态插值到第6帧(帧状态是服务端下发的,且客户端更新频率和服务端更新频率保持一致,一般是1秒30帧)
        A开枪射击B时,发起射击请求,请求包内会有A在XX坐标,以XX角度,B从第3帧,插值到第5帧,当前插值进度XX
        服务端收到包后,根据缓存的前几帧的状态和插值的帧以及插值进度去计算A开枪时看到的B所在的位置,再做命中检测
客户端A接受到A的状态数据包时的处理(移动)
    客户端发起移动包,同时客户端记录下这个操作(客户端utc时间和操作),客户端本地立刻开始移动(此时是客户端的移动预测)    
    RTT时间后接收到服务端发来的数据包,将这个数据包内的时间戳和整个数据包状态存储起来
    因为接收到的数据包里的状态会比当前服务器状态慢大概半个RTT,所以需要本地模拟预测半个RTT的移动
    根据数据包里的服务端发起的utc时间 + 服务端和客户端的时间差,得到客户端对应的服务端发起这个数据包的时间点
    然后客户端从记录下来的自己的移动操作列表中得到这个时间点之后所有服务端未加入计算的移动操作
    通过数据包(指定时间在哪个坐标)+服务端计算出这个数据包时未计算的操作(也就是客户端这个时间点后的其他操作)
    计算出在当前时间应该在的状态C(位置,方向,旋转等),然后向C状态进行插值
    (如果移动的中途没有被其他玩家影响的话就是精确的,即使有误差也会很小(例如被技能打中晕眩之类的)),被其他玩家操作影响后也会发同步消息到客户端,客户端再纠正
玩家B施法,客户端A看到玩家B是怎么施法的
    会有延迟,也就是玩家B在客户端B按下施法,客户端A看到的玩家B至少也是RTT时间后才会播放施法动画
玩家A施法,客户端A看到玩家A是怎么施法的
    按下施法按钮,先播放前摇,前摇时间至少是RTT,接收到返回的数据包时,如果不能施法则停止施法动画,如果能施法则继续动画,以及播放后续施法效果(例如射出飞弹)
服务端延迟补偿
    服务端会记录之前的n帧的世界状态
    服务端接收到玩家A的施法包时,从包中取出客户端发起的utc时间戳t1,加上服务端和客户端的时钟差后得到玩家A在发起操作时服务端的时间t2
    那么用t2去取之前记录下来的世界状态
掩盖不同步的技巧以及优化
    优化命中表现:添加攻击边缘模糊的特效,数据层上会击中的攻击,因为表现层还在插值,所以如果没有特效,看起来是不会击中的,但因为有范围模拟的特效,所以表现上就跟击中了一样
    优化预测:前摇时间的调整
    为了预测效果更好,某些情况下可以信任客户端
    降低延迟
        选择更近的服务器节点(需要负载均很)
        让服务器和客户端tick的速度更高(需要衡量性能压力)
        尽量减少服务端和客户端接收到输入时的缓存buffering处理
客户端平滑插值(平滑处理位移的做法会在整个同步过程中的方方面都用到)
    接收到消息包(包含时间戳以及正确的位置P1)后,和本地记录的该时间戳的位置对比,如果相同则不处理。
    如果不同则,数据层从P1位置开始按已经记录下来的这个时间戳之后的操作包进行移动,然后得到客户端预测的数据层位置。
    和当前表现层的位置进行比较,距离远就瞬移,距离近就插值(如果是直接拉回,不进行P1+预测包的预测处理的话,表现上看起来会莫名其妙的拉回到以前的一个位置,网络差时基本就不会移动了)
体验上分为:对人战斗的体验和单击打怪的体验
优化了延迟后仍然会有的问题
    fps中看A玩家看到自己已经躲到了掩体后,仍然被命中。原因如下:
        1是A的操作还没发到服务端,虽然看着是进了掩体,但在服务端看来是没有躲在掩体后的
        2是fps如果做了服务端的延迟补偿,则B开枪射A,B看到的A是滞后服务端半个RTT的且正在插值的对象,此时如果B的网络很差,则A躲进掩体后,B还是能看到A且命中A
    不停移动的玩家会更难射中,因为即便做了以上的优化后,仍然会有误差
整体流程来看:
    按下鼠标到网络packet发出--客户端帧数越高越好
    网络延时(ping)--延时最大头
    服务器上面buffering的时间--可以根据重要性进行取舍
    服务器上面执行时间(帧数越高越低)
    服务器执行结果下行,又是一个网络延时(ping)--延时最大头
    客户端buffering时间
    客户端显示时间(敌人倒地飙血等等)
mmorpg的近战冲刺技能
    A发起冲刺请求后,本地先做前摇,服务端检测冲刺路线上是否有障碍,没有则通过,通知客户端运行施法,并下发给客户端,以XX速度,向XX方向,移动到XX坐标
    


mmorpg中用状态同步+aoi视野管理
只同步自己视野的状态
十字链表
导航推测(预拉扯算法)
三次参数法
延迟补偿
每秒1个包(坐标,朝向,速度)
持续模拟行进轨迹


碰撞和寻路
    二叉树空间分割法。服务端做碰撞检测
    椭圆表示collider。从四面向场景发射摄像。 1.从左边开始往右扫,碰到collider则暂存起来,暂定为ListLeft。从右边开始往左扫,碰到collider则暂存起来,暂定为ListRight。那么可以这样认为,相交的部分为可行走区域。(上下同理) 2.在可行走区域中画出N个正方形,与后端协定正方形大小。 3.然后剩下的就是用这堆格子来实现寻路
    
RTO是Retransmission Time-OutD的缩写,该时间决定了发送方在发送数据后,在多长时间内如果没有收到ACK,就重置重传计时器,并重传上次发送失败的报文

客户端输入预测
延迟补偿(fps必须要有)
    需要服务器对游戏世界中过往的状态进行缓存,然后推测客户端指令创建时候,服务器所在的时间点,然后使用过往的缓存状态进行计算,
    击中的判定由服务器决定的,服务器根据每个客户端的延迟取历史快照来做判定检测

导航插值
Tick Rate:每秒同步几个包到客户端
客户端和服务端的时钟需要同步,同步包里有实体Id,坐标位置,旋转方向,旋转速度,移动方向,移动速度,时间,移动加速度
相位滞后:可选参数,实体与影子保持一定距离同步,相当于保持一定车距,这样在控制者突然停止的时候,不容易因为网络延迟跑过了又被拉回来。
惯性移动:可选参数,开始移动或者停止或者改变方向都有加速度,这样就不需相位滞后了
关键状态进行缓存,不然如果别人向前连续跳五次,每次取得状态都取到最高点的话,别人客户端上的影子和跟随的实体会奇怪的持续的飞在天上,所以需要将起跳和落地这两个关键状态缓存,实体追赶时只有追上的第一个状态(一号影子)才能追逐第二个状态(二号影子)。
关键状态需要立即同步,比如跳跃、冲锋、落地
模拟丢包
优化:
    发送状态更新包时,不需要每次都发送,而可以只发送改变的状态。什么时候我们觉得改变了?就是当客户端实体与自己的影子之间的误差大于某特定数值时我们才发送更新包,这样虽然玩家在原地做左右摇摆的小幅度移动,只要没有超出范围,都不需要发送新的状态更新,其他玩家机器上看起来,它是站着不动的。


DR同步”和“非DR同步”,前者针对 ,后者针对 RPG和普通 ARPG
1)客户端角色先行表现,即不需等待服务器响应即开始客户端表现,避免网络延迟带来的操作手感问题;2)客户端第三方角色进行延迟补偿和预测同步,消除网络因素引入的位置误差;3)服务器消息缓存重传机制;从业务层面通常有采用技能效果和表现分离,一段伤害多段表现等;

内插值,外插值
有DR的航位推测(适用于FPS,赛车或者操作比较多的ARPG)
    DR Threshold(存在的目的是为了减小同步包的数量)
    玩家以速度v加速度a从pos1向方向dir移动时
    客户端本地以这些参数每隔一定时间(internalTime)模拟计算得出一个预测的位置pos2
    而实际上玩家的移动可能会有微小的调整,那么每隔internalTime的时间检测预测的位置pos2和当前客户端本地实际的位置pos3的距离是否大于了设定的DR阀值
    只有当pos2和pos3的距离超过这个阀值时才发同步包到服务端
    DR过小会导致同步包增多
没有DR的航位推测
    每隔一定时间进行一次同步,不进行位置偏移检测

状态同步中的两种移动同步:
    1是玩家进行操作后,表现层先行,等接收到服务端消息后,进行表现层插值
        缺点:表现上会有点飘
        优点:操作上没有滞后感
    2是玩家进行操作后,需要等接收到服务端消息后,才进行表现层插值
        缺点:有滞后感
        优点:开始移动时人物会感觉比较笨重,停止移动时会有惯性移动的感觉。比较符合真实移动的感觉

第三方客户端在因为抖动而没有接收到移动包时,会本地预测按已有的速度继续向前跑,接收到移动包后在插值到真实位置
当误差较小或者非常大的时候,直接瞬移,表现是有一点轻微抖动或者是瞬移
当误差较大的时候,会根据距离控制速度进行加速跑到正确位置去

------------------------
------------------------


客户端预测,和服务端延迟补偿
爆头
mmo很少做服务端延迟补偿,fps游戏一般会做服务端补偿

如果玩家的Ping很大,服务器会怎么办? 
上面的例子都假设客户端和服务器之间的延迟无穷小,那么当玩家Ping很大的时候会发生什么的呢?
假设玩家A与服务器之间存在100ms的延迟(单向,往返则是200ms),其他玩家的延迟忽略不计,服务器的通信频率足够大(频率不够大还会造成其他很严重的问题,这个放在后面讲)。玩家A在某一刻向服务器发送了一个请求(比如向前走),那么这个请求会在100ms之后到达服务器,服务器判定后返回结果,再经过100ms你的客户端会收到确认,服务器已经把你的位置向前移动了若干距离。
假设客户端在没有收到任何服务器的更新前画面都不会变化,那么在这200ms内你就会觉得游戏“卡顿”。
实际上很多游戏里中你会在这200ms里看到你自己是在向前走,其实那只是客户端“擅自”在绘制你前进的样子,这是一种延迟补偿策略,称为“客户端预测法”。
即客户端能够大致预测游戏未来的走向,因此在接收到服务器更新前会把预测到的画面先绘制出来(比如移动、武器的开火效果、弹药计数的变化等)。客户端收到服务器通信后如果数据有出入则立刻纠正为服务器提供的数据。因此在延迟很大的时候玩家会发现“明明往前走了过了一会又瞬移回到之前的位置”的原因,或者是“明明开了好几枪而且也都显示了但过了一会弹药计数只减少了一点点”。
既然扯到这里了那就认真的讲下延迟补偿策略(lag compensation),一般来讲补偿策略分服务器端和客户端两类,上面提到的预测法属于客户端一类,其他的客户端策略还有插帧法。
所谓插帧法就是客户端会记录之前一次从服务器收到的信息,然后在接受到下一次通信的时候不立刻更新游戏画面,而是逐渐的更新画面(比如两次通信间玩家B移动了10单位距离,客户端会绘制玩家B以一定的速度移动了这10单位距离,而非立刻绘制玩家B瞬间移动了10单位距离)。
插帧法的问题在于如果玩家并未沿直线运动且其直线路径中有本应不能通过的物体存在时(比如绕过一堵墙),客户端会绘制出该玩家穿墙而非绕过去的动作。

服务器端处理延时同步常用的策略
1.“眼不见为净”法,服务器不去补偿玩家的延迟是一个合理的做法,特别是当游戏内进行的事件非常多(想想《行星边际2》里面千人同图混战的情形)。浪费宝贵的服务器资源去补偿个别玩家的延迟是不明智的。这个策略的缺点很明显,就是玩家有可能会对游戏体验不满意。
2.“倒带”法,采用倒带法的服务器会记录刚刚过去一段时间内(比如0.5秒)游戏内的所有信息。当一个有延迟的玩家(比如200ms)向服务器发送一个请求,那么服务器在处理这个请求的时候会调取0.2秒前游戏的状态然后进行判定,在把判定结果对所有客户端进行同步,
如此一来该玩家的操作虽然有延迟但也能与他/她所看见的画面一致。该策略的最大问题在于它让不同延迟之间的玩家被迫体验较大的延迟。举个例子,假设游戏里击杀时间(TTK)足够小,玩家A(10ms延迟)和玩家B(延迟200ms)对射,两人都是空血(一次攻击即死),A比B先开火(时间差很小,比如50ms)。玩家A的次攻击很快(10ms后)就得到了处理并记录在服务器中,
玩家B被判死亡。然而在200ms后玩家B的请求到达,服务器倒带0.2秒,此时玩家AB都未死亡,因此玩家B的攻击有效,玩家A也被判定为死亡。如果没有延迟,那么服务器应该会判定玩家B死亡,因此玩家B将无法攻击,玩家A应该存活。换句话说采用倒带法的服务器里如果有一个延迟很大的玩家将会拖累其他低延迟玩家的游戏体验。


------------------------
------------------------

改善同步的技术,用来降低高ping客户端的延时感受(客户端的动态预测和延时补偿技术)。
有A和B两个客户端,在B移动时,A的客户端上会以一定频率收到B的移动信息同步。如果总是等到收到B的信息后再去被动地移动,那就会导致在A的机器上,B的移动总是滞后的。这一般是典型MMO如WOW的做法,而对某些类型的游戏(fps,空战)来讲,这种延迟是难以接受的。
一个做法是,A总是通过B之前的移动去预测其接下来的移动情况(Q3的做法),这样有极大的可能(实测至少90%以上的情况下)在服务器把B的真实移动信息发过来时,双方是匹配的(也就是预测准确)。在这种完美情况下,在A机器上体验到的B的移动就没有滞后(这个“没有滞后”是相对服务器而言的,因为所有的计算以服务器为准,因此此处暂不考虑服务器跟B之间的延时)。预测本身可以通过缓存之前若干秒的操作队列来实现,注意仅依靠当前的状态是不够的。
这种预测会在B有新的操作事件发生的时候失败,而这里的处理与Q3稍有不同。比如B正在往前飞,突然松开了W键开始减速直到停下。在未收到B的减速及停止消息前,A仍保持了B在全速往前飞的预测,此时若收到了减速的信号(同步过来的加速度突然变为负向的,速度开始变化)此时A可以意识到,自己坐标系中的B已然偏离了正确的位置。那么可以采用一个补偿算法去修正B。修正的幅度可以参考当前客户端的延迟情况。这个算法可以是激进的(尽量迅速地校准,牺牲平滑性)或保守的(保证飞行的平滑性,牺牲修正速度)。
当然了,前文中服务器与B(消息发送端)之间的延时,仍然对玩家体验有决定性影响。当客户端把自身的操作发给服务器时,这时的延时真正的决定了客户端的最快反应时间。这时网络环境的好坏,会直接影响玩家(在游戏中实际表现出)的反应速度。
补充几句话,怎么判断什么时候用这个预测和补偿,用的时候强度有多大呢?仍以前面的AB客户端为例的话,一般来讲约 100ms 的阙值即可(延时越敏感,客户端B的avatar移动速度越快,这个值应越低)。当A与服务器之间的延时(可定期roundtrip测得)高于阙值时,就可以开始缓存操作序列来做预测了。


------------------------
------------------------
网络时延是必然存在的,所以游戏状态的不同步也是必然存在的。但我们可以通过技术手段尽量减轻不同步问题对用户体验带来的影响。

技术术语:

1)Latency:Latency指的是数据包从客户端发送到服务端再收到服务端回包所用的时间,通常被称为RTT。虽然单程的数据包传输时间并不总是等于RTT/2,但是简单起见我们可以认为两者是相等的。下文说到Latency都是说一个RTT时间,单程Latency则是指RTT/2。

80年代有个工具叫ping使用ICMP echo测试延迟,所以人们常把RTT和ping联系起来。ping这个指令现在还在用。

2)Hit Box:角色的3D模型代表了哪些区域是参与到“命中”计算的。你看不到hit box,你只能看到模型。hit box可能比模型大,也可能比模型小,也有可能很不精确,这都取决于具体的实现。我们知道,tick rate会影响命中判定,但是hit box不精确可能对玩家在是否命中方面的感受影响更大。

3)Tick Rate:Tick Rate指游戏服务端更新游戏状态的频率。单位是hertz。如果服务器的Tick Rate是64,这就意味着服务端每秒钟最多向客户端发送64次数据包。这些同步数据包包括了游戏状态更新,比如player和场景对象位置等。一次tick的长度就是其持续时间,单位为ms。

比如,64 rate时tick长度是15.6ms,20 rate时是50ms,10 rate时是100ms

4)Client Update Rate:这是客户端接收服务端更新的频率。比如说,如果client update rate是20,而服务器tick rate是64,那么从体验上来说,这个客户端实际是在和一个tick rate为20的服务器联机。通常这个是配在客户端本地的,也有可能是写死的。

5)Framerate:这个是指客户端每秒最多可以渲染多少帧,通常被称为FPS

6)Refresh Rate:显示设备每秒钟刷新多少次。单位为hertz。如果framerate是30,一个显示频率为60的设备将把每个画面显示两次。反过来,如果framerate是120,但是显示频率为60,那么显示设备只能显示每秒60帧。显示设备的频率比framerate大,提升framerate才有意义。大多数显示设备频率是60或120。

7)Interpolation:这是一种平滑场景对象移动的技术。实际上内插值所做的就是在场景对象的两个位置之间做插值,以让运动过程平滑。插值延迟通常是2tick,也不尽然。举个内插值的例子,如果一个玩家沿着一条直线移动,在tick1的时候位置在0.5m,在tick2的时候位置在1m,内插值的作用就是让客户端看起来是平滑的从0.5m移到1m。但是服务器实际看到的是离散的位置,要么在0.5m或1m,不可能在中间的某个位置。如果没有插值,游戏的抖动将非常明显,特别是在从服务端更新了一个运动对象的位置后。内插值只在客户端做,实际上减慢了将整个游戏状态绘制到屏幕上的速率。

8)Extrapolation:这是客户端补偿延迟的另一种技术。客户端将场景对象的位置做外插值,这样就不会导致绘制的时候没有更新到新数据。通常优先使用内插值,特别是FPS游戏,因为玩家的移动是不可预期的,外插值的结果可能通常是错的。

9)Lag Compensation:延迟补偿是服务端减小客户端延迟影响的一种方法。如果没有延迟补偿,或者延迟补偿做的不好,由于客户端看到的是经过延迟后的游戏状态,玩家要命中目标就必须使用一些预判技巧。实际上,延迟补偿所做的,就是当服务器从客户端收到操作(比如开枪)后,将操作发生时间往回调一个单向时延的时间。服务端游戏状态和客户端游戏状态的时间差异(也被称为"Client Delay")可用下式给出:

ClientDelay = (1/2 * Latency) + InterpolationDelay

延迟补偿的实际操作步骤:

Player A看到Player B向一个角落跑去
Player A开枪,其客户端把这个操作发送给服务器
假定A的延迟的一半是Xms,那么Xms后服务器将收到Player A的操作
服务器从记录的历史信息中找到A开枪时B所在的位置。一般情况下,服务器应该往回看 (Xms + Player A's interpolation delay) 来回滚到A开枪时的游戏状态。但是这个时间是可以调的,取决于开发者希望延迟补偿算法如何工作。
服务器判定这次的开枪是否命中。如果子弹的轨迹和目标模型的hit box相交,就认为是命中了。在这个例子中,我们假定命中了。在Player B看来,他觉得自己已经躲到墙后面了。但是Player B看到的游戏状态所处的时间和Server认定的开枪时间是有差异的,可以表示为:
(1/2 * PlayerALatency + 1/2 * PlayerBLatency + TimeSinceLastTick)
在下一次tick中,服务器使用计算结果更新所有客户端:Player A看到自己命中了目标,Player B看到自己掉血或挂掉了。
需要注意的是,如果两个玩家对射,而且都命中了,游戏如何处理就取决于实现了。比如说在CS:GO中,如果先收到的射击操作命中了目标玩家,那么后续收到的那个玩家的射击就会被丢弃。这样就避免了两个玩家的射击请求在同一帧,然后都命中,都挂掉。在Overwatch中,这种情况是可能的。这里是有取舍的。

按照CS:GO的做法,网络较好的玩家是有很大优势的。经常会有“我在挂掉前打中了目标,但是他没死”的情况。你甚至在挂掉前能听到你的枪响和命中的声音,却没对目标造成伤害。

若是在Overwatch中,玩家反应时间的差异对结果影响较小。比如说,如果服务器tick rate是64,若Player A比Player B早15ms射击,那么双方的射击都是在同一个15.6ms tick之内,所以最终结果是双方都命中,都死掉了。

如果延迟补偿过度,就会出现“我朝目标早前的位置开枪,却还是命中他了”。
若延迟补偿不足,则会出现“我必须对目标的移动做预判,这样才能命中”。
服务器做延迟补偿所记录的历史数据应该是有限的,不然高延迟的玩家会明显拖累其他玩家的游戏体验。

在Overwatch中,服务端延迟补偿也被称为Favoring the shooter(https://www.vg247.com/2016/04/05/overwatch-devs-talk-netcode-and-favouring-the-shooter/, https://www.pcgamesn.com/overwatch/overwatch-netcode),也就是说,如果你在自己屏幕上瞄准了目标并射击,那么很大概率将命中目标。也有例外情况。比如,若你射击目标的那一刻,目标跳跃躲开了,这时服务器认为目标做了一个完美的闪避,可能会被判断未命中。所以计算命中时并不总是使用射击那一刻的信息。这是为了玩家体验打的补丁。

如果你是要设计一套同步方案,根据设计目的不同可能有不同的方案。公平性、即时反馈、网络流量等都可能是重要的设计目标。可以参考以下因素:

1)网络链接。延迟越低越好。选择一个延迟最低的服务器开始游戏是很重要的。网络上的拥塞程度也会导致网络延迟。延迟补偿可以帮助解决“射击和命中”的问题,但是如果你的网络不好,更多的情况下,你可能会体验到“已经跑到墙后面还是被打中”或者“我先射击但还是死掉了”的情况。

2)如果你的客户端frame rate很低(只要低于显示设备刷新频率或跟他差不多),会导致感受延迟变大,通常比tick rate带来的问题更严重。

3)尽量使用内插值。大多数游戏使用的内插值间隔是tick间隔的两倍,主要考虑到如果一个数据包丢掉了,玩家的移动中断也不会在屏幕上表现出来。如果网络状况很好,没有丢包,把插值间隔设置为tick间隔是没有问题的。但是如果有丢包,就会导致抖动。比如在CS:GO中,这对体验的影响比把服务端tick rate从20调高到64带来的体验影响更明显。如果这个值设的太低,会导致极大的抖动。

4)如果有可能,你应该增加游戏的client update rate来优化体验。其代价是CPU和带宽消耗。对于客户端来说,除非你家的网络带宽非常低,增加CPU和带宽消耗是可以接受的。

5)如果你的显示设备刷新率是60hz,那么很有可能你根本感受不到tick rate在64和128会有什么差异,因为由于tick rate差异导致的改变根本无法通过你的显示设备体现出来。

6)通常来说,服务端tick rate越高,用户交互就越流畅,也更准确。当然网络同步量也越大。如果我们对比tick rate64(CS:GO比赛)和20(Overwatch Beta服务器宣传的帧率),两者因为帧率差异导致的最大可感受延迟是35ms.平均情况下是17.5ms.大多数人是察觉不到其中的差异的,但是有经验的玩家通常是能感受到的。高的tick rate并不会影响到延迟补偿的工作。所以有时候,你还是会有明明自己已经跑到墙后面了可是还是死了的体验。把tick rate提高到64并不能解决这个问题。

7)Responsiveness: 当你按下按键的时候,需要能立刻看到反馈。这对动作游戏和FPS游戏都是非常重要的。有多个因素会影响即时反馈。首先,客户端发送玩家的输入应该是即时的。其次,客户端不等服务端回应就根据玩家的输入做状态预测和插值。在Overwatch中,客户端会维护一个历史纪录用于验证客户端预测的准确性。最后,服务端tick rate也会影响反馈。投射物的模拟也应和玩家做类似处理,并加上飞行时间,让玩家对反馈产生的时间有预期。

8)处理丢包。在Overwatch中,丢包是通过在客户端加速“命令帧”和在服务端设置命令缓存来解决的(http://www.gdcvault.com/play/1024001/-Overwatch-Gameplay-Architecture-and, http://www.gad.qq.com/article/detail/28682). 首先,系统采用确定性模拟技术,将时间量化为“命令帧”。每个命令帧都固定为16毫秒(比赛时是7毫秒)。服务端和客户端模拟都运行在保持同步的时钟和这个量化值之上,保持固定的更新频率。当客户端意识到丢包时,会比约定频率更快的模拟,而服务端则将命令缓冲区增大。客户端发送指令的频率加快,而服务端缓冲变大以容忍更多的丢包。客户端的指令数据包包含了未经服务端确认过的所有指令,这样服务端就有机会在实际模拟并发送确认包前更新缓冲区。


----------------
https://zhuanlan.zhihu.com/p/28617637
时钟同步,航位预测,Lag Compensation(延迟补偿)
https://zhuanlan.zhihu.com/p/30520604
网络游戏中子弹与单位的命中判定问题

https://blog.csdn.net/weixin_33888907/article/details/91985725
http://udn.yyuap.com/forum.php?mod=viewthread&tid=121003

FPS和 赛车类游戏(预测插值模式)
(10-30个)
位置预测及坐标差值的“导航推测算法(DR)
影子跟随算法(DR算法的一个改进实现)
除了狙击这种一枪毙命的射击外基本都是客户端判断,之后纠正?

https://blog.csdn.net/qq_14914623/article/details/104557226
延时补偿(好文)

动态预测技术和延时补偿
https://github.com/Unity-Technologies/FPSSample
unity fps sample
https://www.jianshu.com/p/c4ea9073f443
unity fps sample分析
http://www.gulu-dev.com/post/2014-03-15-dynamic-prediction-and-latency-compensation
客户端动态预测技术和延时补偿技术


https://mp.weixin.qq.com/s/1WN9rA4yK6Wi2-BhQFIn5Q
揭秘重度MMORPG手游后台性能优化方案,jps

https://baddogzz.github.io/2020/01/07/Move-Predict/
位置同步之移动预测
https://zhuanlan.zhihu.com/p/56923109
网络游戏同步技术概述

https://blog.csdn.net/left_la/article/details/6346776
赛车类 持续模拟行进轨迹,预拉扯算法(也就是导航推测算法)以及加上的三次参数法

http://www.zhust.com/index.php/2014/02/%e7%bd%91%e7%bb%9c%e6%b8%b8%e6%88%8f%e7%9a%84%e7%a7%bb%e5%8a%a8%e5%90%8c%e6%ad%a5%ef%bc%88%e4%ba%8c%ef%bc%89%e7%8a%b6%e6%80%81%e6%9b%b4%e6%96%b0%e5%8f%8a%e8%88%aa%e4%bd%8d%e9%a2%84%e6%b5%8b%e6%b3%95/
网络游戏的移动同步(二)状态更新及航位预测法
https://zhuanlan.zhihu.com/p/83010584
多人网络游戏同步探究(上)
https://zhuanlan.zhihu.com/p/62860859
三次样条(cubic spline)插值
https://www.cnblogs.com/SiumingLearning/p/CubicInterpolateInUnity3D.html
Unity中三次样条插值曲线的实现
http://www.zhust.com/index.php/2014/02/%E7%BD%91%E7%BB%9C%E6%B8%B8%E6%88%8F%E7%9A%84%E7%A7%BB%E5%8A%A8%E5%90%8C%E6%AD%A5%EF%BC%88%E4%B8%89%EF%BC%89%E5%B9%B3%E6%BB%91%E7%AE%97%E6%B3%95/
网络游戏的移动同步(三)平滑算法
https://www.zhihu.com/people/Coder27/posts
https://zhuanlan.zhihu.com/p/50440945
状态同步demo测试(感觉像是帧同步)


https://gitee.com/fyindex/StateSync/?_from=gitee_search
基于ET框架实现状态同步demo

https://zhuanlan.zhihu.com/p/56922476
UE4网络同步思考(二)---大世界同步方案ReplicationGraph

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页