人工制作vs系统自动化:《神秘海域4》中的战斗AI平衡解读

作者:Rouder,本文首发知乎

地址:https://zhuanlan.zhihu.com/p/261111487


Part . 1


1.1 Combat Design in Uncharted 1-3


神海4团队首先介绍了神秘海域第一部到第三部的战斗设计。神海前三部作品的战斗流程设计高度依赖硬编码。


他们提出了分区式NPC的概念,NPC只可以在指定的区域进行移动、战斗。策划需要在场景里设置好区域,保证NPC整体上可以覆盖到玩家所有可能的前进路线。



这么做的优点是,NPC可以均匀地分布在场景中,防止他们聚集到一起,还能产生一种NPC在智能利用空间地假象。缺点是,策划需要想到玩家所有可能前进的路线,为所有路线设置好分区。由于前三部的战斗场景比较小,战斗流程较为线性,所以分区式NPC机制运行良好.但是第四部的战斗场景得益于PS4的性能而扩大了很多,此机制没有办法良好运作。


在给NPC手动分配区域需要一些技巧。首先要让场景中地部分NPC的分区跟随玩家进行移动。这种区域作为前方战线, 使得玩家无论移动到哪里都可以感受到NPC的存在,保持战斗过程的持续紧张感,不会走到一个地方就突然没有了敌人。然后让场景中部分NPC的分区固定在场景的出口附近,并且将这些区域设置得大一点。这种区域作为后方战线,而且在战斗结束后,玩家正好面对出口,起到了引导玩家前进的作用。最后让场景中部分NPC的分区固定在视野最好的地方,并且将这些区域设置得小一点。这种区域作为聚集点存在。


狙击点


上面提到的区域不但可以静态设置,还可以在运行时根据战斗情况进行调整。接下来用两个例子进行说明。首先来看一下第一个例子,注意观察左方阳台的NPC。


动态分配区域:玩家走左边的情况


系统自动为一个NPC分配了一个区域在阳台上


动态分配区域:玩家走右边的情况


系统自动为一个NPC分配了一个区域在阳台下方。然后玩家等NPC走到油桶附近再把油桶打爆,瞬间可能觉得自己很帅,但是其实都是策划设计好的。


再来看一下第二个例子


动态分配区域的例子二


前方的NPC倒下后,后面的NPC分区会依次设置到前方。有利于保持战斗节奏,持续给予玩家压力。


1.2 Uncharted 4 Design Goals


由于游戏的运行平台从PS3升级到了PS4,性能得到了提升。团队希望实现在大场景下的战斗,以下是马达加斯加的战斗场景。



虽然还是线性战斗流程,但是增加了广度。神海前3部所使用的单纯的分区式NPC机制不再适用,神海团队对该机制进行了调整。


有了这么大的场景,就希望提升主角攀爬能力在战斗中的实用性,所以可探索的垂直空间也增加了。NPC也需要由一套良好的系统来处理攀爬。


前三部在潜行的过程中被法线就没有办法回到潜行状态。这次需要实现一套完整的潜行循环流程,在非战斗、战斗、潜行状态之间进行切换。


一场战斗中同时出现的NPC数量从8个增加到了16个,需要更好地调度敌人。


降低策划地工作量


1.3 Fundamental AI Technology


已有的以及为实现神海4设计目标而提出的基础AI技术


1.3.1 框架概念



Skill拥有一个状态机,例如战斗Skill地状态机有开放战斗状态和掩体战斗状态。Skills是一个由Skill组成地优先级列表,运行时会实时判定各个Skill是否开启,然后再所有被开启的Skill中选择优先级最高的Skill作为当前Skil。Behaviour代表具体的行动,例如移动到一个点、进行设计。Locomotion Controller用于移动NPC和驱动动画,类似Unity的Animator。Bahaviours是一个由Behaviour组成的堆栈,还会去合理的调用Locaomotion Controller。当Skill的状态机确定一个状态后,会将多个Behaviour压栈到Behaviours。


1.3.2 Post


Post是地图上的位置标记,供NPC使用


1.3.2.1 手动标记的数据



黄色区域代表可正常行走区域,绿色区域代表可潜行区域



绿色线段链接的地方可以执行特殊的动画(例如上窜下跳、跃过裂缝、翻越掩体等)来越过障碍。这些特殊动画都需要定义入口、循环体、出口,所以一个动画可用于翻阅各种距离的障碍。



绿色线段标记了各个攀爬区域,橙色线段标记了各个攀爬点的连接处,这些标记可以让同伴NPC执行玩家的部分攀爬动作。


1.3.2.2 生成Post


引擎会利用以上手动标记的数据自动生成所有Post。下图中,Green Post代表开放战斗点,NPC会在这些点进行战斗操作,例如开抢、扔手雷、拳击等。Organge Post代表掩体点,NPC会在这些点位躲避来自玩家的攻击。Teal Post代表制高点,NPC会在这些点进行狙击、探头射击等。Purple Post代表攀爬点,NPC可以攀爬到这些点位上,利用垂直空间。



1.3.3 Post Selector


生成了大量Post之后,就需要用Post Selector模块来为为当前正在执行的Behaviour所属的NPC对各个Post进行评分,最后选中总得分最高的Post执行Behaviour。Post评分的指标有。NPC位于此Post时能否看见主角,能看到主角可以获得更高的分数;NPC到此Post的距离,距离越近获得的分数更高;此Post是否位于NPC所属的分区,不在分区内部的Post都直接零分。间接限制了NPC只能在自己所属的分区内移动、战斗,前三部中使用的分区式NPC机制在这里得到了保留。



例子


1.最下面的NPC正在射击玩家



2.突然决定靠近主角


3.Behaviour使用Post Selector来选择最合适的Post来执行具体操作,更详细的讲解请参考Travis McIntosh GDC 2014 "The Last of Us Human Enemy AI"


4.评分情况



上图中,绿色Post代表得分非常高的Post,这些Post距离NPC较近、NPC躲在该Post的掩体后面可以正对主角、NPC距离主角较远(因为NPC使用的是步枪,方便射击)。红色Post代表得分比较低的Post,这些Post距离NPC太远、距离主角太近。



上图中全是零分的点,因为NPC躲在这些Post的掩体后面没有正对主角且遮挡视线、比当前NPC所处位置更加远离主角。


5.最终选择



1.4 Thing That Didn't Work


接下来会讲解神海团队开发早期的失败尝试。




团队首先尝试同时使用分区式NPC机制和Post Selector机制。第一张图中央的NPC的分区被设置在了如图所示的立方体中,NPC没有任何行动,AI宕机了。具体原因是,NPC处于Combat Skill,Combat Skill需要使用Post Selector去选择一个合适的Post。出于性能考虑(不止),只对在以主角中心,半径为25米的一个球范围内的Post进行评分,最后选取评分最高的Post执行Behaviour。由于地图较大,主角距离NPC过远。由于这些Post都在NPC所属的分区之外,Post Selector给这些点都打了零分。


这是一个相当基础的框架设计瑕疵,分区式NPC机制和Post Selector机制完全脱节。在设计的一开始就没有考虑它们之间的相互配合。按理来说,一个有着这么多年游戏制作经验的团队不应该会犯这样的错误。


随后神海团队设计了一个新的系统来代替分区式NPC机制,需要实现NPC能够分散分布以及智能占据空间。


1.4.1 新系统的首次尝试



为了让战斗更有层次感,加大了武器射程对战场层次的划分。因为主角地移动速度还是相对较快,NPC需要配合移动,最终导致肉眼可见的NPC频繁同时转移位置。如下视频所示



NPC频繁调整位置


1.4.2 新系统的后续尝试


为了更好地对候选Post进行评分,神海团队提出了连接度(Connectivity)和地理优势(Vantage)两个概念。


连接度需要利用navMesh生成的网格自动识别出特征地点,例如房间门口、走廊等。但是只适用于人工建筑,不适用于自然场景。因为人工建筑的空间相对较小,navMesh网格的分辨率足够大。而自然场景的空间相对开阔,navMesh网格的分辨率不够大。这个衡量指标没有在神海系列作品中使用,但是在隔壁的《美国末日》系列作品中大量使用。




地理优势用于处理在NPC看不见主角的情况下,应该选择移动到哪个Post。下图中橙色的区域代表主角从NPC的视野内消失时,在3秒内大致可移动到的位置。从每个候选Post开始向橙色区域内的所有Post打出射线进行检测,绿线代表无遮挡,红线代表有遮挡。最终选择绿线最多的候选Post进行移动。



上面所提出的两种度量指标都没有办法适应所有的游戏场景。很大的一个原因是这两种度量指标都是对策划的高级决策进行逆向工程得到的,都是在尝试将策划的具体想法转换成一套通用的自动化算法。这样得到的算法限制了策划为每场战斗增加独特性,因为算法的成功运行总是存在一定的前提条件,在前提条件的限制下,策划可配置出来的结果也受到了很大的限制。而且算法的执行总是存在着一定的规律,玩家多次游玩之后总是能察觉出这个规律。当然,游戏的玩法总是会存在或多或少的规律,非核心玩法可以有些许规律,但是核心玩法的规律越模糊越好。这样游戏的可玩性,玩家的探索欲才会足够强。


1.4.3 Search Skill的首次尝试


前面有提到神海4需要实现一套完整的潜行循环流程。主要的难点在于,玩家消失在所有NPC的视野之后,NPC应该如何展开搜索。


当玩家消失在所有的NPC视野之后,NPC最后一次看见玩家时玩家的所在区域会会被设置上一个初始的热度值。如下图所示,紫色表示很热,蓝色表示很冷。



NPC开始搜索后,会以热度值为优先级依次搜索各个区域,期间视线扫过的区域的热度值会不停下降,如下视频所示。


NPC依据热度值搜索各个区域


从上体视角来观察NPC的行为会觉得很正常、很自然,但是从玩家的视角来看就没那么自然了。这个搜索算法存在以下缺点。


玩家难以预测NPC的移动路径,NPC会经常突然180度转向,正常人很少会频繁180度转向。当玩家看着NPC渐渐走远,冲出草丛准备转移位置时。NPC这时突然转向就很尴尬。


NPC还会成群结队一起展开搜索,因为大家都按热度值对待搜索区域进行搜索。


NPC不容易观察到一些地图边缘的点,这些点所在的区域热度值一直降不下来,NPC会不断去查看这些边缘区域。最终导致场景的中央很空旷,玩家很轻松地大步通过这个场景。


存在这些缺点的根本原因是神海团队从NPC的视角去设计Search Skill。游戏是为玩家设计的,而不是为NPC设计的。我们应该要从玩家的视角去设计游戏,尽可能地保证玩家游戏体验良好,即使实现上不是那么地符合现实。


1.4.4 失败总结



神海团队在给神海4做设计时,想要从过去的人工配置模式完全转换成系统自动化模式。希望大幅度降低策划的工作量,提升系统的智能化程度。但是这个转换用力过猛,步子大了扯着x,导致神海团队做出了很多错误的系统设计。所以我们在进行全面的系统设计时要在人工配置和系统自动化之间找到平衡点,越早越好。


Part . 2


2.1 Solutions We Shipped


首先来讲解神海团队最终在神海4中使用的解决方案。


2.1.1 Hard Point



一个hard point由Name、Zone Region、Minimum NPCs、Maximum NPCs、Toggle这几个字段进行描述。Name代表该hard point的名字。Zone Region代表该hard point占据的空间。Mimimum NPCs代表该hard point需要被分配的最少NPC数量。Maximum NPCs达标该hard point可以被分配的最大NPC数量。Toggle代表该hard point是否激活。


NPC可以被动态地分配到一个hard point上,NPC必须要在它所属地hard point中才可以执行其行为。如果NPC不在它所属的hard point里面,该NPC会想办法到达它所属的hard point中。


场景中会有很多的hard point和NPC,神海团队设计了Hard Point Coordinator模块来为每个hard point合理地分配NPC。



为场景配置hard point的一个例子


2.1.2 Combat Roles


现在完成了为场景各个区域分配NPC的设计,但是神海团队遇到了另一个困难--NPC在它们各自所属的区域中该干什么。于是他们去研究了一些经典游戏,最终在《吃豆人》这个游戏中获得灵感。


2.1.2.1 吃豆人的角色



在《吃豆人》这个游戏中,红色鬼魂Blinky是一个主动进攻型的角色,它会不停的追踪主角。粉丝鬼魂Pinky也是一个主动进攻型的角色,它会追踪主角正前方两格的位置。橙色鬼Clyde是一个会和主角保持距离的角色,当距离主角比较远时,会开始追踪主角。当距离主角比较近时,会开始往地图的一个角落移动。蓝色鬼魂Inky会追踪 红色鬼魂的位置以主角朝向为轴进行翻转后得到的位置,在神海4中没有与之对应的角色。


2.1.2.1 神海4的角色


参考了《吃豆人》的角色设计后,神海团队也为神海4设计了三个角色,分别是交战者、伏击者、防御者。


  • 交战者(Engagers)



交战者会主动靠经并攻击主角,post selector会以主角为选择范围中心


  • 伏击者(Ambushers)



伏击者会暗中突袭主角,post selector会搜索出距离主角20米范围内的post,预测主角的前进路线,选择其中一个post作为post selector选择范围中心。



  • 防御者(Defenders)


防御者一般会在原地固定不动,post selector会以hard point作为选择范围的中心


  • Encounter Coordinator


神海团队设计了Encounter Coordinator模块来合理分配上面提到的三个角色。NPC会向该模块申请成为某类角色,然后开始执行以下分配步骤。



第1、4步其实是在分配防御者,需要Hard Point Coordinator的协助。第2、3步中的X、Y的取值范围一般为[2,3]。第5步并不希望执行,算是一种fallback策略,在开发期间如果跑到了第5步就会弹出巨大的警告通知策划进行调整。


  • global combat params


global combat params其实就是一张场景战斗参数配置表,策划需要手动在这张表里配置数据。下面讲解一下这张表里的一些字段。


Time delay to replace an engager:当一个交战者被杀后,分配新交战者的延迟


Snuck away diatance for stealth:主角回到潜行状态时,NPC开始搜索所需要达到的距离,距离定义为NPC最后看到主角的位置到当前主角位置的长度


  1. Timer for advancing:NPC切换掩体的时间间隔

  2. Timer for grenades:NPC投掷手雷的时间间隔

  3. Timer for flanking:NPC从侧面包抄的时间间隔


Min flank path rating:NPC选择包抄路径时可接受的最小分数。该数值越小,敌人包抄进攻就越猛


Min/Max shooters:同时开枪的最小\最大NPC数量。建议同一时间只有3~4个NPC同时开火,少了会无聊,多了会太难。该字段可以控制战斗的压力,让战斗保持在一个稳定的压力水平。为了对主角隐藏NPC有同时开火数量限制这个设定,神话团队设立了Shooter(枪手)角色。该角色和之前提到的角色属于不同的layer,由NPC Coordinator模块进行分配。当NPC换弹、看不见主角时,会主动放弃该角色的所有权,NPC Coordinator会将角色分配给其他可以开火的NPC。这样,Shooter角色会以一定的频率在所有NPC中流转,主角会以为所有NPC都可以开枪,只是开枪的时机不同,并没有限制同时开火的NPC数量。效果如下视频所示。


Shooter角色在所有NPC中流转


2.1.3 Search Skill的最终实现


  • 交战者、伏击者


交战者、伏击者的Search Skill最终实现


通过样条来控制NPC的移动路线。路线策划在场景中配置样条曲线环的位置、形状、同一时间沿一条曲线搜索的NPC数。这里有一个小技巧,如果给一条曲线同时分配两个NPC,则可以实现NPC在搜索过程中的互动效果,例如对话、眼神交接等。NPC一般情况下沿着曲线进行搜索,少数情况下回去检查某些特殊位置(掩体后方、峭壁边缘等)。NPC走完一条曲线之后,会自动移动到最近的曲线,沿着新到达的曲线进行移动。


这个方案的优点是,NPC移动会更加地自然,并且可预测,不会再出现之前热力图搜索那种突然回头的情况;NPC不会扎堆一起进行搜索,因为可以设置同一时间沿一条曲线搜索的NPC数;NPC不会走到地图边缘,只要策划配置地曲线不在地图边缘,NPC便不会走过去。


  • 防御者


让NPC移动到其所属Hard Point的区域范围内地理优势最好的post。


2.1.4 各个模块之间的联系



2.2 Evergreen AI Techniques


这一节会讲解神海1到神海4都在使用的AI技术


2.2.1 Combat Params


游戏中会存在一张表,这张表用来配置每个NPC的战斗参数。


2.2.2 Grenade Director


神海团队设计了一个模块Grenade Director,该模块会让NPC向玩家扔手雷。玩家看到手雷之后会因为要躲避手雷的爆炸伤害离开掩体,避免主角一直躲在掩体后猥琐射击。


实现方式是,当主角在一个地方停留下来之后,便开始倒计时;如果主角离开这个地方到达一定的距离,计时清零;如果计时器达到规定数值,则挑选场景中最有空闲的一个NPC成为Grenade Thrower。Grenade Thrower和Shooter属于同一layer。Grenade Thrower会与主角保持一定的距离然后扔手雷。


Grenade Director演示


2.2.3 Flanking


Flanking模块会派NPC去包抄玩家。玩家可能就会觉得这个地方不再安全而离开。通过这样的方式可以避免主角一致躲在掩体后面进行猥琐射击。


实现方式是,当主角在一个地方停留下之后,便开始计时;如果主角离开这个地方达到一个距离,计时清零;如果计时器达到规定数值,则从所有NPC中挑选最有空闲的成为Flanker。Flanker会在避开主角视线的同时绕到主角身后攻击主角。Flanker和Shooter属于同一layer。


问题是如何避开主角视线。神海团队对主角视线这个概念作出了定义。如下图所示,黄色的图形代表玩家视线,该图形会根据玩家的位置和朝向实时进行调整。NPC只要通过寻路系统便可以避开玩家视线。



2.2.4 Accuracy Ramping


该机制的用途也是阻止玩家一直躲在掩体后进行猥琐射击。NPC在发现玩家后,会根据与主角之间的距离获取一个时间,NPC会在这个时间内将瞄准精度提升到最高,百发百中。玩家会因为敌人的命中率提升而感觉到这个地方不安全,开始切换位置。


瞄准精度随时间的变化通过curve定义。curve的描述方式如下图所示。



2.2.5 Perch Posts


当NPC移动到这些Post时,会切换到一种特殊的射击方式,比如探出半个身子进行射击。


NPC在Perch Posts探头射击


2.3 Limitations


虽然神海第四步作品非常优秀,但是神海4最终采用的解决方案也存在着缺陷。


Post Selector的代码中有很多Magic Number,开发者本人也不知道这些数字具体代表什么意思,给后续的维护带来了困难。这种缺陷在需要长期开发/维护的网络游戏中是绝对不容许存在的。


伏击点的生成算法不好。



如上图所示,悬崖下的post虽然也在20米范围内,但是在这些post中伏击的意义不大。针对这种情况的临时解决方案是将此场景的伏击者总数设置为0。


玩家可以用一把手枪击杀50米以外的NPC,过于强大。神海团队一直都知道这个bug的存在,但是一直没有去修复。演讲者给出的解释是:“经过多次测试,大多数玩家总是认为子弹总是可以完美击中准心中心点。如果击不中,玩家会觉得枪like a shit。”


2.4 Conclusion & Takeaways


下面是神海团队总结出来的经验和建议。


Don't reverse-enginneer high-level decision making(不要尝试对高级决策进行逆向工程)。因为这样做会提高开发成本,具体决策转换为抽象代码之后,之后新增的需求也需要“适配”到抽象代码。策划可能并不知道具体决策被转换成了抽象代码,所以后续提出来的需求极大可能是没有办法直接“适配”到抽象代码的。如果程序觉得非常有必要将具体决策变成抽象的,那就跟策划去商量,直接将具体决策转换成抽象决策。这样之后策划提新的需求都是在这个抽象决策上进行调整,降低开发成本。


Design NPC behaviours from the player's perspective(以玩家的视角来设计NPC的行为)。毕竟游戏是为玩家设计的,只要设计可以给玩家带来良好的体验,即使有些设定不是很符合常理,也是可以接受的。


Author roles, then assign NPCs to them programmativally(人工编写角色,系统根据规则为NPC自动分配角色)。需要为游戏设计NPC时,可以人工硬编码角色的行为逻辑。运行时交给相关自动模块去分配角色。


NPCs need a goal other than "shoot at the player":NPC在不对主角进行攻击时,需要有其它事情可以做)。在做一个偏向写实风格的游戏时,NPC绝对不可以没有事情干,需要保证每时每刻NPC都有自己的任务。



  • 投稿邮箱:news@GameRes.com

  • 商务合作:Amber(微信:lcxk6876767)

  • 其他合作:老林(微信:sea_bug)