网络游戏无缝服务器方案

  网络游戏无缝世界服务器允许网络游戏使用很多台服务器支持游戏中一块场地的运行。每台服务器支持整块场地中的一小块场地的运行。当两个玩家处于不同服务器支持的场地上时,他们之间进行的活动应该和整块场地由一台服务器支持时无异。但在实际操作中要做到这一点非常困难,即使使用大量代码也无法保证完全正确地做到这一点。目前使用得最多的方法是代理对象方法,这种方法当一个对象进入边界区域时,它所在的服务器会通知相邻的服务器,后者会创建一个代理对象来表示远程对象。同样地,当这个对象从边界区域移动到服务器“内部”时,所述代理对象就被销毁。但是这种方式即使是最简单的游戏机制实现起来仍然非常困难。造成这种困难的原因就是两台服务器都在运行。当两台服务器同时修改一个对象时就会无法确定对象的状态。

    为了解决上述问题,本方案对于几台服务器之间的边界区域,只让其中一台服务器运行,而暂停其它服务器对这块场地的处理。那么暂停一部分场地的运行会对游戏造成多大影响呢?我们知道大部分MMORPG(大型多人在线角色扮演游戏)服务器端每1/10秒才向客户端发送一次数据。即使是FPS(第一人称射击)游戏,通常也不超过1/60秒向客户端发送一次数据。因此只要在1/10或1/60秒内让几台服务器轮流得到运行,就不会对游戏造成太大影响。这样当两个玩家处于不同服务器支持的场地上时,他们之间进行的活动和整块场地由一台服务器支持时几乎没有差别。

    下面来看一下具体怎么做。参见下图,游戏中的场地被分成了任意小块,每小块由一台服务器支持它的运行,选取其中的16小块为例,其中场地编号为1至16,服务器的编号与场地对应。首先暂停全部16台服务器,然后服务器1、服务器3、服务器9、服务器11分别获取和它们相邻的场地边界的状态。然后服务器进入以下循环:服务器服务器1、服务器3、服务器9、服务器11分别计算各自场地的状态,以及在此过程中对相邻的场地造成的影响。现在服务器1、服务器3、服务器9、服务器11有了最新的自己场地上和相邻场地边界上的状态。然后服务器1、服务器3、服务器9、服务器11暂停对各自场地状态的计算。服务器2从服务器1、服务器3、服务器5、服务器6、服务器7获取最新的场地边界的状态。当然很明显的是此时服务器2的左边界和服务器6的左上角边界部分的最新状态在服务器1上,所以应该从服务器1上获取。其它边界的状态也是一样。另外服务器4、服务器10、服务器12也同时各自象服务器2一样获取它们自己以及相邻边界的场地的状态。然后服务器2、服务器4、服务器10、服务器12分别计算它们各自的场地以及在此计算过程中对相邻场地边界的影响。然后是服务器5、服务器7、服务器13、服务器15和服务器6、服务器8、服务器14、服务器16依次运行。这样就完成了一次服务器运行的循环。


    需要注意的是场地被分割时同一对象不能被同时修改的原则仍然适用,因此小块的宽度至少不能小于边界宽度的两倍。

    可以在游戏运行时把小块场地交给其它服务器来支持它们的运行,只要把这一小块场地的全部状态传送给其它服务器。也可以在游戏运行时把小块场继续分割,然后把分割后的小块场地交给其它服务器来支持它们的运行。或者把相邻的小块场地合并,由同一台服务器来支持它们的运行。在合并前需要先把想要合并的小块场地的状态传送到同一台服务器。这样我们就可以在游戏运行时动态调整支持整块场地中任何一小部分运行所使用的服务器,以达到合理分配每台服务器的负载的目的。

    每台服务器可以支持不止一块场地的运行,因此我们可以把场地1、场地2、场地5、场地6放在服务器1上,场地3、场地4、场地7、场地8放在服务器2上,场地9、场地10、场地13、场地14放在服务器3上,场地11、场地12、场地15、场地16放在服务器4上。这样这16块场地实际只需要4台服务器来支持它们的运行。我们还可以任意分割或合并小块场地。例如我们可以在游戏运行时把场地1至8合并成一块,场地9、场地10、场地13、场地14合并成一块,场地11、场地12、场地15、场地16合并成一块,让它们分别由服务器1至3支持它们的运行。或者也可以分割场地1至16中的任何一小块,把分割后的小块交给其它服务器来支持它们的运行。

我是怎样发明这一方法的?

    记得有一次某个大游戏公司的CTO跟我谈到这一问题,他说“这问题很难解决!”。我说“可是我觉得这问题很容易解决啊!”,并且给出了一个自己的解决方法。但是后来我仔细思考,发现那个方法实际不能解决这一问题。有一天我在国家图书馆看书的时候又想到这一问题,我立即想到了这一方法。等我发现这一方法确实能解决问题后,我开始忍不住地不停地笑。我想别人也许会觉得很奇怪,他为什么不停地傻笑呢。

本方案已申请专利,寻求投资及试用。

交换链接:
交换链接