郭智:穿越火线相关的游戏开发经验,值得一看

郭智:穿越火线相关的游戏开发经验,值得一看

郭智:大家好。 我是腾讯穿越火线项目组的郭智。 我先给大家做一下个人介绍。 我于2011年加入腾讯,现在是《穿越火线枪战》的主要程序员。 我还负责多个手机游戏客户端的开发。 我有十年的工作经验,曾从事过MMOG、FPS和手游。 玩过各种项目,有丰富的自研和一些商业引擎环节的经验。 今天我主要给大家分享一下穿越火线游戏中遇到的问题以及我们使用Unity进行技术的扩展。

我们先说一下整个项目的技术背景游戏运营,因为背景介绍是和我们开发过程中随着Unity版本的演进而发生的一些技术演进有关的。 大家可以看到,我们的项目实际上是在2015年3月就开始了技术预研,经过5个月的时间,我们在9月份进行了第一次外部测试。 经过两轮技术测试,11月经过三轮测试,2016年进入稳定运行期。2017年,我们看到了一个非常重要的版本的发布,就是生存训练模式,这是一些“现在非常流行的大世界里的“吃鸡”玩法。 纵观这三年,我们的技术演进其实总共经历了三个阶段。 主要的是2015年的研发时期,当时重点是Unity 4.6版本。 我们使用的是4.6版本。 当时移动设备、手机的发展刚刚快速发展,所以我们当时做的事情当时面临五个核心问题,也就是说我们解决了五个核心问题,一个是游戏架构,一个是反-作弊,加上网络同步弱,游戏手感,最后一个是图形和性能。 这是2015年初研发期间遇到的五个核心问题。

游戏开发流程图_游戏开发 流程_流程开发游戏的优缺点

到了2016年,我们实际上已经进入了多游戏运营时期。 2016年是整个稳定运行期。 我们尝试了十多种不同类型的游戏玩法。 每个月我们都会推出一些玩法供玩家尝试保持人气。 这些玩法也给我们带来了一些技术挑战。 比如我们有一些交叉火力塔防玩法,也有多人合作打Boss的玩法。 还会有一些像生化司令之类的放置控制玩法,不同的玩法给我们带来了不同的挑战。 2017年是整个开放世界技术爆发的一年,所以我们在2017年投入开放世界开发的时候,也遇到了一些问题。 最重要的四个问题是大世界和工具链的五个解决方案。 ,以及整个Unity引擎功能的扩展和合理利用,最后是大世界技术中比较重要的一些性能优化和适配。

前面我提到,我们面临的一个比较大的挑战是FPC游戏网络的建设。 这是业界的标杆架构。 我告诉大家,在研发期间,通过网络调研和现场测试,我们看到无线网络虽然时延不断逼近固网,但仍然存在抖动和丢包的情况。 在弱网络的情况下,这种情况下,如果直接应用目前一些客户端游戏的技术方案,流量和功耗会比较大,玩家体验也不会那么好。 所以你可以看到,网络弱的时候环境是这样分布的,现在我们玩家之间也是这样分布的。 所以我们的FPS游戏在这种弱网络条件下实现了实时战斗,强调竞技用户有良好的用户体验。

游戏开发 流程_游戏开发流程图_流程开发游戏的优缺点

我们先来看看传统的FPS游戏架构。 传统的FPS游戏架构是服务器不进行逻辑运算。 只转发一些战斗计算和移动计算数据验证响应,通过服务器直接转发一些移动和战斗计算。 该解决方案具有以下优点。 主要是服务器计算逻辑比较简单,性能会很高,其开发门槛会比较高。 比如客户端开发完成后,把DL放在服务器上就可以了。 但是,您也会遇到以下问题。 比如客户端的核心计算就会面临各种插件问题。 另外,服务器实际上也比较有限,无法完成各种复杂的任务。 游戏玩法容易受到移动网络的影响,弱网络情况下不流畅。 基于这些特点,我认为这种架构不太适合质量要求这么高的手游。 所以我当时就提出了我们CS的架构。 我们单独构建并实现了 BS 服务器并运行了完整的游戏逻辑。 这时,服务器和客户端就会运行,进行一致的运动和逻辑计算,然后按照一定的帧率将数据同步到客户端。 这样可以做到高强度的反作弊,在弱网络下做出更多的决策。 这样我们就可以实现更好的同步,那么用户体验就会更好。 所以你可以看到我们有三大优势:一是高强度的反黑客。 我们会弥补薄弱的网络并做好同步工作。 接下来我们会做各种客户端和服务器延迟补偿,以改善整个客户体验。 非常好。 但也有局限性,那就是开发效率会比之前的方案低一些,但也只有这个方案才能带我们走得更远。 这是2015年投资的整个项目。

这个计划从2015年到2018年一直在不断演变。看一下我们的整体架构是什么样的。 其实我们2015年搭建的框架就是基于CS的架构图。 首先我们的底层是Unity。 Unity封装了物理引擎等一系列解决方案。 同时我们的服务器,首先我们的服务器也运行着一个完整的物理机,它是开源的,是在服务器上编译的。 数据层编写了相应的导出工具,导出碰撞模型和关卡数据供服务器使用并保证一致性。 逻辑层,客户端采用Sesharp编写游戏开发 流程,服务端采用C++高性能,保证关键数据一致。 客户端和服务器都将执行相同的移动计算。 服务器将在同一位置进行运动损伤计算,并通知客户端验证结果的性能。 同时,我们将我们的移动同步封装在上层逻辑同步之上。 基于这个架构,我们基本上可以覆盖业界所有的解决方案。

我们可以看到我们当时的视图,一个是客户端的语音视图,一个是服务端的物理视图,这是基于我们和Mina服务端引擎配合做的服务端视图。 可见,服务器始终是整体的权威,客户端是分终端。 这样可以防止很多插件的出现。 这是我们多年来对抗外挂的比较有力的手段。

基于这个架构,我想提一下,我们实际上在各种场合接触到各种同步方案。 然而,这些同步方案无论是用在导航预测算法还是阴影预测算法中,都会遇到各种问题。 在大世界里,我们遇到各种各样的挑战,比如高精度的物理同步,比如快速移动的汽车。 行业将遇到以下问题。 例如,当我们要实现数据同步时,你会发现车辆同步比较快,延迟比较高,而服务器运行帧率却低得多。 最大的服务器运行在30帧,这使得无法进行精确的物理计算。 人眼对于一些不规则的速度非常敏感,所以在参与不规则的物理操作时,人眼就会看出这是比较假的。 根据这个特征,我们可以看到,当车辆相撞时,业界已经不再制作手机游戏了。 这时,我们提出了Move Blending的解决方案。 核心是通过预测和碰撞模拟来做一定的相对混合。 例如,在正常的运动过程中,我们进入最左边的预测同步阶段。 到了这个阶段就彻底完成了。 服务器驱动导航预测算法并进行预测同步。 当预测到相应的碰撞时,我们采用物理模拟动态授权方案,将所有物理模拟授权分配给每个客户端,然后由客户端进行物理授权并进行自己的物理表演。 此时,客户可以做出准确的物理表征。 最后,在通过碰撞物理模拟阶段后,我们返回到最终的物理混合。 只有基于这种物理混合方法,我们才能做出一些复杂的物理表达和同步解决方案。 这是我们在2017年所做的相对技术演变。

游戏开发 流程_游戏开发流程图_流程开发游戏的优缺点

讲完了整个网络架构,其实我们还是会面临一些挑战,比如基于当前一些硬件发展趋势的一些高性能并行架构。 CF手游销售就是如此,在小场景下精准。 同步,比如可以进行10V10的团队爆破,最多不超过20、30人。 因为是竞技性的,所以要求我在同步的时候要准确的同步大家的行为。 我可以给选手更好的体验,能够完成整个比赛。 当时的变革需求是这样的。 到了2016年,就变成了这样的场景。 变成了同屏大量战斗的小场景。 曾经有一个场景,打50个boss,60个怪物。 到了2017年,就变成了这样,一个非常大的世界,战斗复杂度很高,每个区域有500个关卡元素,3000多张渲染图等等,所有复杂、高级的东西都在大世界里实现。 同时,手机的计算能力也非常有限。 因为CF手游一直给人的印象就是性能非常好,像小米1这样的手机都可以运行。 所以当时定义大世界的规划需要有百元机跑三帧的基调。 同时,也需要充实的元素和优秀的画质。 接下来,我们还需要关心功耗。 即使有这么高的要求和图片所需的计算量,我们仍然可能Farpass。 我们是如何解决的? 这一解决方案也经历了三个技术演进阶段。 第一阶段提出了高性能并行架构,主要处理多调度和并行化,以及性能和功耗平衡。 那么适配一定是最优的,适配跨平台、跨厂商、跨芯片。 适应。 第二阶段,我们将基于整个高性能并行的基础来管理和消除大世界。 换句话说,我们需要对管道进行更多的优化。 比如当时我们提出了一个在行业内处于最顶尖的看得见的淘汰方案,我们用这个方案来管理大世界。 有了以上两个基础,我们将继续扩展引擎,优化整个技术的整体性能。 为什么要做并行解决方案? 芯片包含大盒子和小盒子。 这就是HMP的架构。 对于老芯片来说,它们实际上是SMP架构,即双大盒或四大盒架构。 您可以看到无模式架构的特点。 如图所示,可以得出以下结论: 不同的核心具有不同的内部消耗,支持不同的计算能力。 计算能力越强,功耗越高。 另外,当计算量达到高频时,功耗达到90%时就会出现帧抖动现象。 因此,采取合理选择功耗核心、减少大核心的策略。 基于整个Unity机制,我们封装了整个引擎flg的调度层。 基于此,我们封装了我们整个并行引擎的管道,然后基于这个管道来做我们所有的并行任务,比如Gameplay并行任务等等。 稍后,我将在以下情况下实际介绍这些并行任务是如何运行的。

有了并行架构,我们有很多优化创作人,我们将进入第二阶段,这是开放大世界技术的一些实现。 您可以看到开放世界实施中的典型场景。 在这个典型位置中,您可以看到该位置有 600,000 个面孔、700 个 DrawCall 以及 15+ 人和车辆。 这个时候主流的这种渲染级别的机型,比如小米4,如果不经过任何优化直接渲染的话只能跑到15以下,所以我们需要对其进行优化。 我们首先想到的就是在大世界中被淘汰。 因此,我们必须有一个合理的消除方案,包括遮挡消除。 合理是指基于Unity构建最合理、业界领先的遮挡消除系统。 因此,当时就提出了CF可见性消除方案。 首先,回到刚才的游戏世界,将游戏世界分成两个世界。 一是不变的部分,称为静态世界。 动态世界是变化的部分,即人、车、特效、UI是变化的部分。 静态部分仅在世界框架开始时保持不变。 例如,当决定渲染哪些场景时,这些永远不会改变,只会受到相机移动的影响。

游戏开发流程图_流程开发游戏的优缺点_游戏开发 流程

主要核心原则是我需要一个单独的线程来进行可见性检测。 对于静态部分,我放弃了静态数据,使用静态数据进行软件光栅化以获得深度结果。 查询深度结果驱动渲染。 我们可以看到中间的线程使用软件光栅化来获取剔除结果来决定哪些应该渲染,哪些不应该渲染。 如图所示,可以看到这个pipeline中有两个非常重要的实现,一个是数据提取,另一个是运行时,也就是软件光栅化。

先说一下我们的离线数据提取。 该算法包含业界多篇论文。 我们首先得到原始模型,然后简化这个模型的集合,然后得到每个模型中有哪些共面三角形。 然后为了简化平面空间,我把对应的共面三角形简化到平面空间中,最后得到了平面空间简化的结果,然后切入到视图中,然后基于像素范式,即光栅化像素来提取轮廓进行简化,最终得到一个最优的集成集。 回到世界空间,你可以得到一些计算超级快、数据表达超级简单、并且可以通过软件快速栅格化的数据。 提取后,389 张面孔变成了 72 张面孔。 可以看到制作的两张地图,沙漠地图和绿色地图,基本上都是27%和24%的数据。 整体算法就是选择合理的图形算法,在各个维度上最大限度地简化模型。 行业算法的另一个优点是,行业的简化算法只能提取无法进入的建筑物,导致一些计算不准确。 如图所示,即使只有一处差距,我们也要保证他有准确的结果。 这样我们就可以保证我们APS的公平性,在切割的时候不可能漏掉这个人。

总结一下我们的可构建性剔除解决方案,小场景也会被Unity剔除。 Big World 使用自己的淘汰方案。 消除方案实际上是一个可构建的消除方案,它是一个纯CPU的解决方案。 它适用于所有移动硬件。 它可以很好地进行引擎集成,并行化和优化引擎。 其实就像我们基于Unity做一些作业系统优化一样。 内部还有共线消除包,实现最佳的LD管理。 同时,它的运行速度非常快,并获得最优的消除结果。 同时它可以自动生成一些Occuders,优化一些艺术家的作品。

流程开发游戏的优缺点_游戏开发 流程_游戏开发流程图

在软件光栅化和消除之后,你仍然会面临一些问题。 比如你会发现drawcall还是很高。 为了质量,艺术会增加资源,复杂度高,必须控制装载距离和不同倍率要求的动态控制:高、中、低配置。 硬件运行流畅。 首先,需要有一个整体的空间管理计划。 基于这个管理方案,我们首先优化相应的资源,提取利润最高的LD集。 LD 集取代了单个对象 LD。 执行之后我们会标准化表现,使用标准化算法,调整策略。 例如,我们会执行严格的预算,我们会考虑每个场景中的一些性能损失及其性能参数。 它是什么样的,是否满足性能规范,是否做了高层规划算法。 我们会做自动化测试、专业测试和报告监控。 今天,基于这条管道的不断迭代和轮换训练,我们可以得到最合理的场景。

让我详细解释一下我们如何进行空间管理。 因为在手游中,空间划分可以分为物理层、细节层等,每一层可以独立定义每个Care的强度,比如它的加载距离是50×50还是100×100,以及它的高度。 三维高度必须以100米为单位进行划分,如高度为100×100×100。 将距离分组,如图所示。 绿色是物理层,黄色是环境层,也就是我们的建筑,蓝色是细节中的小物体和细节。 每层都可以独立执行一些相关方面的操作。 定义,然后管理,最后在这个级别上很好地划分空间。

然后做距离分组,这实际上就是整个距离资源优化的过程。 其实整个过程就是我们选择LD距离处的集合进行合并,然后预先计算它的收益比例。 换句话说,我们在这些距离上执行马赫数后,得失是多少。 最后,根据我们计算出的每项收入的损失,我们需要用一个算法来弄清楚如何用LD来设定最优的收入比例。 你可以看到,比如我们是否要在不同的Teles中组合这两个对象,可以根据刚才提到的预算分数来衡量。 如果分数比较高,比较合理,那就合并起来。 如果结合起来,虽然DrawCall面数少,但是收入低,所以不太适合。 总是通过这些计算提出合理的大世界预算管理。 一旦有了这套,就可以远距离实施LD替换策略,并且在不久的将来就可以看到模型的LD切换。 在更远的距离,我们将使用刚刚合并的替换模型。 在最远的距离,我们实际上会用不同的LD级别替换不同的模型,这样我们的整体损失就可以最小化。 这个核心原则意味着我离地方越近,使用的模型就越精简; 距离越远的地方,不同的LD就会使用我们的距离优化模型,从而得到最合理的资源优化。 这个过程需要不断的测试和调试,不断调整策略,以在不同的平台上达到最佳的性能。

你可以看到下面的图片。 这张图的意思是,在离线烘焙阶段,我们会计算每张图的角点看到的三角形,看到的面数,看到的数据,就可以计算出每一个三角形。 将盈亏比一并进行游戏开发 流程,然后进行线下规划。 使用我们的离线规划算法进行离线规划,然后合并其资源。 最后最核心的一点就是我们要保证每个位置的表现都是完全可控的。 在完全可控地形的基础上,我们用相对LD代替一些可控结果。

基于对这个开放世界的管理,我们实际上已经进入了我们技术进化的第三阶段,这是非常重要的。 其实随着Unity引擎的使用,Unity引擎的一个非常大的理念就是让它成为我们自己手中的引擎。 事实上,我们的团队自成立以来多年来一直在不断发展。 我们想要成为国内顶尖的游戏设计团队,所以我们会不断对整个引擎进行扩展和性能调优。 我做了以下事情。 这是我们的整体架构图。 可以看到层次感非常合理、严谨。 首先,最底层是平台独立层。 下面我们封装了 UDP 的整个网络层。 刚才提到的网络同步方案就是基于这个UDP网络层来进行网络同步的。 同时其实我们也会基于Unity自己的多线程方案来封装自己的多线程角度库,封装自己的多线程调优库。 我们还将封装我们的数学库和指令库。 我还将连接到一些控制器和平台。 这是我们的平台层。

现在是Unity,我们的CF手游是高性能做的。 基于各种底层渲染优化,大世界里的植被系统的渲染应该怎么做,Inpost的LD怎么做,多线程的Package怎么做,还有我刚才提到的整个大世界的管理方案,以及整个系统解决方案,而骨骼动画则可以进行GPU Skin等操作。 同时我们也对其整个物理算法进行了封装,保证两台服务器上的一致性。

基于这个技术引擎层,我们可以推出我们的GamePlay工作架构流程,比如我们的工作逻辑是什么,我们的前后端交互框架是什么,加上大世界的管理等等都在上面在此之上。 我们将基于这个工作流程进行开发。 我们开发了50多种游戏模式、100多个关卡、500多种枪支以及各种角色载具。 任何需求都是我们团队非常关心的。 没问题。 其实我们只需要和Unity引擎厂商合作,做成我们自己的引擎就可以了。 我们还将提出一些我们自己的创新和突破性项目。

我们为我在介绍中提到的 PPS 数学和物理库制作了某些软件包。 例如,我们提出了业界最快、最适合移动射击游戏的数学物理库。 我们实际上是基于Unity引擎数据库进行封装的。 例如,我们可以检测PPS,对于球和胶囊的算法是最优的。 一个可以重新定义射击者物理原理的模型。 然后我们重新定义了移动射击游戏中的一些基准和手感,比如支持数百种枪械射击手感的数据模型。 您还可以定义标准。 我们很多手机射击游戏实际上是性能和手机的基石,实际上已经成为整个行业的标杆。 同时,我们的形象印象不断扩大,同时保证高、中、低配置的效果都是最优的。 你可以看到我们的屏幕非常高清。 你可能还是分不清哪个是高端,哪个是中端,哪个是低端。 通过不断的图形优化,我们的品质永远是最好的。

有了图形之后,我们会继续优化情况。 我们目前是基于Unity来做这件事,我们已经适配了市面上98%的机器。 数百种 Android 模式旨在稳定在 45 帧。 在我们的生存模式下,平均帧率为 29 帧。 数百种模式,帧速率高达 50。我们可以集成一些电源策略盒,现在集成整个 Vetext 性能测试。 还有一些调整来支持它。 因此,我们始终确保性能最佳。

基于此,我们今天可能会实际分享这些,大家也可以据此与我们进行交流。

问题:我们如何制作自己的引擎,以及我们对 Unity 的依赖是什么?

郭智:我自己用过很多引擎。 我感觉Unity本身可以帮你解决很多问题,可以封装业界做出的技术方案。 基于这个非常完整的技术解决方案,我们将扩展引擎并开发您需要的功能。 为什么还需要自己开发引擎,重新发明轮子? 如果您认为想要实现您在不同场景中使用的技术解决方案,您可以自己实现。

问:这项技术是基于客户端的吗? 这是纯粹的客户端业务吗? 或者我们应该先在服务器上捕获一些,然后在本地进行遮挡消除。

郭智:这个方案最艺术的场景资源就是他所有的3D模型对应的遮挡数据的提取。 提取数据后,使用软件对其进行栅格化并创建遮挡和消除的结果。 至于这个结果,其实可以用在客户端,也可以用在服务端,不过现在主要用在客户端。

问题:如果在服务器上计算物理,会存在延迟问题,在客户端会存在作弊问题。 所以我想问一下什么是物理混合? 服务器计算结果然后客户端拟合吗?

郭智:其实物理混合是一个非常关键的问题。 仅靠服务器的计算精度是无法实现如此高精度的物理同步的,因此我们依靠将动态授权分发到各个客户端进行相关计算。 计算完成后,服务器端也在同时进行计算。 在这么短的时间内,例如2-3秒内,就可以在一定程度上表达碰撞结果。 这样,物理性能最终与服务器最终计算出的权威结果混合在一起,这样我们就可以实现如此高精度的物理同步。 所以在这个阶段,你面临的作弊可能会持续2-3秒。 如果用了这2-3秒,那么我们现在实际上已经在服务器上完成了计算。 我们可以通过方差或者平均差等数据来判断一些方法,进而达到预防的目的。

问:因为我们都知道物理引擎不稳定,不可能在不同平台、不同设备上运行同样完整的性能。 也就是说,我们现在的实验方法就是用服务器来产生最终的结果,然后不同的客户端进行不同的表现,但是最终能拟合服务器的结果就足够了吗?

郭智:对,最后的准确计算就是这个时候。

问:你是基于状态同步,现在感觉和帧同步差不多。 这里有一个清晰的界面吗,还是你独立创建了一个,结合了两者的优点?

郭智:我们有CS架构,这个不是帧同步。 帧的概念从来就不是向服务器发送相关操作,但现在不是这样了。 所以我们还是纯CS架构的状态同步机制。 就说高精度,刚才你看到的同步,一些计算结果给客户端来做一定的模拟。

问题:问一个关于离线同步原理的问题。

郭智:最极端的场景,比如说60万个三角形,你做任何优化都是需要时间的,可能是50毫秒到几百毫秒。 因此,第一阶段,你需要简化相对的数学模型,也就是简化你需要的三角形。 转换为您需要的轮廓表达式。 至于最终的表现形式,我这里不便透露。

问:这个离线遮挡数据是提前生成的吗?

郭智:线下有几个。 一是静态对象生成后提取。 对于动态物体,动态地将它们添加到我维护的一个遮挡中,这是一个遮挡消除事件。

问:这个数据,如果从不同的角度遮挡,数据会不一样。

郭志:这是一个纯粹的三维世界,所以是一模一样的。 因为提取的是正常的三维世界,所以最终在不同的视角下,一个摄像头就能得到你视角的结果,这和Nbla的方案是不同的。

问:关于反作弊的问题,比如客户把模型材质透明了。 如何解决视角问题?

郭智:透视插件最合理的解决方案是在服务器上进行关联检测。 相关性检测有几个维度:一是基于空间管理。 例如,如果此人在该位置无法看到该空间中的角色,则不应同步。 Second, based on the client dimension, it is like the occlusion culling just mentioned. The culling results are not actually sent to the renderer, so the renderer cannot change it.

流程开发游戏的优缺点_游戏开发 流程_游戏开发流程图

文章来源:http://mp.weixin.qq.com/s?src=11×tamp=1699351726&ver=4882&signature=ud6Ue901Q*oe1T8jD8JxZP*O3ZbG-o665h7TgABbHkaX25N2GNlkxwIZ-mK2AJBnPJCHdtMQV7OFURymnG8DiRoISd4ch7UXVDpGlHlKP17Mn78J0D8ids9OgRY4thbQ&new=1