服务器消息的广播
MMO 的 engine 中,需要解决的最重要的问题之一,就是如何把游戏世界中的状态改变消息正确的通知给需要知道这条信息的玩家。
通常,我们会设定每个玩家的 AOI ( Area Of Interest )。当一个对象发生改变时,它会把消息广播出去;那些 AOI 覆盖到它的玩家会收到这些广播消息。
但是,在我们现在的游戏系统中,简单的 AOI 系统是不够用的。比如,类似 wow 中的盗贼隐身,明明已经离你很近,但是你的 client 却看不见他。诚然,我们可以在 client 判断这个逻辑,对盗贼不于显示,而 engine 依然广播盗贼移动的消息。对于不作弊的 client ,这是个简单的解决方案。但在理论上却提供了看见隐身人的可能性,所以,我期望有更好的方法让 engine 可以只将消息广播到那些必须接收这些消息的 client 。但是,在实现这个同时,又不能让底层 engine 牵扯太多逻辑信息。
这里提出一个简单的方案:
基本的 AOI 系统中,对象只有方位坐标是为 AOI 模块所知的。如果希望让每个玩家的视野有所不同,对于观察者(玩家)可能还需要多设定一个视野半径的参数。如上面举出的盗贼隐身一例,解决那种逻辑这些数据是不够的。
我所构想的系统中,观察者有两个参数,雷达半径和雷达强度;而被观察者除了坐标外,还有一个信号半径的参数。(这里,玩家通常既是观察者又是被观察者;而 npc 是纯粹的被观察者)
雷达半径就是前面所说的视野半径;而雷达强度决定了在离目标一定距离时,可以分辨的最大尺寸的物体。这个尺寸当然不是指对象的模型大小,而是指被观察者的信号半径。
有了这几组数据,我们就可以决定被观察者是否为观察者所见。通常,雷达半径、强度,和物体的信号半径都是不变的。但是,游戏逻辑可以根据需要来改变它们;比如通过装备、升级、战斗时 buffer 等等。不过底层 engine 不需要了解这些逻辑的细节,只需要把基本参数拿出来算一下就可以确定了。
我们把这些属性绑定在对象上,由 engine 决定对象的远程方法应该发给哪些人。进一步的,我们可以给对象的每个远程方法加一个权值,以优化网络通讯。比如,人物对象可以有一些诸如挥手一类的 emote 行为,可以有一个较低的信号半径权值。当一个玩家可以看见 500m 外的一个人物时,或许这个人物正在做的挥手动作他还看不见;直到他们接近到 250m 时才能收到挥手的消息。
这样的系统,对于 3d 第一人称的 mmo 或许会有用。了解过我们公司另一个项目没能很好的解决这个问题,写此文将自己的想法记录之。
Comments
Posted by: 独孤残云 | (11) June 7, 2010 09:21 AM
Posted by: 榊 | (10) July 5, 2007 02:09 PM
Posted by: Mandi Zu | (9) March 24, 2007 10:34 PM
Posted by: Mandi Zu | (8) March 24, 2007 10:31 PM
Posted by: ro4tub | (7) October 27, 2006 12:36 PM
Posted by: wangdali | (6) October 17, 2006 05:06 PM
Posted by: LOGOLS | (5) October 9, 2006 06:42 PM
Posted by: Cloud | (4) October 4, 2006 10:12 AM
Posted by: Felix | (3) October 4, 2006 09:35 AM
Posted by: Li Zhuang | (2) October 4, 2006 02:58 AM
Posted by: Anonymous | (1) October 3, 2006 09:44 AM