如何实现一个简单的网络帧同步方案

在网络游戏中,网络同步方案大概有下面三种:

  • 状态同步,即state synchronization
  • 快照同步,即 snapshot synchronization
  • 帧同步,即lock step synchronization

说帧同步,实际上这三种同步方案都是基于帧的同步,所以都可以说都是帧同步。但现在我们一般都把帧同步等同于lock step synchronization不知道是历史遗留问题呢,还是约定俗成的,就不得而知了。在这里我尝试介绍一个我了解到的一个简单帧同步方案。

客户端帧循环

在介绍方案之前,我们首先要了解网络游戏客户端是怎么运行的。可以简单的来说我们的客户端游戏逻辑运行在一个循环里,我们一般称它为帧循环。帧循环可以简单描述做了如下的事情:

  1. 采样玩家的输入数据(如鼠标,键盘,摇杆等状态)
  2. 将玩家输入数据组装数据包并通过网络调用发送给服务器
  3. 读取服务器从网络发过来的数据包,并调用相应的处理逻辑,更新游戏状态
  4. 根据当前的游戏状态渲染游戏场景

假如我们的客户端帧循环有这样一个特性:初始条件相同,输入也相同,最终得到的游戏状态那也一定相同的话(用英文表达就是客户端是deterministic的),那么我们就想在同步多个客户端的时候只要保证初始条件是相同的,那么只要把各个客户端的输入通过服务器发送给各个客户端就能达到游戏状态的最终同步了。这个就是所谓的帧同步了。其实,这里有一个隐含的条件:当一个客户端从服务器收到了另一个客户端的某个输入后,它要处理这个输入时,它当前的状态必须是这个输入发送时的状态。换句话说,这个时候要处理这个输入的客户端必须是已经把这个输入发送前收到的输入都执行完了。这个就是所谓的lockstep。我们总结一下网络帧同步的实现要做到以下两点:

  • 客户端的逻辑是deterministic
  • 客户端按lockstep的方式处理来自服务器的输入数据包

这个时候我们就只需要通过服务器同步各个客户端的输入就能达到游戏状态的最终同步。

帧号

为了客户端按lockstep的方式执行收到的输入,我们在客户端帧循环的第2步,即将玩家输入组装称数据包这一步,在数据包上加上一个帧号(即Sequence Number)。当收到数据包时,我们要对比当前客户端的帧号和数据包的帧号,只有二者是一样的情况下才会立即处理该数据包。

客户端如何发送帧数据

在这里我们约定客户端按每秒10帧的频率发送数据。客户端是发送帧数据的逻辑可以简单用以下的伪代码来表示:

SendFrameData</
  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值