游戏中的AOI

前言

AOI(area of interest),它是MMO游戏中一个极其重要的概念,主要解决游戏中多人同屏的问题。本文并不打算去讲AOI相关的算法,如九宫格,十字链表,六边形网格之类的具体算法实现,因为此类文章网络上已经有很多了。虽然大多数开发者都接触过AOI,但是我发现其中很多人并没有真正深入领会AOI的本质。因此本文会从设计的角度来阐释什么是AOI,为什么要有AOI,以及如何去设计一个高质量的AOI系统。

正文

很多开发者在设计AOI系统的时候通常是这样设计的(以最常见的九宫格为例),比如把场景按照一定的Size划分出很多格子,然后由AOI系统根据玩家位置来更新玩家的所在的网格索引,每个玩家获取周围9个格子的玩家信息来进行显示。

这样就在细节上出现了很多如下问题:

  1. 玩家位置变化的时候如何处理,立即更新或者等到下一帧update的时候更新?
  2. 玩家位置变化或者周边其他玩家变化导致所在网格索引变化后,带来的对象的增加、删除如何处理?
  3. 由于显示列表的容量限制,玩家A的显示列表里面添加了玩家B,但此时玩家B的显示列表满了,该怎么处理呢?

这样的问题林林总总,很多开发者都花了不少心思去处理这样的问题。但是请让我们更深入的考虑一下,为什么会出现这样的问题呢?这样的设计就够了吗?

又比如说某天策划脑洞大开,说我们来做个暗杀玩法吧。并绘声绘色地给你描绘了如下让人心潮澎湃的情境:

“你从酒馆老板处接到暗杀任务后,展开羊皮纸一看,上面只记录了目标所在的场景,并没有具体位置信息,你需要传送到目标场景之后,自己去发现目标的踪迹。于是你使用传送卷轴到达了目标所在的场景,然后站在高山之上,开启了鹰眼术,目光如电刺穿远方层层的迷雾,随着你细致地搜寻,突然间发现远方的天际一个黑点缓缓浮现,你知道他就是此次的任务目标了,随即你立刻翻身上马,向目标疾驰而去……”

那这个时候作为程序,你该如何实现这个需求呢?

很明显,此时目标离你的距离远超你九宫格的距离,你依然要将他显示出来。那这个时候该怎么办呢?

所以,我们顺其自然地有了一个新的概念——“关注者“,AOI搜寻到的列表并不能就完全等同于关注者列表。而客户端显示的就是关注者列表里面的内容。AOI搜寻到的列表只是用来获得关注者的手段。

为了让读者有个更直观的理解,我举个例子。大家都很熟悉微博,假如我们把游戏当作微博来看的话。

  1. 登录场景:当我们注册账号进入微博(游戏场景)的时候,大家都没有关注者。这个时候我的微博首页的时间线上没有任何其他人的动态(游戏中此时只看得到自己)。
  2. 获得其他玩家信息:这个时候为了让大家互相交互,微博提供了附近的人的选项(假设微信上的这个功能移动到了微博)。这个时候你点击附近的人(游戏中向AOI系统拉取周边九宫格的玩家列表),然后获得了一系列的用户信息列表。此时你一一关注,瞬间你的时间线动态就丰富了起来(关注者列表新增周边的玩家并显示在本地客户端)。
  3. 消息同步:假设你的用户名是A,并且你关注了B,C。那么此时你的关注者列表里面是BC。而BC此时并不会说就关注你了,而是收到系统通知,获得了新的粉丝A。那么我们现在看A的时间线,会不停的收到B和C的动态,如果是在游戏场景下,那么B和C最常发送的动态就是玩家B或C移动到了某位置P1(Obj:MultiCastPktPosChanged),玩家B或C使用了技能(Obj:MultiCastPktCastAbility)等等(此处仅为让读者能够直观理解概念,实际上的同步优化处理有很多方法和技巧,在此并不展开)。
  4. 关注机制:虽然上例中A能收到B和C的各种动态,但是A发出来的动态只有自己看的到,B和C是看不到的,也就是说AOI并不需要双向连接。这并不仅仅只是为了解决前面提到的第3个问题(细细思考一下)。同时这也是符合现实感受的。比如说每天上班的时候地铁里面有很多人,你会关注谁呢,你关注的目标会关注你吗?但此时如果周围有人拍了一下你的肩膀,喊了你的名字,那么你就会立即关注他是谁,对吧。(以游戏场景为例的话,假如周边有很多玩家的话,你不一定需要严格按照位置远近来排序,而是需要把跟你关联度最高的玩家加到你的关注者列表中。比如不远处的某个玩家向你发起了切磋请求,那么此时的解决方案就应该是把他加入到你的关注者列表,而不会说根据距离远近再来把这个玩家增添移除掉)。

此时,回到最开始的问题,那么前面的问题的答案就显而易见了。

  1. AOI的信息需要立即更新吗?不一定需要,我们未必需要时时刻刻关注离我最近的目标,附近的人这个功能里面的用户列表更新频率慢一点也没关系。

  2. 因为我们并不需要时时刻刻关心附近的人,所以自然也不会有某个玩家在边界进进出出导致的AOI不停的创建和删除的开销问题。(如果还需要优化就加上lazy time处理下吧)

  3. 这个问题已经显而易见了,没必要一定得互粉,看缘分啦。我附近如果没其他人,又太寂寞的话说不定也会关注你,关注列表满了就算了。

最后,策划的需求解决起来也很简单了。搜寻目标的过程就是使用技能给自己加了个Buff,Buff创建的时候将目标加到关注者列表中,目标死了后buff销毁,并将目标移除出关注者列表。 这在微博系统中相当于你直接搜索该玩家的账号,直接加关注,任务达成后再直接取关就行了。并不需要与”附近的人“这个功能发生任何关系。

总结

因此,当我们设计AOI系统的时候,并不需要严格只显示九宫格范围内的对象,九宫格只是一个手段,一个让我们获得关注者的手段,它只是个过程,并不是结果。大家在设计的时候多考虑这一点,使用起来就方便很多了。甚至我们可以让技能改变关注者列表,从而达成一些特殊效果。

原文

如何实现一个强大的MMO技能系统——AOI

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

57 − = 48