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

让你的AI更健壮 | Game AI Pro

2020-05-14 10:34 作者:有木乘舟  | 我要投稿

But, It Worked on My Machine! How to Build Robust AI for Your Game 

Sergio Ocio Barriales

7.1 Introduction

  每一个AI工程师人在职业生涯的某个时间点都经历过这个阶段:你是如此年轻,充满活力,渴望向每个人证明,你可以完成一番伟大的事业,你还可以用最快的速度完成这番伟业!你完成你的功能,在地图上测试它,现在它就在游戏中了。工作完成了,是吗?

  有效的测试能确保我们的人工智能满足设计要求,并对不可预见的情况做出适当的反应和处理。经验可以帮助你识别常见的陷阱和错误,经验丰富的人工智能开发人员可以识别这些问题,并用测试数据集和类别来捕捉问题,从而使他们的系统更加健壮。在本章中,我们将展示其中的一些策略,分析不同的场景,并提供一些技巧来帮助人工智能工程师利用一些内部知识来进行人工智能测试。

7.2 Presenting Our Example

  调试可能是个非常抽象的话题,因此为了让使本章更易读,我们将提供一个示例,并用它来说明在创建AI角色期间可能用到的不同测试。

  假设这里有一个狙击手,带着一把配备了瞄准镜和激光瞄准器的狙击步枪,这大大提高了狙击手的射击精度。同时,狙击手还随身携带一把手枪,应付近距离战斗。这个角色可以在很多动作游戏中找到,而且他们通常表现出类似的行为。

  如图7.1所示,我们的狙击手将有三个主要状态:战前状态、战斗状态和搜索状态。

  如果狙击手发现敌人,他们就可以投入战斗。一旦到了那里,他们就可以去搜索目标是否丢失,如果敌人被重新侦察到,就有一定几率重新返回战斗状态。狙击手离开这个状态后不能回到战前状态。

7.2.1 Precombat

  在战前状态,我们的狙击手会在n个点之间巡逻,每一个点都会停下来。在那里他们用步枪扫荡这个地区。在这种状态下,狙击手完全不知道敌人的存在。

7.2.2 Combat

  在战斗状态中,根据与敌人的射程距离,狙击手有两种选择。在远距离,狙击手会用步枪瞄准并击落敌人。在近距离,狙击手将使用手枪射击,并采取常规的射击游戏人工智能策略。 

7.2.3 Search

  如果狙击手在战斗中失去敌人的身影,狙击手将进入搜索状态。在搜索状态下,狙击手首先确认敌人不在他们最后知道的位置。在搜索过程中,如果发现了敌人的踪迹,狙击手可以用的步枪扫荡区域,或步行检查附近的区域。

7.3 Basic Functionality Tests

  在我们实现了狙击手的初代版本后,首先要验证的是该原型是否能够按照设计文档描述的正常工作。请注意,在真实场景中,  我们不会在开始测试之前实现整个敌人的AI,而是遵循一个迭代过程。本章中描述的测试,特别是基本功能测试,应该在我们开发完整功能时应用到较小的部分。

  当我们确定该原型能正常工作时,下一个步骤就是想尽各种办法去干扰他正常工作。这是测试人工智能角色最困难的部分,因为每一个简单的改变都可能对其他系统产生无法预料的影响。

   在下面的部分中,我们将重点介绍构成人工智能代理的不同部分,如感知、反应和导航,并将展示与每个案例相关的一些潜在测试。我们希望该实验能为读者提供足够的信息,使他们能在自己的AI角色上识别出类似的问题,特别是一些需要额外注意的领域,同时希望这些经验帮助他们更好的完成自己的工作。

  所以让我们开始谈正事吧!

7.4 Perception Stress Tests

  当我们谈到感知时,我们指的是使人工智能意识到周围环境的所有系统,特别是那些允许它检测其他实体的系统,比如玩家。传统上,这包括人工智能角色的视觉和听觉,但它可能涉及其他感官,这取决于我们正在研究的游戏和/或人工智能的类型(例如,狗的嗅觉跟踪)。

  让我们关注一下视觉系统。为此,我们的狙击手可能会在他们的头部周围使用一些圆锥体或盒子,帮助他们确定可以看到哪些敌人。作为我们基本功能测试的一部分,玩家或敌人应该是可以被检测到的,但为了保险,还是会用边缘案例测试一下。

  狙击手有两种感知模式,这取决于它使用的武器:狙击步枪和侧手枪,所以我们必须分别测试它们。

7.4.1 Rifle Perception Testing

  我们的狙击步枪有一个激光瞄准器,这在游戏中非常常见。激光通常用来表示狙击手所在的区域和他正在观察的方向。

  假设激光的长度为60米,此时一个狙击手正在通过他的瞄准器观察一片区域,我们决定在狙击手前方59米的地方出现。但是,什么都没有发生,为什么?

  这个问题最常见的答案是,我们的视力范围与激光设定的期望值不符。我们应该增加狙击手的射程吗?问题如图7.2所示。

  扩大视锥的危险在于,如果我们想保持相同的视场(FOV),我们不仅要扩大视锥的长度,还要扩大视锥的宽度。当前,这取决于具体的视觉系统实现,但还是先假设我们使用视锥是为了简单起见。

  这个视距问题引出了更多的问题。例如,如果狙击手透过步枪瞄准器看东西,他(她)可以看到视锥外的东西吗?

  经过进一步的测试和与设计的讨论,我们可以决定修改狙击手的视野,并有一个较短的圆锥体和一个包围激光的盒子,如图7.3所示,也许这样就可以解决问题了。

  我们可以做一些额外的测试,以确保所有可能的目标距离按预期工作,我们还应该检查狙击手不会检测到不在其视觉模型定义的区域内的敌人。

7.4.2 Pistol Perception Testing

  狙击手在使用手枪时可以处于常规警戒模式,因此我们重新测试常规感知。一切看起来都很好,但是突然我们注意到狙击手发现了很远的东西。为什么?好吧,答案通常是我们错误的把为狙击步枪设计的新视觉模型应用到了手枪上。因此只要做一些改变,就能修复这个BUG。

7.5 Reaction Stress Tests

 一个好的人工智能角色应该能够以合理的方式对多种不同的刺激做出反应。不做出反应或做出错误的反应很容易破坏玩家的沉浸感。反应测试主要寻找真实性问题,也就是说,那些看起来不好或者破坏了人工智能特征可信度的反应。

  在这里,我们专注于试图打破人工智能的反应。让我们更详细地看一些反应类型。  

7.5.1 Spotting the Enemy

  人工智能应该能够探测到任何状态下的敌人,我们通过应用上一节给出的测试来检验这一点。我们现在需要反复试验的是,当侦测行为发生时,狙击手会不会播放适当的反应行为(如呼喊 和/或 动画)。

  我们要测试的第一件事是我们的动画在近距离是否合理。当人工智能看到在正前方 40米处看到敌人,或者敌人刚刚撞上人工智能时,播放的动画应该是不同的。在后一种情况下,应该让人工智能表现出更夸张的行为。

  另一个潜在问题是,当狙击手装备了狙击步枪时,在遭遇到需要使用手枪来近距离战斗时,会表现出反应变慢的问题。在反应完成后才切换武器,会让AI看起来像机器人,而且速度会慢一些,所以最好可以在特殊情况下,额外增加一些动画, 将武器交换烘焙到AI反应中,让整体效果看起来更自然一些。

7.5.2 Shooting at the AI

  我们还应该测试人工智能在被击中时的反应。我们需要检查人工智能是否总是会对此做出反应,尽管在整场战斗中,这种反应不易察觉。

  我们还应该检查不同的动画看起来是否同样可信,这取决于使用什么武器打击人工智能,它被击中的程度,身体的哪个部位受到影响,等等。根据游戏的不同,这些反应的系统可能或多或少是复杂的。

7.5.3 Reacting to Nondamage Events

  如果我们不直接向人工智能射击,而是开始做一些事情,例如向附近的地面射击、吹口哨或扔石头,我们的狙击手需要对所有这些不同的刺激做出适当的反应。根据事件类型和攻击性(例如,响亮的枪声和关闭的灯光开关),狙击手应该以不同的方式做出反应。

  我们测试的目的是确保反应符合设计,并且有意义。我们可以尝试的测试有:

  • AI能连续对两个事件做出反应吗?

  • 如果这些事件属于同一类型呢?我们是不是一次又一次地做出同样的反应?在这种情况下,我们可能需要添加一些反应代码,来逐步加强AI的反应,并有可能过渡到不同的状态。

  • 当人工智能还在对前一个事件做出反应时,它能处理第二个事件吗?

  • 人工智能会在对第二个刺激做出反应之前完成当前的反应吗?这个看起来坏了吗?

  • 如果第二个事件的优先级较低(例如,投掷石块与子弹撞击),则可能会忽略第二个事件。

  • 相反,如果第二个事件具有更高的优先级,则是否立即处理此新事件?

  • 人工智能在对第一个事件做出反应的同时能够对第二个事件做出反应,这现实吗?

  • 人工智能是否根据与事件的距离做出适当的反应?例如,如果狙击手听到身后有枪声,可能会比听到50米外的枪声时显得更激动。

7.6 Targeting Stress Tests

  现在我们已经仔细检查了我们的人工智能是否能够检测到敌人并对他们所做的一切做出反应,现在是时候确保它能够正确地处理被多个目标或来自不同的、意外方向的攻击。

  根据游戏和实现,AIs可以使用敌人的实际位置来选择他们的行为,或者他们可以保留最后一个已知位置(LKP,last known position)(Champandard 2009)。LKP通过个人人工智能感知系统或与一组人工智能共享的感知进行更新。为了更好地说明这些测试,我们将在AI中使用LKP,但我们不会详细介绍LKP是如何工作的,并会在示例中简化一部分细节。

  通过我们的测试,我们想验证两件事:首先,我们需要知道当玩家被检测到并根据需要更新时,LKP会被合适地设置。第二,我们需要知道LKP是否在正确的时间传播到其他AIs。

7.6.1 LKP-Updating Tests

  当狙击手发现敌人时,它会做出反应,然后投入战斗,只要视线保持不变,设置一个LKP并更新它。在一个大事件发生后(例如敌人被人工智能发现)测试LKP被创建或更新到一个新位置的最佳方法是将敌人传送到人工智能周围的随机位置,并在空中发射一支高射炮(或者根据游戏的设计,使用任何其他导致向战斗过渡的事件):当LKP设置好后,我们将敌人移动到另一个位置,再次触发事件,并继续执行此操作几秒钟,确保LKP相应地更新。

  为了在正常的游戏场景中测试以上内容,我们可以设置一个不死的敌人,创建一个LKP,并让其绕着人工智能移动。在这个过程中,人工智能有可能会丢失目标(我们),这就意味着出现问题了。在现实生活中,如果有人在我们周围兜圈子,我们一定会注意到他,所以我们的人工智能也应该一样!这种丢失目标现象可能是由于LKP更新与视觉系统的耦合过于紧密所致。

  为了解决这个问题,我们可以增加一些时间缓冲,这样当敌人被判定为丢失之前,会有几秒钟的失明现象。我们也可以这样做,即使视觉丢失,人工智能还是能看到敌人(当然在这之前一定要先看到敌人),并且还是能重新将视线投向敌人,这意味着敌人无法隐藏自己的坐标位置。我们可能需要两个系统的组合才能获得最佳结果。

  我们还应该确保我们的游戏使用的任何检测HUD都能按预期工作。当玩家在被发现的过程中,被完全发现时,或是人工智能丢失玩家的目标时,这个系统就会对玩家产生作用。人工智能目标代码的更改也需要与HUD进行交叉测试。

7.6.2 LKP Propagation Tests

  隐身技术在主流动作游戏中变得越来越重要,因此与感知、反应和玩家位置相关的一切都应该得到彻底的测试。

  LKP传播是一种典型的系统,单个人工智能个体通过该系统,来与某个区域中的其他人工智能联系,或标记出具有威胁的区域位置。我们需要多次检查传播是否真的发生了,但我们也必须确保LKP不会在反应的过程中传播。

  延迟的目的是给敌人一个机会,在他们的位置在被探测到后,并在受到伤害之前,消除潜在的问题(例如,摧毁探测器),如图7.4所示:

7.7 Unreachability Stress Tests

  一旦LKP被正确设置和更新,我们就需要更进一步的,去测试当人工智能发现敌人处在一个无法到达位置时,人工智能会表现出何种行为。我们还需要检测,当敌人出现在人工智能看不到的地方时,人工智能的行为。在这些情况下,人工智能至少能表现出一种适当的可信的行为。

  如果人工智能可以看到一个无法接近的敌人,我们希望人工智能可以移动到一个合适的位置,这位置可以让敌人保持在视线之内,并且尽可能可以被攻击到。

  考虑到这一点,我们的第一组测试应该能够回答这些问题:

  • 如果无法到达LKP,人工智能是不是会被卡住?

  • 如果敌人从一个无法到达的位置攻击,人工智能是否会进入战斗状态?

  • 如果LKP可见,但无法抵达,人工智能是否会维持战斗状态?

  如果看不到无法到达的位置,人工智能也应该表现正常。并且,如果敌人想利用这种情况来攻击人工智能的话,我们希望人工智能可以呆在原地,然后准备防御敌人的攻击。在确保人工智能没有陷入这种情况之后,我们可以执行一些额外的测试,比如:

  • 人工智能是直接穿透墙壁瞄准LKP吗?我们应该避免这种情况,像战术环境感知系统(Walsh 2015,Tactical Environment Awareness System)这样的系统可以帮助我们决定人工智能应该瞄准的位置。

  • 人工智能的目标是合理的吗?

  • 如果敌人从未被重置,并且LKP保持不可接近和不可见,人工智能是否会陷入无止境的战斗状态中?这是一个需要游戏设计师来回答的问题,但我们可能想在LKP中暂停,好让人工智能从这种情况中恢复过来。

  • 如果有一个位置,人工智能可以移动以获得对敌人的视距(LOS),人工智能是否会移动过去?

7.8 Navigation Stress Tests

  射击动作游戏中的人工智能角色通常一辈子都在做以下两件事之一:播放动画和点对点导航。糟糕的导航会让玩家失去沉浸感,所以花一些额外的时间来调试它,确保它工作正常,会有回报。

  回到狙击手的例子。在我们的设计里,在战前状态,狙击手在A点和B点之间巡逻, 并在与这个有利位置相关的一组点之间进行扫描。所以让我们跟着狙击手去看看它能做什么。

  狙击手在A点,完成扫描,开始向B点移动,手里拿着步枪。根据游戏和动画预算的不同,角色双手持武器行走的动画可能是为小型武器准备的,这种情况下狙击手的动作看起来会有些滑稽。解决这个问题的一个办法是让狙击手在移动到一个新的点之前收起步枪,要么手持手枪移动,要么手无寸铁。我们的工作是利用手头的工具和资源找到最漂亮的结果。

  另一个需要测试的是战斗中的导航。我们这里有一些可能出现错误或不希望出现的情况:

  • 人工智能能用现在装备的武器正常地跑动和寻找掩护吗?

  • 人工智能可以停止行动,假如敌人挡在路上或者移动?

  • 我们什么时候,该如何去检测这种情况?

  • 人工智能会选择一个新的目的地然后不停的移动吗?它只是停在原地保持姿势吗?在决定移动到一个新点之前,它会播放某种反应动画吗?

  • 如果人工智能靠近敌人,人工智能会盯着敌人吗?

  • 它应该扫射敌人吗?它应该瞄准敌人吗?

  • 人工智能的移动速度是否合适?

  • 人工智能会穿越(a traversal)障碍物吗?(例如梯子,或能够跨越缝隙or障碍物)

  • 如果有两扇门可以进入一个房间,并且已经有另一个AI使用其中一个门,那么被测AI是否选择了另一个门?

  • 人工智能能打开他路径上的门吗?

  • 如果人工智能超出导航网格的边界,它会怎么做?

  • 如果游戏有不同层次的细节,人工智能导航是否在正确的低LOD上?

  当人工智能导航时,我们也应该尝试做反应测试,看看我们是否能破坏他的正常工作流程。关注过渡点可能是最好的方法。例如:

  • 如果人工智能进入掩体,而我们暴露了掩体,它会有什么反应?进入掩体的行为是否被破坏?

  • 如果人工智能在穿越障碍物的时候被攻击,那么穿越动画会结束吗?人工智能会掉出导航网格吗? 

7.9 Weapon-Handling Stress Tests

  当我们的人工智能可以使用多种武器并在任何时候在它们之间切换时,就像我们的狙击手在步枪和手枪之间切换一样,我们需要确保武器交换这一过程正确进行。特别是,我们希望避免人工智能处在手无寸铁的状态。

  回到狙击手的例子。我们对前一节的内容做了一些修改,在战前状态中,允许他在导航的时候不使用武器。所以现在我们有三种可能的场景:狙击手拿着步枪,狙击手使用手枪,狙击手没有武器。

  最简单的测试就是检查基本的功能,也就是说,确保在人工智能没有被打断的情况下,武器转换能按预期工作。然而,最有意思的是需要试着去破坏武器转换这一过程。对于我们的特定示例,我们要测试以下内容:

  • 在战前状态中,狙击手准备从A点移动到B点,因此执行收枪的动作。但如果敌人在动画中途突然攻击,人工智能能正确播放受击动画吗?枪会掉吗?他能把枪收好吗?我们直接让动画结束?

  • 如果狙击手没有武器而被击中,它会在反应动画结束后装备武器吗?哪一个?另外,如前所述,我们可以在装备武器这一过程配置反应动画,使其人工智能看起来反应迅速。 

  • 如果狙击手刚刚到达B点并开始抓起步枪,如果它这时候被击中会怎么办?

  • 如果狙击手发现近距离内有敌人,并开始收起来福枪,以便拔出手枪,而这时候敌人射击人工智能,会发生什么?

  • 如果敌人在战斗中逃跑后狙击手开始考虑放弃目标,并试图进入搜索状态,把手枪收起来,装备步枪。如果人工智能在这个过程中被击中,它会怎么做?

其他有趣的测试与武器重新装填有关。在这种情况下,我们要回答的主要问题是,如果人工智能在换子弹过程中被击中:

  • 动画全都播放完了吗?动画被打断了吗?

  • 武器重新装填完毕了吗?

7.10 Exotic Elements Stress Tests

  我们用来构建角色的一些不同系统可以在不同的原型之间共享,也可以在不同类型的角色之间重用,只需稍作修改或调整。不过有些部分只能适用于特定的角色,如狙击步枪。这些额外的元素使我们的角色看起来特色鲜明、各不相同,因此我们需要花费额外的工作在这些地方,并确保其正常工作,看起来漂亮。

  由于这些组件的独特性,测试会有些难度,但我们主要的目的,就是测试并确保这些特性不会被破坏。例如,对于狙击步枪的激光,我们可能需要测试以下各项:

  • 激光射出来的位置对吗?

  • 激光会在武器移动时跟随吗?激光是独立于武器运动的吗?

  • 如果是,偏差是否明显?

  • 是否有理由允许激光独立运动?

  • 激光在任何情况下都工作良好吗?例如,当狙击手收起武器时,我们应该用激光做什么?应该关掉吗?如果狙击手受到了一次剧烈的打击导致移动幅度过大,这个移动幅度对激光来说是可以接受的吗?

7.11 Group and Timing Stress Tests

  在这一点上,当我们的人工智能作为一个单独的单元运行时,它应该是健壮的、有趣的和可信的。但是,如果我们开始将我们的角色与相同和/或不同类型的其他角色一起使用,会发生什么情况?

  我们可以执行的测试有:

  • 如果一组人工智能接收到一个事件,它们是否对该事件的反应完全同步?我们可能想在反应中加入一些小的、随机的延迟来做一些平滑。

  • 不同类型的人工智能能很好地协同工作吗?有没有什么类型的行为会破坏组内其他人的行为?例如,狙击手可以从更远的距离发现敌人,当敌人仍在LKP时,可能会在其他人工智能执行反应行为之前,就迫使整个小组进入搜索状态。如果我们认为这些交互对游戏有负面影响,我们可能希望能够更好的控制它们。例如,在上面这个能够快速检测LKP的狙击手例子中,如果组内有非狙击手角色(且能到达敌人的位置),我们可以设置障碍,防止狙击手检测敌人LKP。

7.12 Conclusion

  建立良好的人工智能需要付出额外的努力。确保我们的角色遵循游戏的设计是第一步,但长时间的工作调整和测试应该遵循我们最初的设计方案。

  善于发现问题,或者知道如何改进并将特性提升到下一个层次,这是每个人工智能开发人员都应该具备的一项重要技能,也是我们随着时间和实践、讨论和建议而不断改进的一项技能。

  读者可能已经注意到本章中介绍的所有测试都是一步步推进的。我们首先测试在不受干扰的情况下是否正常工作,然后人为的生成一些问题,并以不同的方式抛向人工智能,以检查系统如何处理这些中断:人工智能在被中断时如何反应?比如说,人工智能在交换武器的时候被击中。

  如果我们要求它同时做两件不同的事情会怎么样?例如,当人工智能正在对一个事件做出反应时,接收到第二个事件。

  除此之外,我们一直在关注非计划内的结果(比如狙击手在我们修改了他们的视箱后在扩展范围内探测玩家),并始终确保每一个系统,即使它与我们的变化没有直接联系,仍然按预期运行。

  我们希望读者已经完全理解了测试人工智能角色可能遇到的问题,并且希望本章中介绍的技术和示例,能成为读者们解决工作中遇到的测试难题的一个起点。

References

Champandard, A. J. Visualizing the player’s Last Known Position in Splinter Cell Conviction.     http://aigamedev.com/insider/discussion/last-known-position/(accessed May 15, 2016). 

Walsh, M. 2015. Modelling perception and awareness in Tom Clancy’s Splinter Cell     Blacklist. In Game AI Pro 2: Collected Wisdom of Game AI Professionals, ed. S. Rabin.          Boca Raton, FL: A K Peters/CRC Press, p. 313.

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

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

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

若有错误,欢迎指正。

让你的AI更健壮 | Game AI Pro的评论 (共 条)

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