Grid Online将是一款大型多人游戏,并且需要一些可靠的网络代码来实现后端和世界同步。 我们使用Unity3d作为我们的游戏引擎,其中包含一种联网和多人代码形式。 试图从Unity现有的网络代码中构建MMO架构非常困难(如果不是不可能的话),尤其是在需要大量规模的项目中。 我已经在可用的顶级工具上开发了自己的协议层,这为我们提供了一些有趣的可能性。

通讯层
我很快意识到,Unity无法满足我们的需求。 我们需要一种多场景方法,其中可以同时运行任意数量的场景。 我尝试了各种方法,其中尝试在摄像机范围之外的单个场景中运行分散的多个场景。 问题在于它的扩展性不是很好,我不认为Unity可以同时处理这么多玩家。
这需要一种不同的方法,经过大量的思考,我提出了以下关于如何实现大规模多人游戏技术的方法。 网络体系结构将由三个主要组件构成:
- 主服务器
- 从服务器
- 游戏客户端
从服务器
从服务器代表我们世界中的一个区域,并负责本地世界(区域)同步并处理当前在该区域中的玩家。 网络代码的这一部分正在使用Unity的网络代码,据我目前所知,它可以处理所有播放器和对象同步。 如果事实证明缺少Unity的网络代码,我将编写自己的网络同步代码,并将Unity用作呈现引擎。 从服务器一直与主服务器保持通信,并确保它可以根据需要将授权传递给另一个从服务器(例如,当玩家移至另一个区域时)。
主服务器
主服务器负责管理播放器授权和从属管理。 由于每个奴隶代表一个本地区域,因此它必须知道何时创建新区域以及何时将玩家转移到另一个奴隶。 主服务器可以根据要求动态创建新的从服务器。 例如,如果玩家A移至X区域,但X尚未运行,则它可以产生一个新实例,等待从属服务器变为可用并通知玩家新的从属服务器。
使用主从方法,实现负载平衡相对容易。 如果一个从属服务器变得过多,则主服务器可以轻松地决定将某些播放器(或移动到拥挤区域的播放器)卸载到具有相同场景的新从属实例。 它甚至可以决定哪个玩家应该移到拥挤的人群中,哪个不应该移到人群中。 例如,同一团队中的玩家应始终位于同一从属实例上,而不应在多个实例之间划分; 或希望彼此交易的玩家,应始终将这些玩家移至同一奴隶实例。 如果需要的话,也许我们甚至会让玩家将自己逼到某个特定的实例。 我认为还有更多的游戏使用类似的方法来实现这种负载平衡。
游戏客户端
这是玩家将用来与游戏进行交互的客户端。 它包括使用Unity3d的渲染引擎和用于通信的网络核心组件。 游戏客户端还将允许玩家使用其现有角色之一进行身份验证,创建新角色并加入游戏。 在幕后,它将使用网格网络协议与主服务器和从服务器通信。
网格网络协议(GNP)
我已经在Unity的NetworkTransport之上开发了我们自己的网络协议,用于三个组件之间的通信。 它处理握手过程,在此过程中,对等方首先互相确认并确保他们说相同的网络语言(或方言); 例如网络版本号。 一旦两个对等方彼此确认,他们就准备开始交换消息。 通常,这从身份验证过程开始。 一旦游戏客户端连接到主服务器,它将验证输入的凭据,该凭据将由用户传递。 玩家的客户端将从主服务器检索角色列表,并可以选择其中一个角色在最近的已知位置生成。 所有这些消息传递都在后台发生,由Grid Networking Protocol处理。
GNP是基于消息的,自然是异步的。 它的创建方式很容易被其他进程使用。 系统是松散耦合的,这意味着您可以从系统的一部分创建新的通信通道,并侦听来自系统的另一部分的事件。 例如,考虑一个市场,玩家可以放置待售物品,而其他玩家可以直接出价或购买。 像这样的过程需要权威与客户之间进行一些集中处理,权威性和沟通。 主服务器可以充当中央权威机构,而客户可以发起交易,通信自然会通过GNP进行。
分享是关怀
我们为Grid Online开发的网络协议是作为独立程序包开发的,可以轻松集成到其他项目中。 将来我们有可能将其发布给公众,但我们还不确定。 我个人是开源软件的大力支持者,过去我已经发展了相当一部分的OSS,但是一旦到那儿,我们就必须愿意承担责任,并且必须处理这些问题,要求。 这很容易变成日常工作,目前我(我们)已经全力以赴开发游戏。 无论如何,该决定将是一个权衡的决定。