首页 存档 技术 查看内容

如何设计一个千万人在线的MMO游戏? 如何设计一个性能可扩展的MMO(大型多人在线)游戏 ...

2018-3-30 13:00 |来自: 互联网 354 0

摘要: 如何设计一个性能可扩展的MMO(大型多人在线)游戏分布式系统是一件富有挑战性的任务,需要能够灵活有效地扩展分配计算资源,包括千万玩家在一个共享虚拟世界中彼此交互,实现身临其境的体验。游戏目标: 1.游戏同时会 ...

如何设计一个性能可扩展的MMO(大型多人在线)游戏分布式系统是一件富有挑战性的任务,需要能够灵活有效地扩展分配计算资源,包括千万玩家在一个共享虚拟世界中彼此交互,实现身临其境的体验。

游戏目标:


1.游戏同时会有很多在线玩家。


2.游戏侧重探寻 可玩很多游戏 玩家之间频繁互动。


3.游戏应该能够立即决定在某个指定地图上玩家的数量。


4.游戏设计可以指定使用短暂的地图,在小团体的球员中选择共享脚本经验。


5.游戏服务器使用分布式部署架构。


6.游戏服务器使用分布式网络连接模式来管理游戏客户端的连接。


7.支持横向扩展,通过增加服务器个数等资源方式提升服务器的负载能力。


8.有一个长期的产品计划:将不断向游戏中增加内容和扩大整个虚拟世界的规模大小。架构设计必须支持这种业务规模的扩展。


9.业务和运营计划将寻求不断扩充容量,通过增加服务器的方式,而不是使用更强的服务器替换旧的正在运行的服务器。


为了实现以上设计目标,需要采取面向职责的游戏服务器策略,根据功能职责划分游戏为一个个子集类型。这种将职责分配到服务器类型的方式类似于你设计类或其他软件模块单元的方式,但是有一个更高的抽象级别,包括:


1.将高层次的游戏活动进行功能降解( functional decomposition ),这样以便发现关键操作。


2.为典型的游戏场景编写用例以发现主要的业务行为。


3.按照操作类型将行为归组,包含行为和数据(这是一个对象),这些组其实是一种候选人职责,确认一个服务器类型拥有各自的候选人职责。


4.确认每个服务器类型执行的所有功能都应该不超过它的单一高级职责。


5.避免在一个用例中重复在服务器类型之间进行后退前进(back-and-forth)的交互。


6.避免出现跨不同服务器类型的长请求,也就是避免同步通信。


7.每个操作被看成异步的独立的事件。


8.如果可能,支持每个服务器类型有多个进程实例,限制单例,同时也避免多例带来的复杂性和消耗。


9.不断迭代直至这些服务器类型设计划分比较稳定了,能够应付需求的变化和未来新技术的融合。

从以上几个设计要点,我们需要将这个大型多人在线游戏系统划分为几种服务器类型,这几个服务器类型类似面向对象中类设计,是一种类别组,代表一组功能的聚合,这种类型划分方法就像将人划分为男人和女人两种类型一样。

下面是几个用来举例的游戏类型,不同具体游戏可能不同,但是可以借鉴:

1. Gameplay类型,执行所有核心游戏操作,包括游戏系统的逻辑和游戏效果,其状态包含人物状态,点数,游戏影响,经验值等等。

2.AI类型,执行所有人工智能AI的思考,主要控制NPC也就是非玩家角色的行为,比如您在买卖物品的时候需要点击的那个商人就是NPC,还有做任务时需要对话的人物等等都属于NPC,NPC行为包括路径查找 决策决定和预测等等,其状态是一个有限状态机,决策树和目标列表。

3.Visibility显示类型,使用空间几何和空间分区数据来计算在当前游戏场景虚拟世界中应该显示哪些东东。其状态包含定位位置,视野范围,障碍物和地图几何结构。

4.物理类型,使用空间几何和静态碰撞数据来侦测移动物体将和静物的碰撞,也包括模拟不受控制的移动,比如掉入等等,强调玩家移动时遵循游戏的规则。其状态包括位置,碰撞物 空间几何和路径发现可选地图。

5.目录类型,这个服务器类型维持一个集群中游戏定位信息,对于一个指定的游戏对象,能够指定相应的服务器类型中哪个服务器实例来运行这个游戏对象。

游戏服务器类型之间的交互如下图,客户端通过连接服务器接入,连接服务器和游戏服务器类型之间通过事件消息异步通讯。




游戏对象与状态管理


前面设计了游戏的服务器类型,将一个大游戏划分成几个模块,现在,我们要决定不同的游戏服务器类型的实例中运行的游戏是什么?包括该游戏当前状态等管理。

将游戏状态封装到一个逻辑抽象中是一个有用的设计方式,这个抽象称为游戏对象game object,也就是代表游戏中所有有意义的实体,包括玩家角色 NPC 条目 互动世界对象等等。

这个抽象对象的关键是ID标识,ID必须在整个游戏系统中唯一代表游戏对象实例,需要有足够的值空间,一般使用UUID或GUID或128位整数类型。

不同服务器类型使用不同的游戏状态类型,这样,一个指定的游戏对象类型也许会在不同的服务器类型中有不同的实现,一个处理物理模拟的服务器类型也许有和位置相关的行为和数据等等。一个处理玩家角色优化的服务器类型也许更注重可穿戴的东西,虚拟增强和其他属性。

这是一种有态的stateful的设计模式,游戏将状态保留在内存中以便重复使用直至其不再需要,这和我们通常将状态保存在关系数据库的系统设计是有区别的,每个游戏对象实例在某个时间只存在一个服务器类型的具体实例服务器中,这样降低对象创建的开销,有助于数据状态的一致性,游戏对象禁止在服务器实例之间复制移动,这使得定位某个游戏实例更加具有确定性,避免多线程资源竞争的发生。

游戏对象的定位


游戏对象之间通过异步事件交互,这样通常能实现高
并发,这能确保游戏对象无论是在同一个进程服务器中或不同服务器进程里都能保持交互的一致性,当对象在不同服务器进程中交互时,这些通过消息方式分发到对方的游戏对象中(目标对象)。

游戏必须提供在服务器集群中定位这些目标游戏对象,然后将事件发给它们,实现细节可能不同,但是必须考虑下面情况:


1. 在游戏服务器代码中使用逻辑地址定位目标游戏对象,这个逻辑地址应该包括目标游戏对象的ID,但是不应该包括任何物理主机地址或物理路由信息,可以包含有关目标游戏对象所在的服务器类型信息,比如逻辑地址的结构可以是:

声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

相关分类

返回顶部