腾讯王者荣耀项目技术总监孙勋:游戏在引擎、整体网络同步方案上的转变

生成海报
「大众问答」管理员
阅读需:0

腾讯王者荣耀项目技术总监孙勋:游戏在引擎、整体网络同步方案上的转变

分享者:孙逊,腾讯王者荣耀项目技术总监。 2005年加入腾讯,一开始他不是游戏。 2007年之前,他一直在拍拍工作。 2007年加入成都卧龙工作室王者,现为天美L1工作室。曾参与过《QQ三国》、《封神记》、《霸王三国OL》,后来的《王者荣耀》,现为该游戏技术总监。

这支曾主导终端游戏时代RTS游戏《三国志》框架构建的技术团队,在转型为MOBA手游《王者荣耀》后,为游戏提供了巨大的支持,但过程并非一帆风顺。

在今年刚刚结束的腾讯TGDC上,《王者荣耀》技术总监孙迅在一次技术专场对游戏进行了技术评测,并阐述了游戏的引擎和整体网络上的尝试和变化架构和网络同步解决方案。

孙逊表示,目前的游戏服务器架构主要由“游戏大厅”和“PvP”两部分组成。在不断的探索中,后来在架构中加入了一个Proxy中继服务器,这也是这个服务器的主要部分。加入《王者荣耀》,解决了后来出现在“安卓和iOS”同一台服务器上的一系列问题。

此外,他还介绍了《王者荣耀》在网络协议和同步方案上的一些尝试,并重复了这些尝试的优缺点。

为大家解答为什么,游戏最终会舍弃《三国演义》中使用的TCP协议(传输控制协议)和Client-Server结构(C/S结构),转而使用UDP协议(用户数据报协议)和帧同步方案。

本文是腾讯王者荣耀项目技术总监孙迅带来的《王者荣耀技术架构》主题演讲内容汇编。我们将分几个部分介绍王者后端开发过程中的一些内容和思路:包括《王者荣耀》的背景介绍、后端架构、上线后的调整,以及网络同步解决方案和反作弊解决方案。

目前《王者荣耀》后端机器有4600多台,我们的产能也有一定的扩展,40000多道工序。

《王者荣耀》游戏背景

2012年,我们当时做的终端游戏《八三国OL》就是王者的前身。这款产品原本是一款RTS类游戏,后来我们改成了手游MOBA,后来又改成了手游MOBA,也就是现在的《王者荣耀》。

从2012年开始RTS游戏到2013年,从多控单元RTS游戏到MOBA游戏,到2014年开始手游MOBA的预研,然后到2015年2月我们投入了大量的人力(约100多人)投资开发《战争英雄》(《王者荣耀》的前身),时间不长。

《三国志》的玩法是玩家可以通过在战斗前安排部队形成自己的策略,通过控制多个单位,技能的释放和单位特性的释放形成对抗。

当我们第一次制作《霸王三国》时,客户端引擎是不真实的,但是当我们制作《王者荣耀》时,我们切换到了统一引擎。在开发的 3 到 4 个月内,产品本身没有代码级别。什么都用了《八三国》,所有的代码都需要重写。

《八三国OL》的一些启示

做终端游戏《三国志OL》的经验给我们带来了很多相应的启示,比如策划、流程以及整个团队对MOBA的理解。

当时我们在做端游《三国志》的时候,采用的是Client-Server模式,但实际上我们在过程中学习了帧同步的概念:比如当线断开连接,我们回到视野的处理。 .

传统方法是返回时发送当前镜像和其他后续下游通知信息。

这种方法有问题。如果添加其他的in-scene模块,则需要根据当前场景中包含的各种对象及其状态的各种信息,将这些东西打包发送。 ,在后续的开发和维护中会很麻烦。

我们的做法是缓存服务器发送的所有序列包并重新传输它们,以便让客户端执行快进性能。它的概念类似于帧同步。

另一点是保留设计灵活性。在最初的RTS中,每个玩家最多可以操作5-8个单位进行对抗。后来改成了MOBA游戏,只能操作一个英雄,每个英雄在各种场景下,我们自己的技术框架不需要做颠覆性的改变。

《王者荣耀》整体架构

目前,《王者荣耀》后端整体架构设计来源于产品需求。如果你玩过《王者荣耀》,你就会知道PvP对抗不是靠师服的。

微信1区的玩家可以和微信2区的玩家对战,甚至在iOS平台上也可以和Android平台的人对战。同时,一些公共区域也保留了划分的概念。例如,团队和排行榜基于“区域”。 “概念性。”区域是游戏中的一个数字,可以理解为玩家新创建的角色上的标识。

当我们第一次实现架构时,服务器相对简单。从原型来看,只保留了大厅和PvP服务器,两者是分开的。

PvP服务器使用类似的CGI调用,可以分配使用资源,用完后回收。它不负责其他事情。从大厅拿你需要的东西,用完后还给大厅,让大厅写回DB。

我们做了大厅和PvP的直连,后来把直连改为中间转发。在《王者荣耀》中我们称之为Proxy,相当于一个代理服务器,屏蔽了后端很多进程的分布细节。因为游戏本身机器多,进程多,路由规则不同。

某些排行榜或团队是通过逻辑区域的数量来确定使用哪台机器或多台机器进行处理的。一些消息被随机转发或多次广播。代理负责路由。之后又增加了房间服务器,负责《王者荣耀》中的匹配、排名等相关功能。

如何将实力相近的人组合在一起玩是房间匹配服务器的职责,所以会有与其他服务器团队匹配的团队。

最后我们在上面添加了一个Adapter,用于实现与已经部署的区域资源的跨服务器匹配。

游戏后端架构,除团队等服务器外,其他模块均可在线扩展,或在发现导致掉线的故障时自动屏蔽整个架构。

因为路由方式会限制例如zone 1、zone 2、zone 3到本机进行处理。如果发生故障,只会影响特定逻辑区域内玩家请求的处理,从而缩小故障范围。

目前《王者荣耀》中的机器数量可能每周都可以查到,至少有一台机器宕机。确保架构中的模块自动阻塞和在线扩展非常重要。

整体架构更像是MMO的三层架构。 MMO在腾讯具有典型的三层结构。大厅服务器会根据玩家所在区域登录特定区域的大厅服务器。

单个大厅进程可以承载20000人,单个PvP可以承载1.200万。社区登录微信专区1还是2是人物标志,标记在玩家身上。

《王者荣耀》目前在外网有四大版块,分别是安卓手Q、安卓微信、iOS手Q、iOS微信,还有抢先服务。

我们会采用程序切换的方式,在大版本发布前,优先更新第一台服务器。目前无法与官方服务器玩家匹配,因为他们的版本不一致。等全服发布和版本更新后,我们会开启开关,先发的玩家可以和官服玩家进行PvP对战。

此外,我们还有专门的体验服务器,专为规划和验证而设计。体验服务器保留了可能删除文件的操作,但这在正式环境中是绝对不允许的。

另外,之前的传统手游都是单人游戏,会兼容很多协议,客户端版本无法更新玩。但是《王者荣耀》的主要玩法是PvP,结合实现方式,不同版本的玩家无法匹配到一起,所以我们没有做多版本协议兼容。

上线后的调整

上线后,《王者荣耀》本身整体的后端架构并没有太大的变化,因为我们在做终端游戏的时候,对这个架构有了更清晰的认识,也知道哪里可能存在任何问题。所以整个结构已经比较稳定了。

但是我们做了相应的微调,我们做的最多的是网络本身的优化。 《王者荣耀》刚上线时,市场上对网络时效性要求高的实时PvP游戏相对较少。

我们在网络上做了各种尝试,比如CPU性能优化、延迟、丢包等。网络本身花费的时间最多。

架构的微调,就像刚才提到的传送模块,我们架构中有很多大厅机器,也有很多PvP机器。在架构中,我们不需要每个进程都知道详细信息。例如,大厅服务器不需要知道后面有多少房间服务器。你只需要知道后面有一个房间服务器,你就可以访问了。

Proxy 路由功能负责如何划分、均衡负载,以及如何屏蔽后端故障节点。由于大厅和PvP机器太多,我们使用Proxy将整个架构划分为相互没有交集的“分支”概念。每组Proxy只负责一部分大厅和PvP服务器。

这两种服务器在《王者荣耀》服务器中是最多的,但是除了后端通信之外,在代理之间建立了连接,减少了单个代理通道的数量,同时保持了整个服务器的通信结构。

代理适配器是在启动后添加的。最初,上线的区域只有移动Q、微信、安卓和iOS四个区域。最早的 Android 玩家无法用 iOS 破解。

一开始,Android 和 iOS 是因为某种原因分开的。我们之前假设先更新Android腾讯王者荣耀项目技术总监孙勋:游戏在引擎、整体网络同步方案上的转变,后更新iOS,以保持版本更新的稳定性。但是后来我们希望Android和iOS玩家因为关系链可以一起hack。

所以在Android和iOS版本更新频率相同的情况下,我们希望不需要部署太多额外的机器资源和开发,直接使用Android和iOS现有的PvP服务器和区域资源来获取通过 Android 和 iOS 的 PvP。

安卓玩家登录安卓专区后,会连接到安卓大厅。 iOS登录后,他们将连接到iOS区域的大厅。当他们需要开黑时,我们通过Adapter桥接中转模块的所有区域,并通过一定的算法传递到一定的区域。交付方式的选择直接关系到区域资源的比例。

网络同步计划

之前我们在做《三国志》的时候,采用的是Client-Server模式,服务器端来判断客户端的性能。那为什么我们在做《王者荣耀》的时候会选择帧同步方式呢?

客户端-服务器模型的优点是:

首先,安全。因为都是服务端计算,客户端只负责性能级别的功能,不会影响各种判断的结果。

另外,由于Client-Server模式是基于结果的,中间可以出现丢包,丢包可以接受处理,只要最终结果一致即可。

帧同步在最终游戏中被大量使用。大家耳熟能详的DotA和《星际争霸》都采用了帧同步技术。

帧同步本身对网络的要求比较严格。发出的执行序列不允许丢包。严格保证顺序。如果数据包是12345,则必须是12345。如果数据包丢失,则必须等到数据包丢失。到达后可依次执行。

MOBA 本身有很多单元。客户端在同一屏幕上有近100个单元。如果一个AOE技能打到20个单位然后种下debuff,Client-Server状态模式需要发送这些消息,可能潜在的同步状态信息比较大。

Client-Server 模型本身的另一种开发方式,更难确定客户端性能与服务器完美匹配。

之前我们在做终端游戏MOBA的时候,我们花了两三个星期的时间来培养一个英雄技能。 《王者荣耀》的开发周期当时是三、四个月。在这样的时间压力下,我们用Client-Server的方式处理不了,时间也不够用。

当时团队很紧张,因为当时市场上还没有强PvP和高时效的手游。

帧同步网络的抗抖动能力比较弱,因为不能丢包。帧同步的基本原理,有兴趣的可以自己下来学习一下。

一般都会有区别的,无论是网络模式还是主机模式。该技术的要点在于办公室中的计算是基于客户计算的。 10人中,每人计算一份。它们具有相同的起点、相同的输入和相同的中间计算逻辑。没有随机过程。计算结果在理论上应该是一致的。

即使是浮点运算也不应该存在,它有精度问题。包括大量的碰撞、动画和基本的数学运算库都是在后台实现的。需要去浮点整形,避免客户端的本地逻辑。这是最容易犯的错误。这是不同步的最常见原因。 .

如果一个没有经验的客户端程序不够用,在写程序的时候,用本地代码做相应的逻辑,可能会跑的越来越远,10个人都在平行世界。

整体网络结构大致分为三层:服务器层、客户端逻辑层、客户端表示层。

服务器主要负责两部分:

在《王者荣耀》中,我们的逻辑是在 66 毫秒时每秒同步 15 个数据包。这是必不可少的,因为帧同步不能丢包,数据包必须有严格的执行顺序。

客户端逻辑层理解为客户端的本地服务,即所有客户端操作的结果必须强一致,不能有真正的随机性,没有本地逻辑,也没有浮点运算。得到相同的输入,结果必须一致。

客户端表示层会根据逻辑层的数据进行复制或镜像,然后在表示层进行平滑处理。帧数不同,但不会影响最终的计算结果,只会影响动画和动作的表现。

PvP 首次上线时,我们使用了 TCP 技术。 TCP在局域网没有任何问题的情况下表现良好,但当外网出现丢包或抖动时,受限于实现方法。

比如windows,启动慢等各种原因,你会发现重连的时候游戏很卡,所以后来我们就没有用TCP,改成UDP了。如果发生丢包,服务器会在应用层重新发布。

UDP 受限于 MTU(最大传输单元)的大小。如果大于MTU,就会出现分包,整个包可能会丢失。

因此,我们也有一些比较大的包,会在App层被服务器分包。如果中间有丢包,服务器会补发。将碎片化的包组装成一个完整的包,然后解包。

更有价值的是UDP数据包。如果手机因为信号抖动等原因丢包,发送时使用冗余是更有效的解决方案。

帧同步消息比较小。按照每秒15个驱动帧的理论,20分钟的录制大约是10M。但据我们外网统计,正常的5V5游戏20分钟,视频大小在3M左右。

服务器会将玩家的操作存储为纯内存。当发生丢包时,服务器会根据编号快速找到缓存的信息并发送。同时,根据丢包情况,计算发送给此人的冗余变化量。

一开始,每个发送的数据包都会冗余前3帧的信息。如果丢包严重,我们会在发送之前尝试冗余发送更多信息。客户端拿到后,会尝试压缩逻辑执行过程。

帧同步比较麻烦的模式是它不像Client-Server模式那样进进出出。崩溃后,必须从头运行,中间的计算过程不能省略。

当然,我们也尝试了一些其他的方法。比如客户端上传后,服务端不需要定时采集下发,直接通过染帧号下发,响应更及时王者,操作反馈更强更快。

我们当时做出的结果是手感的提升微乎其微,但带来的负面问题却很大,因为不再是每秒15个包裹的固定递送,包裹数量发送的非常大。跟这个人的操作习惯有关系。

有可能一个人在一秒钟内生成十多个或二十多个输入,这些输入需要打包发送给客户端。由于客户端收到大量的包,设备显然会变热。

我们也和其他部门合作做类似TCP的技术。大家直觉上认为,如果数据包丢失,会在IO层重传。

但实际结果会发现,该技术是低级的,所以对丢包的控制不是那么灵活,可能的结果不如TCP本身。

传统的帧同步方式会延迟交付。我们也试过这个。如果间隔期间出现丢包,或者包下行时出现网络波动,可以通过延迟投递来平滑抖动和丢包。

我们尝试了这个解决方案,但最终没有这样做的原因是《王者荣耀》中的一些英雄感觉偏离了轨道,需要更快的响应。延迟发货虽然有很好的抗抖动和抗包能力,但是手感不符合我们的要求。

另外,在Client-Server方法的实现中,一般都会有一个例程,客户端提前执行,根据服务器的性能进行平滑或拉取。

我们也尝试过这个方案,但最终放弃了,因为这个技巧会让角色的表现有点不稳定。

当客户端在本地移动时,客户端的性能会立即跟进,但根据服务器的下行链路,实际上会进行一些偏移或更正。当网络抖动发生时,字符会漂移一点,所以我们放弃了这个解决方案。

在帧同步方案中,所有客户端都进行计算并期望产生一致的结果,但是如果一个错误或有人使用了修改器,结果就会与其他人不同。当出现差异时,我们说的是不同步。

我们会定期提取一些关键信息来制作哈希。不同步的人的哈希值会与其他人不同。

《王者荣耀》刚上线时的不同步率在2%左右,也就是说100款游戏中可能有2款是一人或多人,结果与其他。我们现在做到了万分之三的失步率,万分之三的游戏有这种情况。

这是如何改进的?如果使用帧同步,肯定会遇到不同步的问题。客户端写入错误并使用本地逻辑。可能浮点计算误差达到这样的临界点,会产生不一致的计算结果。

我们有很多方法:自动化测试,使用机器人连续运行,比如在新英雄之前,有脚本测试,连续运行,看看是否会出现不同步的结果;有特殊体验服务器和抢占服务区,发布到官网前先测试,先暴露问题,再解决问题。

另外,当它不同步时,我们会上传并保存整个记录和客户端之间的日志,以便我们可以根据记录和中间执行的日志序列快速定位问题所在.

我们还监控单轮的延迟和质量。有没有卡,有多少回合卡住,有没有丢包,丢多少包,最大时延多少,抖动最大,我们都有相应的记录和统计。

运营部的同学给了我们很多帮助。我们会整合相关SDK进行网速测试和问题分析。

根据我们自己的统计,游戏卡顿的原因主要有以下几个:

我们在网络优化方面做了很多尝试,比如基于丢包增加冗余,然后在各个方面优化我们的执行效率,以降低CPU使用率。

在《王者荣耀》的背景下,有两件事我们一直在努力,网络优化和匹配机制,我们尝试了各种方法,甚至以后会尝试使用AI深度学习方法。更准确地定位玩家的真实等级,让他可以匹配更真实的同等级对手和队友。

相关标签:
评论
  • 消灭零回复
热议问题
M61266+M37160M8组装机进入总线方法(常见的问题一定要知道) 1
春兰CL2101,CL2501总线进入方法(找对方法很重要) 1
东宝21寸彩电进入总线方法(操作方法其实不难) 1
假冒索尼、松下I2C彩电总线进入方法(对症下药维修其实很简单) 1
金星D2118彩电总线调整(找到问题很重要) 1
金星D2530A彩电总线进入方法(其实没有你想得那么严重) 1
熊猫2586彩电进入总线方法(故障维修介绍) 1
东杰ECSD21D19彩电总线调整方法(维修其实不难) 1
声宝SP53M、29HX8、29HX5、SP60机芯彩电总线(这个问题特别常见) 1
乐华RB25K9彩电进入总线方法(看完下面操作就可以学会了) 1
layui

微信扫码添加大众问答站长

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2466368147@qq.com 举报,一经查实,本站将立刻删除。