最新最全手机游戏下载!
首页 游戏资讯 游戏资讯 王者框架|天游轮-《王者荣耀》群玩不掉帧不卡顿的结构方法及实现原理

王者框架|天游轮-《王者荣耀》群玩不掉帧不卡顿的结构方法及实现原理

时间: 来源:网络 编辑:2u手游网小编 浏览:101

自上线以来,《农药》凭借强大的产品实力和腾讯的运营能力,在游戏市场表现不俗。

根据第三方调研数据,《王者荣耀》渗透率达到22.3%,用户规模达到2.01亿,日均活跃用户(DAU)为5412.8万。 如此骄人的数据王者框架,令人非常钦佩。

当然,作为一个技术人,我更愿意从技术的角度去了解王者荣耀的一些实现原理和架构方法,从而发现新的知识领域,拓展自己的知识边界,丰富自己的专业技能。

在本文中,我们将谈谈王者荣耀的技术实现和同步方式,并从MOBA和多人在线战术竞技类游戏的角度分析王者荣耀的实现方案。

以下是主要讲解的要点:

服务器架构。

沟通方式。

同步方案。

技能同步。

断开并重新连接。

服务器架构

不难发现,王者荣耀的服务器采用的是房间模式。 每位玩家登录后进入大厅进行游戏匹配。 匹配完成后,将一起战斗的玩家放到一个房间里进行战斗。

房间类型的玩法与在线播放单元的不确定性和播放次数的不确定性很小,需要匹配一个房间服务器才能让少量的人进入一个服务器。

这类游戏最重要的是其“游戏厅”的承载能力。 每个“游戏厅”都有逻辑限制,需要维护和播放的玩家数据是有限的,但是“游戏厅”需要保持比较高的在线用户数,所以一般来说,这种游戏仍然需要“拆分服务器”。

“游戏厅”中最具挑战性的任务是将玩家“自动匹配”到一个“游戏室”中,这需要对所有在线玩家进行搜索和筛选,为了更好的体验,天游娱乐将进行分区匹配,以实现更快的同步.

一般的方法是玩家先登录“大厅服务器”,然后选择组队游戏的功能。 服务器会通知所有参与的游戏客户端与房间服务器建立新的连接,以便所有参与的用户都可以在房间服务器中进行游戏。 游戏是互动的。

沟通方式

说到通信方式,一般有http和两种方式,但是底层也用到了http,只是每次通信完成后就会断开连接。

这种方式对于需要频繁交互的双方来说效率太低,所以对实时性要求高的游戏一般都采用这种方式进行通信。

但是,通信分为两种类型:TCP 与 UDP。 具体使用哪种类型取决于游戏的类型。

以下是两种类型的优缺点:

从上面的对比中,我们会发现tcp已经为我们完成了我们想做的一切。 我们只需要建立链接,然后像文件一样读写即可。 而udp需要我们自己设计一切。

看到这一切,你可能首先会觉得用的是tcp而不是udp,那么真的是这样吗? 根据游戏的不同业务和场景,我可以明确的告诉大家,王者荣耀使用的是udp,包括腾讯大部分的长链接手游。 为什么是这样?

TCP以一定的代价保证数据的可靠性

TCP可以保证数据包的可靠性和顺序,全部给你打包。 tcp发送一个数据包,等待一段时间,直到检测到数据包丢失,如果没有收到它的ACK,则将丢失的数据包重新发送到目标计算机。

重复的数据包在接收端将被丢弃,乱序的数据包将被重新排序以保证数据包的可靠性和顺序。

但是为了保证可靠性和顺序,需要保证不管tcp是什么情况,只要数据包出错,就必须等待数据包的重发。

这是什么意思? 也就是说,即使最新的数据已经到达,这些数据包仍然无法访问。 新到达的数据会被放入队列中,需要等待丢失的数据包重新发送后才能访问所有数据。

这样如果网络环境太差或者不稳定,比如国内的移动网络,或者天佑遇到网络拥塞丢了一个数据包,一切都需要停下来等待数据包重发。

客户端会等待接收数据,播放器操作会卡顿,响应不及时。

udp的可靠性——DIY手工组装

由上可知,udp主要在可靠性方面不能保证数据包的顺序。 例如第100个收到的数据包不一定是第100个发送的数据包,不能保证不丢包。 一个数据包丢失了,udp 本身不会检查它。

如果这两个问题解决了,那么UDP的大部分可靠性问题也就迎刃而解了。

具体解决方案大致如下:

为每个数据包增加序号,每发送一个数据包增加本地序号。

每个数据包都添加了一个位字段以容纳多个确认。 确认字符的数量取决于应用程序的数据包发送速率。 速率越高,确认字符的数量越多。

每收到一个包裹,收到的包裹上的序列号就会变成确认字符,这些确认字符在寄出包裹时会带上。

如果从确认字符中发现数据包丢失,则由应用程序组成一个包含丢失数据的新数据包,并在必要时使用新的序列号发送它。

当多次收到相同的数据包时,它可以被丢弃。

同步方案

游戏中常见的同步方案有状态同步和帧同步。 一般大型的使用状态同步,比如魔兽世界。 状态同步采用C/S架构,所有状态由服务器控制,安全性相对较高,但流量较大。

[caption id="attachment_453880" align="aligncenter" width="500"]王者荣耀商业模式框架_王者框架_xposed框架和谷歌框架 王者荣耀商业模式框架_王者框架_xposed框架和谷歌框架[/caption]

帧同步采用囚徒模式,强制所有C端采用逻辑帧率,保证输出一致。 其特点是流量小,安全性相对较差。

王者荣耀使用的是帧同步,那么具体的帧同步是什么,又是如何实现的,我们从两个地方来分解:

帧率

什么是帧率? 没做过的同学可能对这个名词不是很清楚。 下面从天游娱乐的一个小例子来说明一下。

记得小时候有一种漫画书,我可以快速翻阅,看到漫画里的人物会动。

由于人眼特殊的生理结构,如果看到的画面帧率高于每秒10-12帧左右,就可以认为是连贯的。 这种现象称为视觉暂留。

这就是为什么电影胶片是一帧一帧地拍摄,然后快速播放的原因,就像上图中翻看漫画书一样。

游戏中的所有动画也是通过这种方式渲染的,但帧率由 GPU 控制。 你看到的图像是GPU逐帧渲染的,比如30帧/s。 所见画面越流畅,帧率越高,所见画面越流畅。

— 帧同步

帧同步可以说是通过帧率来扩展的。 你可以把一场比赛看成是一个巨大的状态机,所有的参与者都使用相同的逻辑帧率不断前进。

我们看下面两张图:

图为A、B、C三位玩家的时间轴,这个时间轴不是电脑上的本地时间,而是A、B、C三人在线时定义的时间轴。 虚线隔开的时间片称为turn,可以理解为一帧,箭头表示玩家将自己的操作指令广播给其他玩家。

我们把一个游戏看成一个大的状态机,因为大家都在玩同一个游戏,所以F是一样的,初始状态S0也是一样的。

在第一回合结束时,所有玩家都收到了完全相同的输入I,注意这里的I不是一个值,而是当前游戏中所有玩家的一组操作指令。

在时间t1王者框架,所有玩家的计算机自行计算结果。 由于F、S0和I是固定的,所以每个玩家电脑上计算出的下一个状态S1一定是相同的。

那么通过上面的介绍我们可以知道:

我们把游戏的进程分成一个帧。 这里的帧和游戏的渲染帧率不一样。 它只是借用了框架的概念。 自定义框架称为 turn。 游戏的过程是每一回合连续推进,每个玩家的回合以同样的速度前进。

在每一帧中,只有当服务器收集了所有玩家的操作指令,即输入确认后,才能计算并进入下一回合,否则等待最慢的玩家。 然后广播给所有玩家。 只有这样才能保证帧的一致性。

游戏严格按照回合进行。 如果有人延迟高,其他玩家必须等玩家追上后才能继续计算。 不存在某个玩家领先或落后其他玩家数回合的情况。 在使用同步机制的游戏中,每个玩家的延迟等于延迟最高的玩家。

由于每个人的轮次是一致的,输入是固定的,所以所有客户端在每一步的计算结果都是一致的。

我们来看看具体的执行过程:

在上图中,我们可以清楚的看到这个囚徒模式的帧同步,在第二帧,因为玩家1有延迟,导致第二帧的同步时间延迟,导致所有玩家等待,出现卡顿现象。

乐观锁&断线重连

囚徒模式的帧同步有一个致命的缺陷。 如果其中一个播放器连网速度慢,势必会影响其他播放器的体验,因为服务器要等到所有的输入都到达后,才能同步到所有的C端。

另外,如果中途有人掉线,游戏将无法继续或者掉线的玩家无法重新连接,因为在严格帧同步的情况下,中途加入游戏在技术上是非常困难的。

因为你重新进入后,你的初始状态和大家不一致,你的状态信息丢失了,比如你的等级,随机种子,人物属性信息等。

早期玩过冰封王座的用户都知道,一旦掉线,游戏基本就没戏了,需要重新来过。 至于为什么没有卡顿的现象,因为当时的解决方案是使用局域网的方式,所以基本上没有延迟的问题。

为了后期解决这个问题,现在包括王者荣耀,服务器会现场保存玩家游戏的游戏指令和状态信息,当玩家掉线重连时,可以返回到断线前的状态。

但是,这仍然不能解决帧同步的问题,因为严格的帧同步是要等到所有玩家都有输入,再通知广播更新。 如果A服务器还没有输入同步,大家就得等,那怎么解决呢? 这个问题?

采用“定时不等待”的乐观方式,在每次时钟到来时,将操作广播给所有用户,而不管每个玩家是否有操作更新。

具有这种帧速率的时钟由服务器控制。 当客户端有操作时,会及时发送给服务器,然后服务器会以每秒20-50次的频率向所有客户端发送更新消息,如下图所示:

在上图中,我们可以看到服务器不会等到所有用户输入都收集完了再进行下一帧,而是会以固定的频率将玩家的输入信息同步到各个C端。 如果有玩家的网络延迟,服务器的帧率会进不去等待。

比如上图,在第二帧,玩家A的网速慢,那么此时他就会被网速快的玩家给秒(其他游戏类似)。

但是网速慢的玩家不会卡在网速快的玩家身上,只会觉得自己的操作有延迟。

技能同步

游戏中有很多东西是和概率有关的。 比如技能的伤害有一定几率暴击伤害或者被折射击中。

根据帧同步,基于相同的输入,每个玩家的伤害是独立计算的,那么如何保证所有电脑的暴击伤害一致呢? 这个时候就需要用到伪随机了。

大多数编程语言内置库中的随机数都是由线性同余生成器生成的。 如果不指定随机种子(Seed),则默认使用当前系统时间戳作为随机种子。

一旦指定了随机种子,生成的随机数序列就具有确定性,也就是说两台计算机使用相同的随机种子,第N次随机的结果是一致的。

所以在游戏开始前,服务器会为每个玩家分配一个随机种子,然后进行同步,让每个玩家在计算每个角色的技能时都能保证伤害一致。 这也是大部分帧同步游戏采用的方案,包括王者荣耀。

更多此类文章请关注我的博客:天友注册-天友总代理注册平台登录获取最新资讯。

本文原文链接:天游论-《王者荣耀》无掉帧无卡顿结构及实现原理

相关攻略

猜你喜欢