« Lua 下实现抢占式多线程 | 返回首页 | 开线流水帐 »

MMORPG 中场景服务的抽象

MMORPG 中,场景信息同步是很基础而必不可少的服务。这部分很值得抽象出来,专门做成一个通用的服务程序。

此服务无非提供的是,向有需求的对象,同步场景中每个实体的状态信息。那么,我们分解需求,可以看到两点,一是提交状态,二是同步状态。

每条状态信息其实是由三部分构成,状态对象名(key)、状态值(value)、时间。

玩家、NPC、场景中的可变物品,其实都有可改变的状态。比如对象的位置坐标是最常见的状态。其它的状态还有玩家或 NPC 做的动作,玩家离线,上线,等等。

可以有若干数据源向这个服务提供数据,如果借用 zeromq 中的模式的话,这个服务应该使用一个 PULL socket 收集数据。它获取从不同数据源 PUSH 来的,key-value 。然后打上时间戳,储存在内存中。

这个服务另外提供一个发布服务,向所有订阅者广播其收到的状态改变信息,每条信息包括推送来的 key-value 以及附加上去的时间戳。

第三,这个服务应该提供一个请求应答服务,除了订阅模式外,允许别人索取从指定的 timeline 到现在的所有状态。这多用于新的订阅者上线,它需要获取历史上的状态信息。

综上,这三条看起来就是一个 twitter 的基础服务,但缺少了对象之间的关注关系。嗯,在这个简化系统中,这点是可以省略的。另外,状态并不是 tweet 。我们在意的是对状态的修改,而不是同一 key 下的历史上所有状态值。比如,我们只关心一个玩家当前最新的位置,而不关心他历史上在哪里。


这个玩意能做什么?除了同步玩家和 NPC 的位置外,还可以作为战斗系统的基础。比如,玩家做一个攻击动作,可以做为一个状态提交。对于显示来说,场景中的其它玩家都应该看到他做这个动作。但一个额外的战斗模块也可以通过订阅场景,了解到这个玩家做了攻击动作。

之后,战斗模块通过其它途径获得这个攻击动作的具体含义(会产生多少伤害等等),进行运行,得到结论。而进入战斗状态的玩家,可以通过订阅战斗模块发布的信息来获得细节。

嗯,这只是举例说明其一可以想到的用途而已。如果我的归纳没有错误的话,提供上面基本服务的设施,可以做的事情很多,却只需要实现定义好的简单需求了。再列一下:

  1. 一个 PULL socket,获得格式为 key-value 的状态信息。收到后加上 time 储存。

  2. 一个 PUB socket ,一旦受到 1 里面获得的状态信息,即可连同 time 发布出去。

  3. 一个 REP socket ,收到 REQ 请求(一个 time 值),把从这个时间点之后的所有状态信息反馈回去。


下一步,我们看看怎么增强这个服务,解决更复杂的问题:场景很大怎么办?

我们的状态信息还需要增加一个部分,位置。即 key-value-position 。

我们可以增加发布点,把场景分成若干区域,每个区域树立一个灯塔。position 本身会被匹配到临近的几个灯塔上。每个灯塔都是一个子发布点。

增加这样一个服务 :提供一个 REP socket ,收到 REQ 请求(一个position 值)后,返回若干临近的灯塔 id 以及灯塔的信号半径 。然后,用户可以选择订阅这些灯塔。当发现自己的视野即将超出灯塔覆盖后,可以重新索取更换一批灯塔。


关于状态的删除。当物品消失,玩家下线,npc 死亡 等等事件发生后,相关状态,变得只有时间线最后一条信息有意义了。这个时候我建议提交 k/v 对的时候将 v 设置为空,表示把这条状态删除。这样以后用户在请求时就不用获取到无用信息了。

Comments

是啊

感觉有点像手机通信里的蜂窝系统 呵呵

云风的3D引擎貌似还遥遥无期?要不要再过五年才能出来呢?

慢慢地感觉来留言的人越来越少了,云风是否可以开始一些3d技术方面探索的话题呢

地区很抽象的!!

首先,看起来云风同学的老乡过来提醒需要改进发言验证了机制了,呵呵。

其次,那个灯塔换用蜂窝电话来类比会不会更清晰一点儿?

最后八卦一把,新闻上看到了网易在杭州的漂亮大楼,不知道云风现在还在杭州么?你们的游戏计划什么时候公测?期待去体验一下 :)

我觉得订阅信息、分区灯塔这些概念有些复杂,可不可以这样来理解这个问题:
1. 系统中的每个对象的变化都理解为一个事件,无论是来自玩家的还是系统的,都按顺序放在消息队列中。
2. 规定每个事件都有发生地坐标、每类事件都有其特定的做用范围。处理时根据作用范围把事件放入作用范围内玩家的消息缓存中,超出范围的不用管。
3. 在玩家消息缓存已满或心跳频率到达时把消息打包压缩发送给PC。

这样处理流程简单了,易于优化和并发,另外也避免了跨界问题。

云风总结的不错,本人补充一点,场景同步还可以细分策略

1,需要server立即主动同步的数据,比NPC位置,hp,mp,

2, 不经常改变的,比如NPC身上挂的static buf, client做cache定时请求数据

3,基本不会改变,如NPC的称号client请求才会同步

战斗数据客户端和服务器采用一套数值计算,当然战斗计算结果以服务器的为准,服务器只同步基础属性

说的不对,敬请原谅,水平有限


这么看zeromq总结的通讯模式确实很赞。。请问风云会不会在实际项目中使用zeromq呢?

Post a comment

非这个主题相关的留言请到:留言本