王者荣耀正在使用的游戏 AI 框架:behaviac“易用高效” 的蜕变之路

7,560 阅读13分钟

behaviac是什么?

也许有很多人对它还不是很了解。

访问http://www.behaviac.com/(点击阅读原文直接访问)获取文档、教程、API、FAQ、源码、下载等一切相关资料。

简单概括来说,它是一款由腾讯研发部引擎技术中开源的一款游戏AI的开发框架组件。也可以做为游戏原型的快速设计工具。支持全平台,适用于客户端和服务器,用以助力游戏快速迭代开发。

当然,今天behaviac已经不仅仅可以用来做游戏的研发。在我们目前的用户中,已经有用户将behaviac运用到了VR产品领域以及机器人领域。截止2015年底,公司内部已经有十几个项目组选择使用behaviac,而这其中也包括了《天天炫斗》、《王者荣耀》、《全民突击》、《QQ飞车》等重量级大作。而最重要的是behaviac获得了大家认可,这是最让我们产品组所有人感到高兴的事情。


说到这里大家也许会奇怪,我为什么还在说去年的事情。因为,在2015年behaviac收获成绩的同时离我们的期望还有距离,我们不仅仅只是做一个能用的工具,我们的目标是一个有广泛影响力的,给用户带来价值的卓越产品!究竟怎么进一步提升behaviac?用户心中的behaviac是什么样子?

于是,一场围绕behaviac脱变之路的攻坚战便悄悄的开始了。


发现问题

去年的behaviac,虽然功能已然很强大(从编辑,调试,状态保存恢复,多平台支持,支持unity等等该有的都有了),并且也费了好大的力气去编写文档和教程,来帮助用户快速的上手。但在,在我们向各项目组提供技术支持过程中发现,仍有很多的用户在实际工作中出现各种各样的问题,甚至是在我们意料之外的一些问题。比如:

  • 编译构建,经验不足的新入手用户不知道从哪里开始,遇到问题茫无头绪;

  • 连调失败,有的时候连调失败或者没有更新,遇到问题无从下手;

  • 事件处理,不够直观;

  • 类型导出,需要程序员写太多的胶水代码,繁琐易出错;

  • 性能优化,用户不清楚在开发版和发布版间的取舍,用户不清楚如何进一步优化;

  • 门槛高、上手难,可是,我们明明提供了文档和教程,是大家没看到,还是不理解呢?

behaviac项目组所有人都明白,作为一款游戏快速研发、迭代的工具。强大且全面的功能性固然是产品的核心竞争力。但是,“易用高效”同样是behaviac的核心竞争力,我们在走访了用户和研究了竞品之后发现了自身存在的问题。

  • behaviac功能虽多也编写了文档和教程。但是,文档分散,教程不直观;

  • behaviac缺少示例,没有足够多合适的示例来示范在具体场景下的使用;

  • 作为一款工具,高效的技术支持必不可少,用户希望在遇到问题时,能够“马上、立刻”获得帮助;

  • 高效不仅体现在算法上,易用实际就是高效;

  • 优化流程,简化操作,减少使用者干预。 


积极求变

在明确了发力点之后,我们在今年开始了一系列大刀阔斧的变革。我们相信今年使我们的产品通往“卓越之路”的正确方向!

一、两次底层技术革新

behaviac的特色是基于类型信息,不需要写节点,易于扩展。在behaviac最初上线时,需要在程序端写特殊的宏及注册代码导出类型信息到xml文件,从而编辑器能够使用类型信息,设计行为树。

查看图片

然而在使用的过程中,这一设定带来了下列问题:

  • 程序员需要写特殊的代码来声明和注册Agent类型,看似简单,但是反馈下来带来了很多麻烦和困扰,特别容易错漏;

  • 支持自定义类型或是第三方库中的类型的时候,程序员需要按照一定的格式写声明和注册代码,稍有遗漏就会带来编译错误,链接错误,或者运行时错误;

  • 修改类型的名字或者属性的名字后,需要程序端首先导出生成更新过的xml类型信息,而编辑器里原有使用的地方无效需要重新编辑;

  • 策划需要添加新的功能的时候,需要依赖程序员修改代码来导出新的类型信息xml文件。这些都给我们的用户在实际操作中造成了困扰,并且极大的降低了效率。

于是,我们在2015年已经进行第一次颠覆式的革新。在这一次革新中,我们允许策划在编辑器里添加和修改类型及成员:

查看图片

注意元信息的箭头现在是双向的了。这个改动主要解放了策划,策划可以把编辑器作为原型设计工具来使用,策划不再依赖程序员首先修改代码了。然而,这一改变并为解决程序员的麻烦。而且,带来了新的问题:

  • 双向箭头,带来了数据容错的问题;

  • 初学者会搞不清楚到底应该怎么做。是从左到右呢还是从右到左呢?

  • 由于程序端使用反射系统来访问类型,对于C#版,反射系统会导致GC,而且还会产生装箱拆箱操作。

结合几项考虑,我们决定在2016年再次颠覆我们之前的设计:

查看图片
新的设计中是从编辑器到运行时的单向箭头,也就是说类型完全在编辑器端设计,类型信息以源码的形式生成,程序端把编辑器生成的关于类型信息的源码编译进程序。整个设计有如下优点:

  • 流程简单,没有歧义;

  • 程序员不需要写任何额外的代码,程序员只需要把生成的代码加入工程

  • 支持方便的添加新的类型或属性,修改已有的类型或属性,不再需要修改多次;

  • 属性不再必须是public的,被有效的封装;

  • 数据的兼容性检测,可以最大限度的支持策划和程序员并行工作,最大限度的避免策划等待程序员更新;

  • 支持热更新,将允许在代码不改变的情况下使用自定义变量以及修改行为树。


二、不再依赖MonoBehaviour

在C#版本中,最初为了方便的在unity中使用behaviac,Agent是从MonoBehaviour继承的,这样子就可以使用MonoBehaviour的Awake,Start,Update接口,方便behaviac的上手和接入。然而有些项目需要在服务器端使用behaviac,有些项目不想过多增加MonoBehaviour数,也就是说有些情况下更喜欢的是把behaviac::Agent作为其他某个MonoBehaviour的成员来调用。

我们响应了社区用户的反馈,增加了BEHAVIAC_CS_ONLY的宏,用户可以根据自己的需要来选择是否从MonoBehaviour继承。


三、优化鼠标操作

最初的编辑器中,“鼠标左键”用来选择节点,“鼠标中键”用来拖拽画布,而节点不能直接被拖拽,滚动中键用来缩放。在实际使用中,不少人一上来会使用“鼠标左键”来拖拽节点但又拖不动,他觉得不习惯,不喜欢。还有一些用户在工作中,发现自己的鼠标没有中键,或者中键是坏的,这就造成了一个非常尴尬情况。

查看图片
我们一开始的做法是添加了提示,并且支持了鼠标左键和右键同时按下就是滚动的功能。但是效果并不好,大家压根不会去看你的提示!抱怨用户不看提示和文档是没有意义的,用户就是这么直接。 

我们多次专门讨论这个问题,有一次灵感来了,我们可以使用鼠标左键来拖拽!鼠标左键点击节点的时候是选择,拖拽节点的时候就是移动节点,而拖拽画布的时候就是拖拽画布,既符合直觉,也能作为操作的提示,还解决了鼠标中键的问题。同时还在工具栏增加了按钮来支持缩放。经过了这个改动,问题得到了完美解决。


四、建立官网

随着用户的日益增多,原先我们在github上基于jeklly搭建的纯静态网站已经不能满足我们的需求。我们想提供属于自己的平台,能够把常见的问题分门别类的展示给用户,用户可以查看常见的问题,也可以提出自己的问题,而不是陷入反复回答类似问题的无聊中。

基于我们网站开发的经验,特别是前期开发过程中已经留意收集的技术,快速的开放了基于WordPress的网站,更好的展示文档教程;开发了Q&A论坛,用来作为收集和回答问题的平台。

  • 突出搜索:针对不同用户的需求,每一位用户都能够快速的通过关键字搜索找到所需信息;

  • 使用标签,结合分类:多维度的管理文档和教程,用户能够结合自己的使用情景快速且高效的找到答案;

查看图片


五、优化教程和文档

原来的文档比较分散,而且文字过多,没有充分发挥文档的作用。我们开始制作新的教程和文档:

  • 每个教程都是一个典型的使用场景,教程间由浅入深,层层深入;

  • 每个教程都有逐步操作的清晰说明,同时还提供可供下载运行的项目文件。用户可以拿来就用!

  • 编辑器中可以按F1键就可以跳转到相应节点的文档。方便用户“现场”就可以获取文档;

  • 针对操作性强的部分,制作必要视频,结合动图,降低用户理解门槛;

  • 提炼热点问题,热点概念,制作相关说明文档。


六、调试和离线调试

behaviac之前是提供了实时调试的功能而且很方便。

  • 程序运行的时候,编辑器可以通过网络和程序建立连接,甚至可以远程调试;

  • 实时的显示行为树的更新情况;

  • 而且可以设置断点,查看和修改变量。

然而游戏逻辑的问题常常需要结合前后若干帧的数据反复推敲;而且提供技术支持的时候,问题很难描述清楚。而且程序的执行情况我们已经支持了写到log文件,那么可不可以支持离线调试呢?有了想法,接着就是可行性分析,接着就是具体实现。于是就有了现在的离线调试!只是根据log文件就可以快速定位问题,感觉在实际操作和体验上又有了进一步的提升。

查看图片

  • 编辑器中加载程序运行产生的log文件,以和实时调试相同的图形显示形式显示行为树的更新情况;

  • 可以查看变量;

  • 可以模拟运行,可以设置断点,可以拖动到任意帧。


七、支持有限状态机

相比“有限状态机(FSM)”,行为树有诸如自包含,更容易扩展等优点,然而不少用户还是更喜欢FSM的直观,他们就是想用FSM!

查看图片

既然用户有这个需求,而且经过我们的评估后觉得这对于behaviac本身在功能性上也是一个很好的补充,于是我们决定:支持了“有限状态机(FSM)”:

  • 条件转换,当条件为真时跳转到指定的状态;

  • 等待转换及状态转换;

  • 有限状态机和行为树的互相引用;

  • 状态可以有前置和后置。


八、其他

除了上面的一些改进,我们还在很多方面做了改进:

  • 支持类型转换

  • 子树及prefab

  • 性能统计

  • 使用cmake支持跨平台构建

  • 多下载源,更友好的版本说明及下载管理

  • 更有意义的报错


数据说话

每当一个产品进行了革新或者优化之后,最担心的问题就是,用户是否真的“买账”,是否真的有触达到用户真实的需求。“数据”往往是最客观、最有说服力的证据。那么behaviac今年的变革又是否达到了预期呢?

从Github的数据来看,2016年相对于2015年,behaviac受到的关注度有了明显的提升,Watch、Star均为上一年3倍,Fork出去的分支增长为去年的4倍。

进入2016年以来,behaviac论坛的人数和官方QQ群的人数也持续增长,关于behaviac的讨论和互动非常频繁。

从下图可以看到,behaviac在2016年每月都会被使用5万次以上,近几个月再次有了突破式增长。

查看图片
@工具使用情况

由一系列的数据可以看出behaviac在今年无论是用户数还是工具使用情况都处在一个稳步上升的趋势中。这说明我们一系列的变革在一定程度上获得了用户的认可,并且赢得了一些用户口碑。但这只是走向“卓越之路”的第一步。


未来展望

在后续的工作中,“易用高效”将仍会是我们的核心发展方向。因为,只有不断打磨产品细节、不断紧跟市场发展节奏、切实以用户需求为核心,才能将尽可能完美的behaviac呈现给大家。卓越的产品没有既定的标准,用户说“好”才是真的好。

  • 提供编辑器的多平台版本,实现网页版编辑器;

  • 持续提供更多易于理解的教程和文档;

  • 持续提供更多深入文章,或者梳理功能,或者剖析细节;

  • 支持lua,java等语言或脚本;

  • 持续改进优化功能


查看图片