原标题:做个几万人一起玩的《荒野大镖客》有可能吗?
剥离设计和玩法,让我们从技术的角度解析这个问题。
多人游戏的规模,一直是个让人捉摸不透的问题。从 MUD 发展而来的 MMORPG,同时在线人数超过五位数的并不少见,但到了《方舟:生存进化》《ATLAS》和"吃鸡类"的作品中,服务器、或者说一个房间容纳的人数一般在 70 到 200 之间徘徊。
估计有不少玩家曾经幻想过,将《荒野大镖客:救赎2》这样细致入微的单人体验塑造成大型 MMO,上万名牛仔在西部世界里快意恩仇、何其壮观。但即使是技术力如此之强的 Rockstar,也只敢采取"32 人战局"的设计方式,并在删减了一些内容的情况下推出《荒野大镖客 Online》。
有时候,扩充多人游戏规模的瓶颈,还不单单只是愿不愿意花钱买服务器的问题。抛开设计、玩法上的考虑,许多开发团队面临着"想做大却没法做大"的技术窘境。《绝地求生》跟《堡垒之夜》将人数设置在 100,也未必全是讨个好彩头。你要说蓝洞和 Epic 想要致敬高见广春的小说《大逃杀》,那应该也是构思 42 人相互厮杀的世界。
巧的是,今年我在 CJ 逛展时结识了田桑。他过去曾在 EA 负责线上游戏的功能设计,后来又任职英礴(Improbable)的游戏解决方案工程师,跟进过 5 个 MMO 项目,十分了解多人在线游戏的构造。我们从"吃鸡"的人数聊到《荒野大镖客:救赎2》的多人模式,于是就有了这篇科普。
为什么 MMORPG 能支持上万人
线上多人游戏的规模能到今天这个程度,肯定不是一蹴而就的。1996 年的 MUD《侠客行》最早是在大学里设置的服务器,当玩家规模增长到 1000 人同时在线时,其负载瞬间就被推到了极限。
同时期图形化的网游显得更加"寒碜",由于网络游戏的用户存在多个状态,如果说文字 MUD 仅仅是用一句话来描述,那图形化的状态可能要涉及到位置、动作、频率等诸多因素,每秒钟得同步非常多次,导致数据的容量特别大。因此号称领先于时代的《子午线59》,一个服务器能够容纳的人数也只不过 250 人。
当然,那个年代《子午线59》的同屏人数已经足够震撼了
《网络创世纪》的制作团队当时没少为用户规模这事操心,在 Alpha 测试的时候他们就觉得 250 人离"大型多人互动"的概念还有些距离,于是 Beta测试前是又是买硬件又是研究新技术。到了 1997 年,这群人在 BUG 一堆的情况下硬是把能够同时容纳的并发人数怼到 3000,导致后来不少漏洞被玩家利用。
在田桑看来,因为 90 年代是个快速发展的时代,他理解的早期用户规模扩容偏向堆带宽和硬件。只不过现在成本的越来越高,采取这种方法的代价太大,一个侧面现象就是 CPU 的主频很多年来没有太大提升。而从技术的角度来说,传统 MMORPG 使用的架构是 C/S(服务器-客户机),作为一个被应用了 10 多年的架构,广泛存在于《Runescape》《魔兽世界》等作品的设计中,它可以说是网络游戏支持上万人同时在线的基础。
从名字就能看出来,C/S 最早是两层结构,客户机也就是玩家电脑(主机)负责渲染,服务器处理游戏逻辑。后来又加了一层"数据库",搭载了用于保存游戏结果的存储器,估计也不用做太多科普。
一个典型的 C/S 架构交互
为了保证用户的规模足够大,传统 MMORPG 在"保真度"上做了很多牺牲。所谓的保真度可以简单理解成游戏的细致程度,包括物理模拟,比如撞墙之后产生反作用力,或是像《半条命2》那样实打实的把罐子握在手里捡起来;也包括延迟和同步,比如动作游戏和 FPS 游戏对服务器帧率都有非常高的要求。
根据田桑的解释,传统 C/S 的客户端不做模拟,或者是比较轻量的模拟,它们把这些状态以比较低的频率发到服务器,对服务器的负载要求较低,因此就可以允许更多的玩家同时在线。
《黑色沙漠》在 MMORPG 里的保真度算是不错,但相比单人游戏还是差了一截
保真度的差异,我们甚至能从单机游戏和 MMO 的渲染逻辑中看出来。单机游戏的图像会尽可能从 GPU 中加载,理想状态下最好能做到不访问硬盘和主存。《超级马力欧兄弟》每个关卡中的方块、每个怪物出现的位置都是固定的,角色、敌人和场景在游戏启动时就渲染读取完毕,进而放到 GPU 内存中。
而 MMO 中更多引入了"其它玩家"的变量,加上其技能、特效、位置的无数种组合,基本无法提前确定要渲染的东西,因此只能动态的从主存和硬盘读取纹理等数据。客户端与服务器的交互最先只确定玩家位置,本地先进行轮廓渲染,再在保持帧率的前提下一点点把画面读出来,体验肯定要差一些。
突然冒出来这么多人,在线多人游戏的图像具有不可预测性
事实上,在牺牲了保真度的前提下,要保证用户的规模够大,尽可能降低服务器负载,C/S 架构仍然需要写一个极其复杂的后端。从《魔兽世界》的处理方式不难看出,那个年代暴雪工程师的天赋何其之高。
最常见的就是"空间分割法",即把游戏中的地理(地图)进行分割,逐一分配给不同的服务器进程或者设备。
空间分割法
一个变种是"空间复制法",即把世界复制很多份,每份单独塞到一个服务器;而为了解决玩家因刷宝、挑战高难度怪物而大量聚集起来的问题,他们又研究出"实例法",单以副本的方式为每波玩家提供极其有限的地区。
空间复制法
因此在田桑的眼中,基于 C/S 的 MMORPG 有着相当高的技术门槛:
"市场喜好抛开不说。MMORPG 的技术门槛就要比 DS 高。UE 的 DS 我个人觉得就是一个非常棒的产品,像做《方舟:生存进化》的,还有其它很多工作室,他们没有多少后端积累,就可以把游戏做到那个量级。"
而这里提到的 DS(Dedicated Server,专用服务器),不仅是当下很多主流在线多人游戏都会使用的技术,也恰好能够解答"为什么「吃鸡」的玩家得是 100 人"的问题(当然DS和C/S不是同一类概念)。
为什么一局吃鸡的玩家得是 100 人
首先得声明 100 人只是个数量级,并非锱铢必究的数字。
简单来说,DS 可以比喻成"房间制"。好比《绝地求生》《堡垒之夜》《战地5》和《我的世界》,一个服务器(独立主机)对应一个房间,然后这个房间大致能够容纳两位数到三位数的玩家。
目前市面上主流的游戏引擎,如虚幻和 Unity 为线上多人游戏提供的解决方案都是 DS。这是一种能最大限度提高网游保真度的架构,它最早的目的就是为了解决 FPS 的同步问题,追求高精度、低延迟,涵盖客户端预测、服务器校验,延迟补偿等多种技术。
《GTA5》的战局也是一个 DS
田桑拿虚幻引擎举了个例子:"DS 结构下,引擎是带到服务器上运行的,客户端渲染相关的部分被剥离出来了,运行的是物理、AI 等纯逻辑。由于服务器能运行物理计算,所以联网游戏可以做到物理的同步,就可以实现很真实的游戏体验。"
在虚幻引擎的 DS 下,服务器便承担了计算碰撞同步的任务,例如判定武器有没有命中,环境爆炸产生的碎片轨迹这些东西。而且角色的 AI 行为树同步也依赖 DS,所以服务器会高频率地处理状态,负载非常大。这导致 DS 架构虽然有着支持高保真度游戏的优点,同样也具备高消耗、低承载的缺点。
一个典型例子是《光环5》的战区模式。这个用到 DS 架构的模式,支持的最大玩家数是 24 人,而且对于 AI、载体和目标的数量都有相应限制,原因正是要确保不会超过服务器的承载量。为此开发团队简化了 AI 逻辑,因此在战区模式下 NPC 会显得比战役中的要"蠢"。
如果延续 C/S 架构下的扩容思路,玩家们可能会感到困惑 —— 一台服务器负载太高,你加几台服务器不就完事了么?
然而,DS 架构在这一点上还受限于游戏引擎:
"虚幻引擎的主要逻辑是单线程运行,如果把服务器的主频性能,比如从 16 核变成 32 核,能够负载的人数其实是不能增加的。而且就算从一台机器增加到两台机器,可容纳的玩家数量也不会变化,因为有一个技术架构的限制……至于增加核心数有没有用,这个还要看引擎本身是否支持多线程扩展。"
Epic 有一段时间为了《堡垒之夜》能支持 100 人共斗绞尽脑汁,对虚幻引擎做了不少优化。比如在跳伞降落的过程中,主动降低远程调用所需要的带宽;又比如限制客户端向服务器发送移动更新的频率,避免因为客户端帧率过高,最终导致服务器过度负载。
Epic 曾提到过一个观点,既然一家公司都要做大型 MMO 了,那肯定有自己独特的要求和后端解决方案,依样画葫芦地照搬他们的 DS 不太适合,虚幻本身去研究扩容的事情可能会比较鸡肋,鼓励开发者基于这项技术自己想办法。
而主要逻辑是单线程运行的 Unity,其实或多或少也和虚幻引擎一样需要面临同样的问题。
做个几万人的《荒野大镖客》有没有可能
从上面两个部分的论述来看,不难发现如今线上多人游戏面临一个两难的局面。要么就沿用传统 C/S,自己写后端,以降低保真度为代价追求规模;要么就拿 DS 架构办事,缩小规模,提高保真度。
但有没有办法将它们融合起来呢?其实很多开发团队都在思考这个问题。
市面上有着这样特性的产品不多,"褒贬不一"的海盗冒险多人游戏《ATLAS》勉强算一个。抛开产品品质的问题,《ATLAS》用的就是 DS 架构,而且"理论上"支持 40000 名玩家同时游玩。
《ATLAS》
他们的做法,是在 DS 外自己写了世界服务器和数据服务器的后端。先把多个 DS 实例给拼起来,再由世界服务器统一负责管理 —— 比如只要玩家过地图,就把玩家的数据搬到另一台服务器。其实可以类比成《魔兽世界》的"空间分割法",当然明显能够看出技术不怎么成熟,Steam 上负面评价最多的地方就是"卡"和"连不上"。
英礴本来也打算打造一个庞大的、高保真度的游戏世界,结果发现技术方面都是坑。于是干脆先把 DS 的问题捋清,降低日后游戏制作的门槛和风险,因此催生出了一个解决方案(工具):SpatialOS。
SpatialOS 是一个基于底层公有云资源的游戏开发环境。它一方面会给你提供云端的服务器托管,一方面给予技术支持,类似于一个多功能插件。这个工具可以很简单的接入虚幻和 Unity 引擎,甚至任何其他第三方引擎,它主要提供在 DS 架构下扩充多人游戏规模的手段。
其中一个扩容思路和《ATLAS》有点像,如果一个 DS 不够用,就把多个 DS 拼接起来统一管控。因为 SpatialOS 虚幻开发套件的方向就是走多进程,这样更容易利用多核甚至多机器的计算资源,可以突破传统 DS 的限制 —— 简而言之就是给游戏加服务器有用了。
上面这段话有点绕,直接看"把 DS 拼起来"的示例图更加直观。下图中 9 个方块代表 9 个 DS,每个游戏服务器的管辖区域分别由不同颜色代表,玩家不仅可以无缝跨越服务器边界,也能和不同区域的其它玩家互动。
据田桑解释,这背后的秘密是 9 个 DS 之上有一个"网络层",它才真正负责所有游戏状态的管理。一个 DS 是一个区,通过这个管理层将所有区弥合起来。客户端连到这个管理层,而不是所有的 DS 之上。
利用多个游戏服务器来模拟游戏世界的不同区域
说到分层这个概念,SpatialOS 中还有项名为"AI 负载拆分"的功能,正好能解决前文《光环5》战区模式的问题。理论是,如果把 AI 的负载扔到另一个服务器,那不就为玩家扩容腾出空间了吗,而且还不必让 NPC 变"蠢",可谓一举两得。
这种方法可以采取的应用很广,对延迟要求不高,和核心系统(如物理)耦合度不高的东西都可以拆分出来,比如天气系统。分出来的层,则基于云放到另一台虚拟机上。
英礴本身做了一些实验,使用原生虚幻引擎的情况下,在已有 100 名玩家的基础上最多可以运行 229 个 AI;而将 AI 负载扔到另一个服务器后,维持相同服务器帧率的前提下 AI 数量可以达到 479 个,相当于扩容了一倍。
目前正在测试的冒险生存游戏《拾荒者》(Scavengers),刚好就采用了 AI 负载拆分的技术。开发商 Midwinter Entertainment 表示玩家会在游戏中遭遇极端天气、怪物肆虐,外来入侵者以及敌对玩家团队等各方面的威胁。而 AI 负载拆分使得他们在 3x3 公里的地图内,一方面保证了这些高保真度的体验,一方面又实现了"60 名玩家+300 个 AI"的规模。
当然,尽管分层看起来很牛逼,但银弹却是不存在的,田桑举了个例子:
"假设 A1 区域有 10000 人,负载不下了。那要么把 A1 切成 A1 和 A2,分别放 5000 人,也可能是在 A1 上面再加一层,这都是开发者自己去控制的。但是这个事情会带来成本,因为两个区间之间有大量通信,要靠服务器硬件来堆。
比如一个服务器要从 1000 人扩容到 3000 人,那就分三层……如果每层额外带来的性能损耗是 50%,每一层实际只能跑 500 人,三层只有 1500 人。那你又得多分几层,这时候的损耗可能又不止 50% 了。"
所以,要想在 DS 架构下把玩家的规模扩大,得综合多种方法。SpatialOS 实际上还有一套名为 QBI 的系统,可以自定义降低同步频率,解决一些网络负载的问题。比如其中一个表现就是令距离玩家较近的活动物体看起来更顺畅,越远"越卡",主要是看开发者如何发挥想象。
正如之前提到的技术限制,MMORPG 人数规模很大,可以达到几千上万人,但基本集中在社交、打怪,或者是副本的交互方式,很少见到有真实的物理模拟。另外一个方向是像《堡垒之夜》《方舟:生存进化》这样的游戏,它们有些地方做得很细致,但人数又容易碰到瓶颈,通常就是房间制的。
由此引申到能不能做"容纳几万人的《荒野大镖客:救赎2》"的问题,田桑认为理论上是可行的,只是还没有开发者触及到这根线。而且即使解决了技术问题后,话题就又回到了无法回避的开发风险和成本。
不过,未来这两种需求应该会交汇到一起,使得线上多人游戏在现今的标准上再进一步:一方面能支持更多玩家,一方面又能保证更真实的模拟。至少有人目前正在朝着这个方向努力,或许再过不久,有着高保真度的大型多人在线游戏就不再仅仅停留在幻想中。