帧同步与状态同步

最近在做的游戏中要用到网络同步的相关知识,因此针对帧同步与状态同步中查询了一些资料,并且涉及了TCP和UDP在游戏网络同步中的一些优缺点的整理,在这里记录一下

帧同步与状态同步

帧同步:服务器负责转化客户端的操作,每个客户端在固定的逻辑帧执行该帧所有客户端的操作命令,通过严格一直的时间轴上执行同样的命令。

优点:可以无视客户端服务器,开发方便

打击感反馈好

网络流量小

缺点:

  1. 网络要求高,涉及到具体帧同步实现的方式:

锁帧问题:服务器会等待所有客户端的第N帧都到齐之后再发送到每个客户端其他客户端第N帧的操作。所以一旦有一个客户端卡住就会所有人都卡住。War3的做法是加入超时机制,如果第N帧没有受到某个客户端,就不再等待它,并认为它什么都没做

逻辑帧平滑问题:一般受到的逻辑帧命令数据会加入客户端正在顺序执行的逻辑帧队列中。如果队列过长延迟就会高,如果队列端在网络波动的时候就会出现队列空饥饿状态,造成逻辑帧不平滑,可以采用逻辑和表现分离,平滑插值等做法。

  1. 反外挂能力差
  2. 断线重连需要追帧
  3. 客户端计算压力大,要每逻辑帧计算所有游戏单位的逻辑状态,即使单位没有在屏幕内
  4. 对结果一致性控制严格

状态同步:

服务器承担所有计算,客户端只表现

优点:容易断线重连  容易防外挂

缺点:流量大,打击感反馈不准确,所有表现都是服务器推动的,在网络波动、客户端服务器不同计算的误差下,客户端各个表现难以契合

对网络要求比较高

 

网络优化的方法:1. 使用可靠的UDP代替TCP,降低延迟

  1. 在表现上优化,客户端先行,平滑插值等在表现上降低对延迟的感受

 

在CS架构中,每个客户端的最终状态不是由每台客户端共同确认,而是由服务器来确定最终结果,每个客户端展示一个类似的结果,而真实的游戏状态运行在服务端

在纯粹CS架构中,本地不需要运行游戏代码,而是把一些按键,鼠标移动,点击等信息封装为数据包然后发送给服务端,服务端会在它的游戏世界中更新我的玩家状态,然后封装一个数据包把我的角色信息和离我近的玩家信息返还给我,所有的客户端在每个消息更新的间隙做差值预测,保证每个状态更新期间物体可以平滑移动。

(当以客户端信息为准的时候,很容易被黑客攻击,自由地改变自己想要改变的数值)

客户端预测:

在原来的游戏中,我点击射击之后,需要等待数据包发送到服务端,然后服务端返还给客户端,然后才能射击(会有延迟)

解决办法:两个部分:客户端预测和延迟补偿

客户端预测:客户端可以运行一部分游戏代码,在本地预测我的游戏角色移动并可以即时响应我的输入

难点:客户端与服务端对玩家所做的事情不一致的时候客户端如何基于服务端去更正信息

客户端与服务端的位置是会产生不一致的。因为假设客户端到服务端需要花费100ms,而服务端到客户端也需要100ms,那么同步的时候服务端的状态就是客户端200ms以前的状态,如果直接进行同步就会看到客户端不断被拉回之前的状态,这就让客户端预测失去了意义

解决办法:在客户端创建一个buffer,用它来循环保持角色的状态以及本来玩家的输入,当客户端受到服务器的更正信息的时候,首先丢弃比更正状态老的信息,然后基于(更正的)正确的状态重放存储在buffer里面的输入信息,重发的这些输入信息的范围是从正确状态到当前预测时间之间。

 

UDP与TCP在网络游戏中的应用

UDP传输不保序不可靠,不能确定到达,可能丢失,也可能因为校验失败而被丢弃

传输非常快,因为不可靠所以不用花时间和带宽进行重传

应用通过Socket拿到的UDP包能保证是正确的

连接快,因为本身是无连接的,在通信前不需要建立连接,收发双方每次通信都是无状态的

简单

报头小,节省带宽

 

TCP有保序的可靠的传输,通过报头的Sequence number,acknowledgement number和window size来确定接收到的包是否按顺序,是否丢包

流量控制,通过windowsize实现,防止发送方发送太快导致接受方来不及接收

拥塞控制,通过sequence number,acknowledgement number等实现,判断是否丢包,是否拥塞,并采取措施

 

TCP问题:本身保序可靠传输,适合于回合制游戏,RPG等通信频率不高的游戏,例如炉石传说

传输慢,因为TCP本身使用了很多控制方法来保证有序和可靠,因此快节奏的游戏难以适应,因为它们通信频率高,要求延迟低,新发的数据包更加重要

连接慢,首次通信要三次握手

报头大,难扩展

 

网络同步模型:主要为锁步同步(Lockstep)和状态同步(state Synchronization)

还可以考虑快照同步

帧有两种定义:逻辑帧  tick  在逻辑层面是离散的过程,可以认为是一个帧一个帧的运算

渲染帧  frame  画面也是离散的过程,画面是一幅一幅的展现出来的。

逻辑帧率和渲染真率是独立的,例如tick是20,frame是60

k帧中,每一帧的状态集合Sk,收到的外部变化集合Ik

上行:客户端发送

下行:客户端接收

锁步同步:上下行都包含游戏外部变化原因Ik

状态同步:下行仅包含游戏得到的结果状态Sk,上行包含Ik

锁步同步:目的是在P2P中防止外挂

每个客户端在发送第k步的明文信息之前,现队铭文信息进行加密生成预提交哈希值,当客户端收到第k步中所有客户端的预提交哈希值后,才发送自己第k步的铭文信息,收到后将明文和哈希值对比,对比后如果不同就判断该客户端外挂

锁步同步既可以同步客户端的玩家操作,也可以i同步客户端的状态

至此,现在为大家所理解的:操作同步、不等待超时玩家的操作的确定性锁步同步,终于成型。
总而言之,每一步都停止等待的网络同步很早就有,却缺个简短的名字。为了安全性提出的“Lockstep”方案使用广泛,逐渐成为停止等待同步的代名词。翻译成中文时,引入了时间帧的概念Bucket Synchronization也和Lockstep已经结合起来使用,便将“step”译为帧,称为“帧同步”。然后更狭义的确定性锁步同步用得越来越多,大家也逐渐把“Deterministic Lockstep”简称为“Lockstep”,所以,确定性锁步同步口头交流中更常被简称为“帧同步”,有时也会被称为“操作同步”。

由于锁步同步仅同步变化的原因,所以要求所有客户端的运算逻辑g,t是严格确定的,才能够通过相同的输入得到相同的结果,否则就会累积出现蝴蝶效应

·  不使用浮点数而使用定点数,或限定各客户端所运行的硬件及操作系统从而浮点数的运算是一致的,

·  确定性的随机数机制,

·  确定性的容器及算法(增加、移除、排序等),

·  隔离和封装逻辑层,以防止其他不确定性的调用,

·  如需,则也须做到确定性的物理机制、导航机制、动画骨骼机制等,

·  排查所有引起异常(exception)的逻辑

 

状态同步:只同步游戏的运算结果

帧同步与状态同步的对比:

帧同步:流量一般情况下较低;预表现(客户端预测)较难,客户端需要在本地进行状态的序列化和反序列化;确定性要严格,否则容易引发蝴蝶效应;对网络的适应能力低,因为客户端预测难以实现;断线重连较难,因为需要耗时地使用帧同步数据进行快播追赶上当前的游戏进度;离线重播(播放录像文件)容易,且重播文件小,因为只需要保存每个帧的操作状态即可;网络逻辑性能优化较难,因为客户端需要运算所有的逻辑;当具有大量网络实体时,流量问题不大,因为其网络流量取决于客户端的数目,网络实体的增加对流量没有影响;当有大量网络实体时性能较差,因为客户端要运算大量的数据;对于外挂难以抵抗,因为客户端拥有全部的信息,尤其是透视挂会比较严重;平时开发很高效,但是需要保证确定性,不能在后期出现不同步bug;较难使用第三方库,因为无法保证确定性。

 

状态同步:流量一般情况下较高;预表现较为容易,客户端进行预表现(客户端预测),客户端进行预测,服务端进行权威计算,客户端和服务器最终进行同步;确定性不严格,因为所有客户端都听从服务器的指令即可;对网络的适应能力较高,因为客户端预测较为容易实现;短线重连较为容易,因为只需要让服务器发送当前游戏状态即可;离线重播(播放录像文件)较易,但是重播文件大,因为需要保存大量的每一帧每个客户端的当前状态;网络逻辑性能优化较为容易,因为大部分逻辑是在服务端运算,分但大部分客户端的运算压力,并且服务器也可以帮助客户端进行可观察对象的剔除工作等,减小客户端压力;当有大量网络实体时,如果客户端能观察到的网络实体较少,比如吃鸡这种游戏,则问题不大,但是如果客户端观察到的实体很多,比如一些RTS游戏,则问题较大;当有大量网络实体时,如果客户端可以观察到的网络实体较少,则性能较好,否则较差;也会有透视挂,但是服务器会进行视野剔除,所以影响比较小;平时开发的效率一般,需要前后端联调,写代码时不需要保证确定性;较容易使用第三方库。

Rudp:

  1. 报文按顺序到达,即tcp流特性;
  2. 报文选择性可靠,即tcp ack特性,确保报文正确到达,可以选择是否重传未收到ack的报文异或是接收方发请求告诉发送方“我没收到请你再传一份”;
  3. 心跳,即测试连接存活;
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值