欢迎光临散文网 会员登陆 & 注册

Paragon Bots:一麻袋骗人的伎俩

2021-11-09 16:15 作者:有木乘舟  | 我要投稿

Mieszko Zielin’ ski

32.1 Introduction

  Paragon 是 Epic Games 用虚幻4引擎研发的一款MOBA类游戏,在项目开发后期决定在游戏里加入机器人玩家,有限的时间和人力资源,以及围绕玩家而构建的游戏机制,意味着项目组没有多少富余的时间去完成这个任务。本章将介绍我们为UE4的AI系统做的一些扩展,以及为Paragon机器人做的一些简单系统实例。最后,我们对基础行为树做了一些增强,提出了一些适用于MOBA游戏的空间表征,将所有这些与我们成熟的空间决策系统、环境查询系统(EQS)集成,并添加了一些其他技巧。结果超出了我们的预期!

32.2 Terms Primer

  本章中有许多术语读者可能不知道,所以我们将在这里解释它们。玩家在Paragon中控制英雄单位,英雄单位即可以施放技能对敌人造成伤害或削弱(debuff),强化(buff)或治疗自己和队友的角色。Buff(强化)意味着提高能力(如回复,移动或攻击速度等),而削弱则有相反的效果。技能(Abilitiy)会消耗英雄的能量,这是一种有限的资源。从某种意义上说,技能也会消耗时间,因为它们受到冷却时间(CD)的限制。有些能力总是活跃的(active),而另一些则需要明确的激活。游戏的目标是摧毁敌人的基地,同时保护自己的团队的基地。基地的防御塔是团队可以用来阻止或减缓敌人前进的速度。塔和塔之间有一条甬道,连接到敌人的基地,小兵从一个基地出发通过甬道移动到另一个基地。小兵是一种简单的生物,他们会为自己的团队而战斗,并且每隔一段时间出现一波(wave,即几队小兵同时出现)。

  这款游戏的意义远不止于此。在小路之间有一个丛林,里面住着丛林怪物(英雄为了获得经验和临时增益(buff)而杀死的中立生物),在那里可以找到经验井。游戏中的英雄和技能可以升级,获得被动或主动能力等。然而,本章只关注

游戏中有英雄和能力升级,以及提供被动和主动能力的纸牌等等。然而,本章将只关注bot是如何围绕前一段所述的游戏元素进行思考的。

32.3 Extremely Parameterized Behavior Trees

  经验丰富的AI开发者可能会惊讶于所有Paragon机器人都使用相同的行为树。由于时间和资源的限制,我们无法为每个英雄,甚至是每种英雄类型开发单独的树。由此诞生了一个特定的解决方案:主行为树定义了通用结构和规范准则,但行为执行的细节(比如使用哪种能力,执行哪种空间查询等等)是参数化的,因此一些具体的实时数值只有在需要的时候才会从AI身上获取。

32.3.1 Vanilla UE4 Behavior Trees

  在详细介绍UE4的行为树系统细节以及该系统在Paragon的扩展之前,先来个总览。UE4的行为树系统已经做为工具包被使用多年了,所以介绍将会被限制在新增功能实现上。

  UE4的行为树系统是基于事件驱动方式实现的。一旦选择了表示任务的叶节点,在任务完成或条件改变之前,树不会重新评估。执行条件以装饰器节点的形式实现(Champandard 2007)。当它的条件改变时,装饰器节点可能会中止较低优先级的行为或它自己的子树,这取决于设置。

  行为树与黑板系统(Blackboard)紧密相连,黑板系统是默认的通用信息存储结构,采用简单键值对存储的形式。它非常灵活(它几乎可以存储任何类型的信息),并且有很多方便的内置特性,可以在运行时读写数据(动态性)。黑板系统的键值对是参数化行为树节点的最简单方法,节点需要的数据value可以简单的通过key来获取。参数化行为树节点的一个例子是MoveTo节点,它从黑板系统中获取移动目标位置。

  我们的BT实现还有一个辅助节点类型—服务节点(service node)。它是一种附加到常规节点(组合节点或叶子节点)的节点类型,只要它的父节点是活跃分支的一部分,它就是“活跃的”。当激活或禁用的时候,服务节点会得到通知,并且可以选择多少帧活动一次。

32.3.2 Environment Querying System

  UE4的AI系统的另一个单元,就是EQS系统,中文名字叫环境查询,顾名思义其实就是对当前的场景里满足条件的一些信息进行查询,并且返回结果,让我们AI根据收集的这些信息做出不同响应。主要用于AI定位和目标选择等任务。通常BT系统提供了一个任务节点和一个服务节点,用于运行EQS查询并将结果存储在黑板中。

  对于Paragon,我们对EQS进行了更改,这样就可以通过在黑板上指定一个键来指向我们想要使用的查询模板。查询模板本身是常规的UE4 UObjects,所以不需要在黑板上做任何工作。唯一需要做的事情是扩展BT任务,发出环境查询,以便能够使用由黑板值指示的查询模板。然后我们使用这个新功能为近战和远程英雄执行不同的定位查询;近战英雄尽可能靠近敌人以发动攻击,远程英雄则将距离维持在攻击范围内,这样就不会离敌人太近。

32.3.3 Blackboard Extension

  黑板系统存储新类型只需要一个新的键值类型就可以。对于Paragon,我们增加了一个能力标识key,唯一标识给定英雄可以执行的能力。通过新的黑板 key type,我们可以方便的配置BT节点,并根据不同目的选择不同的能力。第32.4节描述了选择能力的方式。

32.3.4 Behavior Moods

  通常认为行为树是信息的最终消费者,其根据数据和信息来做最优决策。除此之外,我们也需要能获取正在发生的行为的信息的子系统。子系统并不需要具体直到AI在做什么,只需要知道其当前的“情绪”(mood),如是否在逃跑、是否在攻击角色或塔等。当前的mood是通过专有服务节点设置的。“情绪”信息随后会被用在一些派生功能中,如设置AI的关注点、哪些移动相关的能力可以使用等。

图32.1显示了所描述的扩展和特性如何混合在一起的示例。

32.4 Ability Picker and Bot Ability Usage Markup

  在给定的上下文信息中去决定使用那种能力不是一个简单的任务。这个决定取决于多种因素,比如目标类型,我们想对它做什么,我们现在有多少能量,以及哪些技能正在冷却。此外,许多能力具有多种不同的效果。例如,有些技能可以伤害或拖慢敌人,但它们也可以治疗友军英雄。

  Paragon中的能力是通过蓝图的脚本语言实现的,这给了设计师很大的自由度去设计能力的功能执行。此外,仅通过原始信息是不足以弄清一个能力的的使用方法的。为了解决这个问题,我们想出了一系列标签,设计师用来标记AI应该使用的每一种能力。我们称之为机器人能力使用标签;例子如表32.1所示。

32.4.1 Ability Cached Data

  当机器人英雄被赋予一项能力时,我们从对应蓝图中获取相关数据。我们将结果存储在机器人的能力缓存数据(Ability Cached Data)中,非常小心地确保数据表示是有效的。标签在数据中被表示为一组标记。存储的其他信息包括能力的范围、类型、伤害、能量使用、冷却时间等等。它还会缓存时间戳,显示指定技能的冷却时间何时结束,以及AI何时有足够能量施放指定技能。机器人控制的英雄的每一个可用的激活技能都在能力缓存中有对应的表示。能力缓存数据是能力选择器效率的关键。

32.4.2 Ability Picker

  能力选择器是一个简单但功能强大的工具,能从一组给定能力中选择正确的能力。

能力选择器执行此操作的方式非常简单——实际上,奥秘就在能力缓存数据中。

能力选择器所做的就是遍历在给定时间点可用的能力列表,并检查它是否与所需的效果和目标类型相匹配。返回的能力是所需成本最小的之一。根据目标类型,“最佳成本”可以有不同的含义。 当瞄准小兵时,我们更喜欢消耗小的技能,而我们留下费用更高的技能来瞄准英雄。 不用说,这种评分方法还有很大的改进空间。核心能力选择器算法非常简单,在代码清单 32.1 中以伪代码形式呈现。


  AllAbility 是一个数组,其中包含机器人可用的每个能力的能力缓存数据。IfValidTarget 函数检查给定的目标是否属于合适的类型(英雄、小兵、塔),是否属于有效团队,以及目标的空间密度是否足够高。IsBetterScore给小兵更低的分数,给英雄更高的分数,因此会更倾向于同英雄战斗。

32.4.3 Target’s Spatial Density

  一些技能被设计师设计为可以对小兵单位释放,但只有当该区域有一个以上的小兵单位时才可以使用它们。这种是范围技能(AoE),它影响指定区域内的多个小兵,而不是单个小兵。在一个小兵身上使用这种技能纯粹是浪费精力和时间。

  为了能够有效地测试给定的小兵是否“单独”,我们找到传递给能力选择器的每个小兵的空间密度。小兵密度作为影响贴图计算的一部分进行计算,这将在本章后面介绍,因此在运行时获取此信息只需执行简单的查找操作。

32.4.4 Debugging

  有一个系统来控制所有的技能选择有一个更容易调试的额外好处。添加可选的、详细的日志记录非常容易,一旦启用,它将描述在选择过程中哪些功能被丢弃,以及为什么被丢弃。记录的信息与空间和时间上下文相结合,我们可以通过UE4的可视日志即时获得这些信息,从而快速解决许多技能选择问题,这些问题通常被证明是技能标记中的错误。你永远不能相信那些该死的人类!

  在机器人的技能执行测试中,一个非常有用的技巧是添加一个控制台命令,用于在游戏运行时覆盖技能选择,以始终选择指定的能力。由于采用了集中式方法,我们能够通过将一段调试逻辑插入到Ability Picker的FindAbilityForTarget函数中来实现它,该函数将始终拾取指定的技能。

32.5 One-Step Influence Map

  the influence map 是游戏AI中众所周知的概念,它已经存在很多年了(Tozour 2001)。这是一个非常简单的概念,易于掌握,设置简单,但从提供的非常简单的信息中产生大量有用的数据。这个想法是基于这样一个概念,即队伍对其环境施加“空间影响”,与他们的战力、生命、战斗状态或任何其他随距离衰减的因素成比例。the influence map是所有这些影响的叠加,可用于指导人工智能决策。

  通常,构建the influence map需要每个智能体通过两个步骤。首先是在代理的当前位置应用代理的“影响”,这通常是智能体影响力最大的地方(也有其他可能性[Dill 2015])。第二步是影响传播,我们获取给定智能体的影响并将其传播到所有相邻区域,然后传播到这些区域的相邻区域,依此类推。智能体以这种方式分布的影响是距离源越远,影响越弱的函数。

  影响力传播可能是一个非常昂贵的操作;取决于影响力映射表示和分辨率(尽管有算法提供无限分辨率影响映射[Lewis 2015])。当考虑更多的影响来源时,开销也会更加高昂。由于Paragon服务器的处理限制,未选择原始的方法。

  有很多种方法来实现the influence map。性能对于Paragon机器人非常重要,所以我们选择了一个非常简单的结构来表示图上的影响力。由于在垂直轴上没有与游戏性相关的可导航空间重叠,因此我们能够用一个简单的2D单元格网格表示地图,每个单元格表示地图的一个固定大小的正方形。使用的正方形大小是在获取高分辨率数据和不占用太多内存来存储地图或在计算更新影响力时使用太多CPU之间的折衷。

  我们不能简单地忽略这样一个事实,即不同的敌人具有不同的射程和力量属性,这将通过影响传播自然地影响the influence map。代替实际的影响传播,我们应用一些智能体的影响来映射特定半径内的单元,而不仅仅是智能体当前所在的一个单元。我们对每个目标(甚至是远程目标)使用零半径,对英雄我们使用每个给定英雄的主要能力范围。有人可能会争辩说,在半径而不是点上应用影响几乎与影响传播相同,但是当将影响应用到半径内的每个单元时,与将其传播到连续的邻居相比,性能会有很大的提高,特别是如果传播关心单元到单元的连接。将影响应用于半径中的所有单元确实会产生忽略通常会阻止影响的障碍物的副作用,但由于Paragon匹配的动力学和Paragon贴图的构建方式,这种影响可以忽略不计。

  我们使用the influence map的主要方法是确定机器人在战斗中的位置。根据英雄类型和情况,我们可能希望机器人远离敌人(远程英雄的默认情况),或者相反,靠近敌人(近战英雄的默认情况)。我们还可以使用“友好影响”来表示更安全的位置,或者相反,帮助机器人分散开来,避免成为容易的AoE攻击目标。事实证明,所描述的用例实际上并不需要影响传播,因为影响范围(定义为英雄的有效范围)已经嵌入到the influence map数据中。传播的数据会让我们了解战术位置可能如何变化,但在Paragon中,它一直在变化,因此我们选择了一种更便宜的解决方案,而不是只能产生细微更好的结果的解决方案。通过故意扩大每个英雄的半径,也可以在一定程度上伪造 Influence propagation。扩展甚至可以从运行时信息中派生,比如当前速度、健康状况、能量等,因为我们定期从头开始构建the influence map。如下文所述,the influence map与EQ集成,以影响定位、目标选择等空间过程

32.5.1 Other Influence Sources

  其他游戏玩家类型也可以改变the influence map。让我们首先考虑塔楼(第32.2节中描述的防御结构)。所有进入敌方塔楼攻击范围的人物都处于极度危险中,因为塔楼会主动攻击,甚至对高级英雄也是如此。然而,影响信息仅由英雄机器人使用,只要英雄有小兵陪伴,英雄在敌方塔楼范围内是安全的。小兵是塔楼的主要目标。出于这个原因,只有当一座塔没有小兵可以攻击时,我们才会在地图构建中包含该塔的影响信息;否则,机器人不会关心塔楼的危险(或者事实上,甚至不知道它!)。

  这里值得一提的是,由于塔楼是静态结构,我们不需要重新计算每一帧都会影响哪些the influence map cekks。相反,我们在匹配开始时收集所有受影响的单元格,然后在重建the influence map时重用缓存的信息。

  在the influence map生成过程中,我们考虑的另一个影响源是AOE攻击。其中一些攻击持续时间足够长,因此有必要将其纳入影响计算。在the influence map中有这些信息,可以很容易地“看到”进入这样一个区域的危险!我们不会用持续时间短的AoE攻击来注释影响地图,因为AI不会有机会对它们做出反应,不管怎样,这些攻击持续的时间刚好足以造成伤害,而且一旦它们被施放,几乎没有机会避免它们。

32.5.2 Information Use

  如前所述,the influence information的主要用途是给智能体定位。通过添加另一个扩展空间查询系统(EQS)的测试类型,可以轻松地将此信息包含在其余的定位逻辑中。EQS可以用一个简单的测试样例读取世界空间里指定位置的 the influence information,该信息可以用来计算和筛选智能体未来可能的运动位置。将这一简单的测试合并到所有智能体的定位查询中,可以让我们快速获得非常好的结果。由于这一变化,机器人获得了避免进入敌人塔楼的火力或撞向敌人群的能力,并可以选择靠近朋友的位置,等等。

  调用与地图的每个单元格相关的辅助信息。严格来说,这些信息不是影响图的一部分,而是作为影响图构建的一部分收集的。辅助信息包括影响每个单元的智能体列表。我们利用这一信息,通过有效地减少他们考虑定期视线测试的目标数量来改善角色的感知能力。查询给定区域内敌方目标或英雄的the influence map归结为一个简单的查找操作。

  影响数据的最后一点是我们称之为目标密度(target density)的东西。这是一个针对给定类型敌人(小兵或英雄)的简单单元格计数器,我们使用它来确定给定目标是否“单独”或在攻击特定目标时是否可能击中其他目标。这是提示能力选择器在给定目标上使用AoE能力是否浪费能量的信息。

  出于时间成本的考虑,对重要的数据进行复用是必要的,尽可能的榨干数据的最后一丝有用信息。

32.6 Lane Space

  我们经常要回答的一个问题是“机器人X在其所在的路线上上离Y有多远”,其中Y可能是敌塔、英雄、小兵,或者只是世界上任意的位置。我们并不真正关心实际的3D距离,只关心“路线有多远”。如果路线是直线,这是非常容易回答的,但在Paragon就不是这样了……除非我们把它们弄直!

  图32.2a描绘了常规MOBA地图,其中a和B标记了两队基地的位置。共有三条路线,左右路线完全不直。这就是路线空间概念的由来。将三维世界位置转换为路线空间需要将其投影到AB段定义的直线上。有关此转换的说明,请参见图32.2b。

  引入路线空间可以很容易地添加一种新型的EQS测试,用于根据给定路线上与作战线的相对距离进行评分或过滤。例如,我们用它来让远程机器人选择在小兵身后10米的位置。

32.6.1 Lane Progress

  路线空间的自然延伸是Lane Progress。它是一个定义为位置到a或B的路线空间距离的度量,是|AB|标准化(从a到B的距离)。

Lane Progress是相对于给定团队的基地计算的,因此,对于团队a,基地a位置的Lane Progress值为0,基地B位置的Lane Progress值为1。对于B队来说,情况正好相反;事实上,对于每个团队A的Lane Progress值x,团队B的值将等于(1–x)。

32.6.2 Front-Line Manager

  在MOBA中,英雄们必须了解基于危险和安全区域的路线定位。在战斗中,远程英雄更喜欢呆在小兵线后面一点,而近战英雄应该在前线战斗。

  为了让机器人像真人一样工作,我们创建了前线管理器(Front-Line Manager)。它的唯一目的是跟踪所有活着的小兵,以及所有剩余的塔楼,并计算出战斗地点。在the influence map构建期间,the influence map管理器正在向Front-Line Manager提供有关小兵的信息。根据这些信息和给定团队每条路线上塔楼的当前状态,Front-Line Manager正在计算两个团队每条路线上的前线。准确的前线值以Lane Progress表示。

  类似地,对于the influence map信息,我们通过实施另一个测量位置到前线距离的EQS测试,将前线信息纳入定位逻辑。

  另一个前线信息相关的地方是在选择敌人的过程中。我们希望避免机器人追击敌方英雄深入敌方领土,因此到前线的距离有助于目标得分。同样,这是通过专用的EQS测试完成的。

32.7 Other Tricks

  由于时间限制,偷工减料是至关重要的,所以我们还使用了很多其他的小技巧。这些通常是简单的临时解决方案,要么工作得足够好,以至于玩家不会注意到,要么是给未来新的解决方案占个位置。

  第一个值得一提的是完美的目标。远程英雄机器人精确瞄准目标位置。严格来说,这不是作弊,因为有经验的玩家做同样的事情不会有问题。而且它甚至不像听起来那么致命,因为大多数远程技能都使用物理投射物(不是瞬间命中),其中一些具有弹道特性(受重力影响)。增加轻微的瞄准角度偏差不是问题;Paragon的简易难度机器人实际上做到了这一点,只是“完美目标”有助于修正一个机器人,以弥补与人类玩家的技能差距。此外,人类的大脑硬件支持的东西太多了(特别是视觉处理),为什么机器人要放弃一件与生俱来的东西呢!

  我们使用的另一个简单的技巧是解决一个来自混合人类机器人团队的玩家的投诉。问题是,游戏一开始,所有的机器人就开始在车道上奔跑。有人建议机器人应该等一会,等小兵出现。由于这是一次性行为,将其视为常规人工智能推理的一部分将是对性能的浪费。我们提出了一个非常简单的想法(并实施了),即比赛开始时触发的一次性行为。它使机器人等待小兵出现,然后沿着路线行走,直到他们看到敌人,或到达地图的中间,此时机器人切换到默认行为。沿着路线行走需要使用Paragon的自定义导航流场,这使得移动完全无需寻路,因此比常规AI导航便宜得多。一旦我们有了脚本化的行为支持,它在测试中也很有用。

32.8 Conclusion

  我觉得在游戏AI上工作是一门艺术,它利用现有的东西,为通常不那么简单的问题提出简单的解决方案。在本章中,我们展示了如何将这种方法应用于Paragon机器人上的工作。在时间紧迫的情况下工作时,重用和扩展AI系统尤其重要,因此提前投入精力使这些系统具有灵活性将在未来获得回报。否则,对Paragon中的所有机器人使用单一行为树是不可能的。当涉及到解决特定于游戏的问题时,通常最好提出一个简单的解决方案,通过提供一些易于理解的抽象,将问题隔离开来,并将复杂性隐藏在AI代码的其余部分中。The Ability Picker and Front-Line Manager 就是很好的例子。“保持简单”的原则永远值得遵循!

文章来源:http://www.gameaipro.com/  

如侵犯版权,请联系译者删除。  

读者若需要转载,请注明出处。   

若有错误,欢迎指正。


Paragon Bots:一麻袋骗人的伎俩的评论 (共 条)

分享到微博请遵守国家法律