构建无风险环境以增强原型提示执行行为树

10.1 Introduction
研究游戏技术是一个迭代过程。 做了一个又一个游戏,我们在尽可能的复用已有系统,但这种迭代对经历过验证的可靠系统几乎没有实质性的优化和改变。与此同时,游戏的创造性本质是渴望改变、原型设计和测试新想法,其中许多是在制作期间甚至项目接近尾声时出现的,这个时候去改变已有系统是风险最高的。 我们可以做些什么来提供一个无风险的环境来处理那些可能改变游戏规则的想法,还是不做?
Hinted-execution Behavior Trees (HeBTs) 试图解决这个问题。 该技术是对传统行为树模型的扩展,允许开发者基于一些高层逻辑动态修改BT的优先级; 新层以即插即用的方式工作,这意味着删除它不会影响其他模块的基本行为,这大大降低了风险。
在本章中,我们将介绍该技术——这是一个经过验证的解决方案,成功应用于 Driver: San Francisco 中的 AI——然后研究它的工作原理并展示 HeBTs 如何应用于实际的问题。
10.2 Explaining the Problem
电子游戏拥抱变化,原型设计则是必要的环节,也充满了乐趣,但构建这种体验需要开发人员和设计人员共同努力。这是一个双向的过程:设计师提出的想法被程序员转化为技术,但同时,这项技术将原始想法提炼出来,并将其转化为可行的东西。这种来回迭代的过程塑造了最终游戏的内容。
技术方面,程序员在高层面上实现具有可调参数的系统,设计师使用这些系统来构建游戏。这个工作流程如图 10.1 所示,在行业中非常常用。创意来自设计师,工程师实现想法,设计师根据实际表现提出修改意见,工程师接到反馈迭代优化系统。

这种工作流程的关键点在于,设计人员几乎无法控制系统内部的工作流程。通常这种情况是可许的,程序员把控实现细节无需设计人员关心。但是,从概念设计到实际落地可能是一个漫长的过程,对系统的任何更改工作量都很大(需要提出需求让程序员去实现)。理想情况下,希望设计师的想法能被快速验证和测试,而不需要向程序提需求做新功能。
上述方案可以减轻概念设计和实际落地之间的时间差,但也不一定适用所有情况。如图10.2所示的新的工作流程,需要设计师也具有技术能力,比如直接修改行为树,这有一定风险且可能产生的问题多于收益。

另一个必须考虑的因素是,电子游戏是非常复杂的工程系统,新游戏往往无法直接使用旧游戏的工程代码,需要做大量的修改优化,这意味着我们的解决方案必须能适应下一个新的游戏的工程代码。
本章中介绍的解决方案 HeBTs [Ocio 10] 是对传统 BT 模型的扩展。 它解决了这些问题,并允许快速和安全的制作游戏原型。
在以下部分中,我们将展示如何修改和操纵现有的 BT 实现,以允许额外的高级决策层动态更改我们行为的某些部分的优先级。
10.3 Behavior Trees
过去10,行为树越来越受欢迎,且已成为许多游戏的基本组成部分。在本节中,会介绍一下行为树的基础知识,因为理解本章下面的部分需要这些知识。更多关于BT的介绍可以参考 [Isla 05、Champandard 08、Champandard 13] 或 AiGameDev.com 上的各种材料 [AIGameDev 15]。
10.3.1 Simple BT
行为树是数据驱动的结构,以树或图的形式表示。行为树的节点为叶子或枝,叶节点代表一个动作或一个条件检查,即与游戏世界直接通信的节点。另一方面,分支节点不执行任何操作而是控制执行流程。在这个类别中,我们找到用于控制流(选择器、序列、并行等)或装饰器的节点。
用一个简单的例子展示下行为树的工作流程:

在我们的示例中,我们模拟了一个非常简单的士兵行为,如果它生命值过低,则会找掩护;若可攻击状态,则会保持警惕(或空闲)。
当节点更新时,它总是返回一个状态值:“成功”、“失败”或“正在运行”。 返回值由父节点处理,然后决定如何处理这些信息。因此,行为树中的执行流程来自其静态结构(即,不同的分支将以不同的顺序激活,这取决于我们使用的节点类型)。
示例树最重要的节点是选择器(图中用问号表示)。选择器允许我们在行为树中表示条件; 将其转换为我们可以在诸如 C++ 之类的编程语言中执行的操作,选择器是“if-then-else”构造的行为树版本。该节点有责任决定 AI 在任何给定节点将要做什么。本例中使用的选择器中的优先级来自于选择器子节点的定义顺序,即最左边的节点/分支为最高优先级,最右边的为最低优先级,导致静态优先级。
选择器尝试通过测试每个子分支直到一个成功来选择最好的子分支。 在示例中,我们将两个分支表示为序列。
序列是一种特殊类型的节点,它将按顺序运行其每个子节点,如果所有子节点都成功则成功否则失败。 因此,序列将非常频繁地测试一些先决条件作为它们的首要任务,如果先决条件通过,则可以并且将运行实际操作。
在图中,每个序列都有两个孩子:第一个节点是条件节点,或者只是检查世界中的事实的节点; 第二个节点是一个适当的动作,或者是对世界状态进行修改的节点。
最后,我们向我们的树添加了一个过滤器,在示例中它实际上是行为树的根。只要 AI 还活着,过滤器就会确保行为一直运行。
为简单起见,我们将继续使用上一节中的示例,但本章中介绍的概念可以应用于其他行为树。
10.3.2 Tree Complexity
我们正在研究的树非常简单——它只有少数节点——对其进行更改将非常简单。 问题是,在实际情况下,树可能有几十个或几百个节点,并且不容易修改。在一些解决方案中,通常会有好的工具来让我们更轻松的使用树(如,通过扩展/折叠分支或改进UI),但这并不能消除结构的固有复杂性。了解一个更改可能会对复杂树产生哪些影响和副作用并非易事。
回到图 10.3 中的示例树,在某个时刻,我们决定提高“攻击”分支的优先级,因为想让士兵更具有攻击性,甚至从不撤退。在这种情况下,将不得不修改树,这回使得【take cover】分支几乎无用。相反,如果我们决定只在某些情况下增加攻击的优先级会怎样?
仅仅通过使用基本模型,我们就可以通过几种不同的方式来实现这一点,比如添加一个新的选择器并复制树的某些部分,或者向【take cover】分支添加一个额外的先决条件,这还不错。
但是,如果我们希望 NPC 只攻击 5 秒然后撤退并且只对一些特殊标记的 NPC 这样做呢? 事情可能会变得复杂。 在这种情况下,我们最终会得到一棵类似于图 10.4 所示的树。
可能有更好的方法来重新排序树以适应新情况,但图中所示的方法足以证明我们的观点:修改行为树以适应新逻辑需要一些思考,并且总是存在风险。
在本章中,更关注那些在大型复杂行为树中进行的工作,且由于截止日期或生成里程碑不鼓励进行重大更改的案例,需要不断迭代已有系统。

10.4 Extending the Model
行为树是一项伟大的技术,但需要良好的技术能力和长时间的思考来维护它。上一节中研究的树的逻辑变化示例表明,简单树中的微小变化可能会导致难以理解的结果变化。逻辑变化是可怕的,极力避免的,有些结果可能会让制作人开心,但弊大于利。
本节中,提出HeBTs这种解决方案,这个方案的想法是允许更高级别的树的额外层与我们的主树同时运行,并让新逻辑的动态修改主行为树中的优先级。
10.4.1 Hint Concept
行为树和 hinted-execution counterpart 之间的主要区别在于,行为树的执行流程虽然由自己的结构定义,但HeBTs可以动态重新排序其分支以产生不同的结果。
该系统试图模仿现实生活中的命令层次结构,其中较低级别的级别由较高级别的人员告知应该做什么,但最终如何做取决于个人。 在我们的系统中,个体 AI 是一个复杂的行为树,它控制着 AI,因此它的行为是自主的,但我们希望设计师可以在更高级别的层上测试新想法。
非技术人员可能对 AI 的内部工作方式不感兴趣,只想告诉它做事(即,他们只想命令 AI “杀死敌人”,而不是“找到一条通往 你的敌人,然后靠近,拔出你的武器,向你的目标开火,在你需要的时候重新装填你的枪,等等”)。 这些建议在 HeBTs 模型中称为提示。
提示是 AI 可以从更高级别的来源接收的一条信息,并使用它来产生替代行为,作为优先级重新排序的结果。 这意味着 NPC 在保持其对不同情况做出正确响应的能力的同时,将考虑到命令层次结构中更高的请求,以使其行为适应这些请求。
10.4.2 HeBT Selectors
行为树中的大部分决策都发生在其选择器中,选择器会根据某些优先级尝试不同的可能性,直到找到匹配项。
在选择器的最简单实现中,优先级通常来自将分支添加到选择器节点的顺序。 所以这意味着我们所有的优先事项都是静态的。HeBTs 允许开发人员动态更改这些优先级,根据更高级别的逻辑片段传递给他们的信息,重新使用与其选择器关联的分支。 为了做到这一点,HeBTs引入了一种新型的选择器节点。
作为复合节点的选择器有一个子分支列表,每个子分支代表一个更高层可能希望节点选择的动作。 在我们的新选择器中,分支被分配了一个唯一标识符,该标识符在创建时分配。 这允许设计师工程师命名分支,从而创建有利于每个分支执行的提示。
提示可以是积极的、消极的或中性的; 如果提示是积极的,则树被告知要做某事; 如果是消极的,则被告知不要做某事; 并且,如果是中性的,则选择器根本没有收到提示。 中性提示用于将优先级重置为其默认值。
例如,假设我们有一个具有五个分支的选择器,分别命名为“A”、“B”、“C”、“D”和“E”。 我们刚刚实现了一个 HeBTs 系统,我们的高级逻辑告诉我们“D”和“E”是非常可取的,但“A”是我们真正应该尽量避免的。图 10.5 显示了新选择器将如何使用此信息。
新的选择器维护四个列表来控制他们的孩子和他们的优先级。第一个列表只是跟踪原始优先级; 三个额外的列表存储已被积极暗示(因此具有更高优先级)的节点、尚未被暗示的节点(它们是中立的)和已被消极暗示的节点(它们已降低优先级)。 这些额外的列表仍然使用原始顺序进行排序,因此如果暗示了两个或更多节点,AI 将根据其原始行为知道哪个动作更重要。

10.4.3 Hints and Conditions
通过到目前为止的修改,已可以使树能够接收 hints ,并重新排序由它们的选择器节点控制的分支。树设计者有责任公开他们认为对更高级别公开很重要的任何逻辑(即选择树将接受的提示)。
正如我们所说,行为树中的执行流程由非叶节点来控制。可以由许多不同类型的节点,但是简化传统的行为树模型,我们可以说大多数树都是选择器和序列的集合,如图 10.6 所示。

这些序列大多数都遵循一个基本模式——如图 10.7 所示——其中一些条件节点被放置为第一个子节点,然后是实际操作。这样,只有满足这些先决条件时才会执行操作。 如果其中一个条件失败,该序列将退出,返回失败,该失败可能会被选择器捕获,然后将尝试运行不同的分支。

在某些情况下,这对我们的提示不利,因为条件可能会使提示分支失败并且不被执行。 我们可以使用图 10.3 中所示的示例来说明这一点。
假设我们已经公开了前两个分支作为提示。 我们将使用“掩护”和“攻击”这两个名称。 假设我们想通过向树发送积极提示来提示 AI “掩护”。
按照我们定义行为树的方式,“take cover” 分支已经具有最高优先级,因此选择器并不真正需要对其子项重新排序(实际上,它确实重新排序了它们,但是这一次,分支的顺序不会改变)。 如果我们仔细观察第一个分支,我们可以看到“take cover”被构建为一个检查先决条件的序列(如图 10.7 所示),称为“low health”。
在 AI 满状态的情况下,先决条件将失败,从而使序列保释。 失败最终会传播到选择器,该选择器将运行不同的分支。因为我们在暗示 AI “take cover”,所以我们可能期望它考虑我们的建议,而不是公然无视它。
我们需要一种方法来忽略这些前提条件,即如果条件对于要执行的分支的其余部分并不是真正必需的。 在我们的示例中,我们实际上并不需要在低血量时去找掩护:这只是一个设计决策,可能试图使行为更可信。
为此,HeBTs 提供了一个提示条件节点。 这种类型的节点用于允许行为树测试它是否正在接收某个提示以及它的类型是什么(正面、负面或中性)。 我们可以修改示例的行为树来修改序列的先决条件,因此我们的分支将如图 10.8 所示。

10.5 Multilevel Architecture
在上一节中,我们介绍了 hints 的概念以及如何通过它们动态修改行为, 这些提示是通过我们所谓的“更高层次的逻辑”发送到我们的树上的。可以采用不同的方法来实现这些层级,如通过脚本层来使用系统生成新行为。
不过,过多的使用脚本会增加理解成本,因为需要一定的技术背景。 可视化解决方案会更合适,因为学习成本比编程要简单得多。为什么不利用我们构建的工具来生成我们的基础行为树,并扩展它?
10.5.1 Behavior Controllers
行为树是由动作序列组成的块构建的,它们是负责修改环境或AI实例本身状态的节点。根据系统的粒度,这些操作或多或少会有点复杂,从子行为(如“采取掩护”)到原子操作(如“寻找掩护点”)。对于对行为树内部工作原理不感兴趣的用户(只关心结果),粒度越粗,系统对它们来说就越简单。
修改大型行为树可能很复杂,可能需要考虑很多变量。此外,树中的微小变化可能会导致不好的行为,使 AI 无法按预期工作。因此,我们不希望从头开始创建新行为; 相反,我们只希望它们具有灵活性和可塑性。因此,让我们保留一个由工程师维护的基础树,并为团队提供创建新的更高级别树的方法。
更高级别的树使用一组不同的构建块。 具体来说,我们将用一些我们称为hinters的新节点替换动作节点。顾名思义,这些节点可以将提示发送到行为树的底层。新树将在我们的基本行为之上工作,动态修改它并允许设计师轻松安全地对新想法进行原型设计,因为主要行为树不会被永久修改,从而降低风险。
至此,我们的AI将由多层行为树控制而不是一个树,这组树将由一个行为控制器拥有。这些控制器负责维护多层级行为树,运行它们并生成结果。
行为控制器就像一个堆栈,我们可以在其中推送新树。 堆栈的顶部代表最高级别的逻辑,而底部包含基础行为树。每次新增一个新树时,控制器都会通知新创建的高级树它的直接低级树是什么,这将允许将提示发送到正确的行为树。 这种多级架构如图 10.9 所示。

当创建了所有不同的树并将其注册到行为控制器时,就可以执行最终行为。HeBTs从上到下运行,高级别优先运行。这意味着,当一棵树被执行时,它已经收到了所有的提示,并且它们的分支将被正确排序。 这个过程如图 10.10 所示。

在每次更新结束时,AI 将根据从环境中收集的信息和收到的提示,运行它认为具有更高优先级的任何操作。
10.5.2 Exposing Hints to Higher Levels
高级树使用基本行为树构建,并确定对它们可用的提示。在创建新树时,设计者可以为其选择器的分支命名,这将自动暴露相应的提示。以类似的方式,如果在低级树中的任何地方使用了条件提示,则该提示将自动公开。
高层级树不使用动作,只使用hinters,其允许树发送较低层级的树向它公开的提示,以生成新的行为。 在内部,它们是非常简单的节点:它们的逻辑只执行一次,并且在发送提示后立即退出。
需要注意的是,hinters可以发送不同类型的提示,允许我们发送积极的或消极的提示。 如有必要,他们还可以将提示设置回中性。
10.6 More Complex Example
到目前为止,我们已经研究了 HeBTs 是什么以及它内部是如何工作的。 并用一个例子来说明, 但该系统的潜力还尚未完全挖掘。因此在本节中,将展示一个更接近真实游戏的示例。
10.6.1 Prototyping New Ideas
有许多不同的方法可以修改行为以从运行相同逻辑的两个 AI 获得不同的响应。其中一些方法十分简单,如个性特征的使用。 但是,在现有行为之上添加更复杂的逻辑开始变得复杂,特别是如果我们不想或无法更改原始行为树。
在真实的项目中,我们随时都会发生变化,但是新的想法和变化可能会给项目带来很大的风险,或者需要我们负担不起的资源。 正如我们所看到的,HeBTs 允许我们轻松生成此逻辑,只需使用高层级行为树(建立在基础树上),引导其正常执行我们的新逻辑建议应该完成的操作。
10.6.2 Base Behavior
处理一种新行为需要我们有一个正常工作的基础行为,因为它将定义我们游戏中的 AI 对不同情况做出反应的方式。 在实际项目中,它也会经过彻底的测试和优化。
假设在我们的例子中,我们的设计团队决定游戏需要一些士兵:
在预定义的路线巡逻
当玩家进入他们的视野时,将玩家检测为敌人
一旦识别出玩家就攻击
如果受到伤害,将尝试找到掩护位置以继续攻击
这种行为将由复杂的行为树表示,我们在图 10.11 中展示了它的简化版本。

让我们来看看基本行为。 乍一看,我们可以看到由选择器控制的三个主要分支。我们将分支命名为【PATROL】、【COVER】和【ATTACK】; 这会自动公开具有相同名称的提示,这些提示可以由更高级别的树使用。 行为树的根是一个条件循环,它将保持树运行直到 AI 被杀死。
第一个分支定义了AI的战前行为。例子中,士兵会在没有敌人的情况下在该地区巡逻。正如我们在上一节中看到的,这种情况可能会阻止树在收到“PATROL”提示时按预期运行; 为了解决这个问题,我们添加了一个提示条件并将两个条件节点放在一个选择器下,这将允许我们在任一条件为真时进入分支。同时,使用一个并行节点来运行节点并将其作为断言(不断检测条件以确保始终得到满足),这样,一旦AI与敌人交战,分支结构就可以立即退出。
第二个分支保证当AI状态不好的时候会找掩护。与巡逻分支类似,我们添加了一个提示条件以确保树将正确使用提示。
最后是战斗分支,跟【COVER】分支类似,通过断言assertion来确保AI只有在没有受到攻击时才会触发战斗。
10.6.3 Prototype Idea
理想情况下,系统正常运行后,工程师大部分工作将用在调试和迭代改进行为。有时设计师需要不断测试新想法以不停改进游戏体验,此时就需要对已有行为做改动。这时HeBTs将会发挥作用。
为了展示新系统的功能,将会用一个高层级树来实现一个“伪装”系统。功能设计是:
玩家可以穿上他们杀死的敌人的衣服,如果他们这样做,其他 AI 就不会注意到
AI 不应将“伪装”的玩家识别为敌人,但如果被玩家攻击,AI需要做出反应。
基本上,这些更改需要修改游戏玩法和 AI 代码,而这项新功能无法进入最终游戏。因为游戏使用了 HeBTs,我们可以将新想法的原型设计委托给设计团队,或者至少让他们在最少的技术监督下尝试新想法(如果我们有适合这项工作的工具)。
我们必须牢记,如果我们想要一个几乎不需要扩展任何编程工作的系统,我们必须从正确设计我们的基本行为开始。 此外,构建一套完整的树节点和条件可以促进进一步的工作。
10.6.4 Creating a High-Level Tree
作为设计师,希望新系统可以让AI忽略“伪装”的玩家,所以,底层树更倾向于【巡逻】。高层级树的第一次遍历与图 10.12 中所示的非常相似。

简而言之,这就是我们的高层级树应该有的样子,不过仍需定义条件来检测玩家是否在伪装,但树里没有这种类型的条件。
系统需要一种方式来让AI维护一些关于世界的知识,常见的方法是使用黑板系统。 假设我们确实有这样一个系统,我们可以在其中编写信息并从那里获取有关世界状态的详细信息。此时,状态会被转换成“敌人伪装了吗?”,该状态会在黑板系统中检测相关信息。但是,如果我们需要从黑板上读取这些信息,我们必须先将它设置在某个地方。
简单起见,将使用【broadcast】操作把数据写入黑板系统,这样(通过将此信息写入到黑板)可以让游戏世界的其他AI在一个AI死亡后立即获取到该信息。由于我们在高层级树上的第一遍已经在检查 AI 是否还活着,让我们扩展树以正确修改黑板。 我们在图 10.13 中展示了这一点。

要做的第一件事是添加一个额外的序列作为树的新根,在运行【while alive】分支时始终有一个黑板更新跟随它。此外还添加了额外装饰器作用旧序列的父级,目的是忽略序列中失败时的情况(事实上,每帧都是失败的,除非玩家在【伪装】),我们并不希望分支失败,这样会破坏根序列。
以上,当AI活着时,行为树会持续检查黑板来决定是否提示基础行为树去巡逻,除非AI死亡否则黑板将始终更新着。当一个AI死亡时,其余AI将会更新其黑板,并向其基础行为树发送【PATROL】提示,并按照设计忽略玩家。
这是个好的开始,但行为树还不完整,此时AI还不会对伪装中的玩家造成的伤害做出反应。解决办法是当AI受到攻击的时候同步清理黑板数据。最终的高层级行为树如图 10.14 所示。

在最后一棵树中,我们添加了一个额外的选择器,用于捕捉敌人是否被攻击,清除伪装标志。 选择器的第二个分支与我们之前的迭代相同,最后,第三个分支只是确保,如果没有任何事情发生,“PATROL”提示被清除。
10.6.5 Analyzing the Results
这种类型原型设计的关键是新逻辑是完全可选的。 让系统知道它并观察AI在额外特征下的行为,或者可以删除高层级树,这将保持原始行为不变。
基础行为只需少量的数据变动,除非使用高层级树否则这些更改没啥用。特别是,我们一直在用两种修改方式:分支命名是一种无害的更改,根本不影响行为;提示条件确实会修改树的原始结构,但由于它们是简单的标志(提示)检查,如果不存在高层级树,则永远不会启用提示,因此带来的风险非常小。 提示条件也是可选的,在某些情况下,我们可能根本不想使用它们。 简单地预先命名分支将暴露动态优先级控制。
10.7 Other Applications
在本章中,我们重点介绍了 HeBTs 为快速安全原型设计带来的好处。 这些树也可用于在其他情况下提供帮助。 在本节中,我们将展示一些可以从使用 HeBTs 中受益的额外场景。
10.7.1 Adaptation
有很多种方法让游戏适应不同类型的玩家。其中,我们发现“难度级别”这个选择功能(或其他适应玩家的难度改变),可以让我们未不同的人群提供更好的量身定制体验。
HeBTs使我们可以为每个玩家提供不同的游戏体验,允许动态修改内容:为每个类别定义不同的高层级树,并在运行时决定哪个最适合玩家;基础行为树将根据收到的提示重新计算其优先级,使玩家更好的享受游戏。
这就是 Ubisoft's Driver: San Francisco 使用的方法。 在 Driver 中,逃跑的司机能够调整他们的路线选择算法——由行为树控制——通过实施一系列不同的高层级树来指导路线生成过程 [Ocio 12]。 这些高层级树被称为“预设”,它们做了一些事情,例如让路线查找器更喜欢直线路线(这样休闲玩家可以更容易地抓住逃跑路线)到曲折路线或穿过土路或小巷的路线。
10.7.2 Group Behaviors
我们的hinted-execution模型还可用于基于命令层次结构创建复杂的组行为。 提示会沿着链条向下流动,允许一些 AI 更好地控制其他人应该做什么。
在基于提示的系统中,可以在已有链接上创建新连接,作为构建在多个基本行为上的高层级树,而不仅仅是一个;在这种情况下,每个基础行为树都会公开特定类别的AI可以接受的指令,高层级树将能够向其基础行为的AI广播提示。
这方面的一个例子是一支拥有战士、弓箭手和医师的小型军队。 图 10.15 显示了它们行为的简化版本。

我们可以使用不同的将军,定义不同的高级树来创建一支服从我们想要发送的命令的智能军队。 例如,我们可以构建一个高级人工智能,它想先用弓箭手攻击,阻止战士和医疗兵,然后继续进行近战类型的攻击,包括派遣医疗兵和战士一起尝试治疗受伤的单位, 绝不允许部队撤退。 控制这种行为的高级树如图 10.16 所示。

单位组(作为高级实体)也将由 HeBTs 控制,因此它们也可能会收到提示,从而产生复杂的指挥链,可以帮助我们创建更可靠的组行为。
10.8 Conclusion
行为树 是一种经过验证的技术,已在许多成功的商业游戏中使用。但是,与任何其他技术一样,任何更改都是有风险的,尤其是如果这些更改是在生产的最后阶段进行的。HeBTs 试图通过提供一种对更大、更复杂的行为树进行动态、可恢复修改的方法来降低这些风险。 这些修改也由另一个行为树(我们称之为高层级行为树)控制,因此我们仍然可以利用该技术的强大功能和可视化编辑功能。
正如我们在本章中所展示的,HeBTs 可以帮助解决许多不同的问题,例如快速原型设计、动态行为适应或群体行为。 在任何情况下,风险都保持在较低水平,因为我们永远不会失去我们经过测试的基本行为。
这项技术并不难在现有行为树系统之上实现,并且还被用于 AAA 游戏 Driver: San Francisco。 HeBTs 是游戏 AI 成功的关键,允许开发人员根据玩家的行为调整AI的行为。
References
[AIGameDev 15] AIGameDev.com. http://www.aigamedev.com/.
[Champandard 08] Champandard, A. J. 2008. Getting started with decision making and control systems. AI Game Programming Wisdom, Vol. 4, pp. 257–263. Boston, MA: Course Technology.
[Champandard 13] Champandard, A. J. and Dunstan P. 2013. The behavior tree starter kit. In Game AI Pro: Collected Wisdom of Game AI Professionals. Boca Raton, FL: A K Peters/CRC Press.
[Isla 05] Isla, D. 2005. Handling complexity in the Halo 2 AI. In Proceedings of the Game Developers Conference (GDC), San Francisco, CA.
[Ocio 10] Ocio, S. 2010. A dynamic decision-making model for game AI adapted to players’ gaming styles. PhD thesis. University of Oviedo, Asturias, Spain.
[Ocio 12] Ocio, S. 2012. Adapting AI behaviors to players in driver San Francisco: Hintedexecution behavior trees. In Proceedings of the Eighth AAAI Conference on Artificial Intelligence and Interactive Digital Entertainment (AIIDE-12), Stanford University, Stanford, CA.
文章来源:http://www.gameaipro.com/
如侵犯版权,请联系译者删除。
读者若需要转载,请注明出处。
若有错误,欢迎指正。