网络游戏网络同步方案的选择

     随着电子竞技的快速发展和移动互联网的迅速崛起,手游的市场份额月来越高,不但各种原创的手游被开发者开发出来,甚至许多流行的端游也被开发者移植到手机上来,如今手游的类型多种多样,从单机到rpg,slg策略游戏,卡牌游戏弱交互游戏,以及rts,mmorpg,moba等重型多人在线游戏,其网络同步方案各有各的特点,到底如何选择游戏的同步方案呢?我们先来介绍一下常见的同步方案。

一.p2p模式

网络游戏网络同步方案的选择_第1张图片

    从字面上看面对面的模式,在同一场游戏中的所有玩家,需要和所有其他的所有玩家保持一个网络连接(如图),在游戏过程中一个玩家的操作需要转发给所有其他的玩家,然后其他玩家收到来自另一个玩家的消息后,根据预先规定好的规则来模拟游戏过程,从而来保证游戏的同步进行。这种模式的好处很明显,降低了主机的网络压力和延迟,并且可以在一个局域网内进行游戏,降低的了来自网络延时,但是由于所有的数据演算都在客户端因此容易作弊,除此之外随着玩家数量的增多,玩家需要保持的网络连接也会增多。

   在这种模式的 基础上有人做了一个折中的方案,一场游戏,由一个玩家创建房间,创建房间的玩家作为主机(即服务器),然后所有其他的玩家都和创建房间者相连,这种方案虽然降低了大部分玩家作弊的可能性,但是大大增加了主机的作弊可能性,并且正常游戏的体验完全由主机的网络质量决定,如果主机的网络延时很高就会走向一个极端(除了主机意外的所有玩家都会很卡),这种情况对于玩家来说明显是不公平的。

这种模式就好像一个玩家通过主机来控制其他玩家来保证游戏的同步进行,换句话说这种模式下控制权在玩家自己手里,也正是这个原因,作弊的可能性大大增加。

二 client-server模式

网络游戏网络同步方案的选择_第2张图片

在这种模式下,有两种同步模式,状态同步和帧同步。

    1.状态同步

    这种模式的运作过程和上面的方式有一个明显的区别,这种模式下是通过server来控制其他玩家,所有的控制权在server手中,server具有决策权,这种模式可以防止大部分的作弊行为,但是另外一个问题有产生了,这种模式下严重依赖server的稳定系性以及网络质量,如果server的网络质量不好所有的玩家都会很卡,甚至如果servr挂了,整个服的玩家都完蛋了。除此之外,server要负责所有玩家的数据处理和演算以及把一个玩家的操作数据转发给所有其他相关的玩家。因此这种模式给server带来了很大压力。

    当然这种模式只适合一些若交互的游戏,比如rpg,卡牌,slg类型的游戏,这些游戏共有的特点就是和服务器交互的频率不高,服务器手机所有玩家的操作信息,进行演算之后把演算结果转发给其他玩家,其他玩家做相应的模拟和显示。但是向moba,mmorpg,rts等大型的多人在线游戏中由于交互的频率极高,这种方案会造成明显的卡顿。

      2. 帧同步

    接着说,一般moba,rts等大型多人在线游戏,客户端每秒需要和服务器同步20-50次不等消息(wow,lol,守望先锋等),服务器集中处理来自客户端的上行消息,基本上每秒在20次左右,基本上会比客户端少一些,毕竟服务器需要负责所有玩家的操作。如果按着上面的模式来同步玩家的操作,试想一下,玩家一个操作从客户端到服务器来回的时间,再服务器演算的时间,也就是说在一个玩家进行一个操作上行到服务器之后在这段时间里什么都干不了,如果网络不好这段时间会明显变长。在这种情况下玩家就会有明显的卡顿,因此状态同步是不适合拿来做这种重型游戏的。

    什么是帧同步,顾名思义就是同步操作要以每帧来计算,不用想就知道同步的频率很高,举个例子在你打英雄联盟或者dota时,你点击鼠标的频率时多少,以及打团战时你释放技能的频率,服务器要以比你手速更快的频率来把你的这些操作同步给其他玩家,来保证所有玩家看到的游戏场景时一致的。

    为此,有一部分开发者为了降低服务器的延时,服务器只负责转发客户端上行的操作指令,并不做仲裁,把某个客户端上行的操作指令转发给其他相关的玩家后,让玩家自己根据这些指令来模拟游戏过程,这种模式有点像上面的第二种,只是转发的操作不是由某个玩家来做而是由服务器来进行。但是这种模式虽然降低来来自服务器器的延时,但是如果网络不好,还是会有延迟,并且容易作弊的缺点又一次出现(不过好像很多以前的老游戏都是这种模式)。有人为了解决这个问题就另外起一个服务器来专门做客户端指令的检测,以此检测客户端的作弊行为,但是我感觉这种亡羊补牢的模式并不是很好。

帧同步,这种模式下服务器每帧同步操作过程中,对所有来自客户端的操作信息进行演算和处理,结束后下发到所有玩家。唯一需要改变的客户端的行为,客户端在上行了自己的操作后,不必等到服务器仲裁结果的返回,也就是说客户端在上行消息之后,立即根据当前自己所掌握的游戏数据,模拟出一个游戏进行状态,不需要等到服务器的返回消息。但是操作的结果由服务器来决定。举个例子,玩家a在某时刻向玩家b开枪,玩家把此操作上行服务器器后立即进行弹道的模拟演算,根据当前掌握的b的位置信息和移动速度以及方向等详细信息来模拟操作的游戏过程,正常情况下客户端的演算结果和服务器的演算结果应该是不会有差别的,但是网络的延时存在,如果在快要打到b的时候,b躲开了,并且b上行了躲开的操作,但是由于网络的延时,你并没有收到来自服务器器b躲开的广播,因此你自己播放了打中的特效,并且自己也播了掉血的特效,但是这只是暂时的,因为你上行的操作,服务器也进行了演算,服务器判断b躲开了,所以等到下一帧的同步时,b的血又回来了。这种情况很长见,我们在打游戏的过程中经常会有自己从一个地方突然回到一个地方的情景,这中情况就是服务器判断你在某个时刻被眩晕了或者是被障碍物挡道了,但是你没有收到这些消息,自己的演算和服务器不一样,服务器把你强行拉回的结果。

     现在很多游戏都采用这种模式,守望先锋,还有手游皇室战争(又一次我在玩皇室战争我自己看到我把对面的塔打掉了,结果屏幕闪了一下,对面的塔忽然对了1000多点血,这就是对面的一些防御操作,由于网络的延时我没有及时收到,我自己演算了所有的游戏操作,但这些操作都是错误的,被服务器强行同步回来了。),还有守望先锋,这里给大家一个帖子,是守望先锋的程序员讲了他们是怎么做游戏同步的(建议电脑观看,里面有视频,手机看不了点击打开链接)。lol,dota这类游戏是怎么做网络同步的,我没有找到可靠的证据来证明它们的同步方案,但从理论上来说,他们比守望先锋的同步要求更为苛刻(它们有小兵,野怪,各种buff,这些数据是守望先锋没有的),所以我猜测它们既有可能也是这种模式,或者说是一台服务器转发指令,另外一台负责演算监测客户端的演算的正确性。

     当然这种模式下也会有延迟存在,因为一个指令发出到服务器,服务器广播给其他玩家这些需要一下最基本的网络传输时间,也就是说,一个玩家所看到的其他的玩家游戏状态其实是个过去是,只有自己的状态的最新的,比如你朝某个方向打b,其实此刻他已经不在那个位置了,你打的知识一个影子(照这样分析,我们是不是应该朝玩家移动靠前的位置一点打是不是更有可能打中),为了解决这个问题,服务器一般采用一种叫做柔和差值算法,就是服务器取样某一段时间的网络延时,把这段时间计算在内,也就是说你打了b,服务器会把b的时间倒回去一点来判断你是否打中。这样就保证了游戏的公平性,减小了由于网络延迟带来的误差。

    说了这么多,其实这些方案实现起来时非常困难的,没有一定的技术积累是很难去实现的,现在大多的游戏都是一些若交互的游戏,基本上是把数据库存进去,再拉出来,再加上一些游戏逻辑。一个有些经验的工程师都能完成,但是上面说的是需要我们去自习研究和斟酌的,否则就会出现每个同一场游戏的每个玩家看到不同的场景,即不同步的画面。

你可能感兴趣的:(架构设计)