GOAP与氛围AI简述 —— 选型篇
原本想将这篇一口气写完,结果又成了一个未完待续系列
用了一个周末将将简单写了第一篇,还未润色,可以简单略读
全篇可能分为三个章节,等待激情填坑
- 选型篇:讨论对于氛围AI这一场景,GOAP的选型优势
- 技术篇:讨论GOAP的基础技术原理,并讨论其改良空间
- 实践篇:如何基于GOAP的核心思路,实践一个有趣的氛围NPC系统
BTW,后天黑神话就要发售了,等我通关回来真的还想得起这件事吗😢
最近,在捉摸着搭建自己早先构建的NPC系统 [待填坑][开发日志] 开发一套值得信赖的NPC系统
但在决定这次的AI选型的过程中,我似乎有意识地略过了基于行为树的AI方案
一方面,是对行为树的过度熟悉带来些许厌烦。先前已经在至少三个项目中用过行为树了,对于基础的使用方法和各种业务的使用都有一定的认知,对于其限制也有了相当的概念,不太想再一次重蹈覆辙。
另一方面,意识到自己久违地没有充分学习什么了,多少有种缺憾感。也想趁这个机会挑战一下自己罢!
于是,我的目标盯向了GOAP()
可以先简单描摹一下我对GOAP的基础认知,并基于此逐渐展开我们想让其堪何大用
GOAP这一AI架构出现在我眼前总共有两次
- 第一次是源自网络和朋友对只狼AI的简易介绍;在他们的介绍中,只狼的AI会评估环境和玩家的变招,基于克敌制胜的目标形成一系列进攻计划,并通过执行进攻计划中的子动作,来呈现AI战斗表现(捉虫:只狼使用的AI技术是HTN,即Action组织非动态的GOAP)
- e.g. 当玩家距离AI较远,且处于较大前摇动作中时,AI可以评估打断玩家动作和拉近身形的目标,从而在等待玩家欺近、释放劈砍动作、释放突进动作中选择最能满足当下所有目标的后者
- 第二次则是学习Games104的途中,听王希老师进一步介绍了GOAP的基准思路:设立一系列目标,并通过确认可用的行动,在条件的限制下,构建一个完整的计划用于完成目标。是谓目标导向行为规划(Goal-Oriented Action Planning, GOAP)
这次,我也终于有机会进一步学习这一虽然并不新潮,但足够新颖的技术栈。
优势分析
在进一步消耗精力来完善这篇文章之前,我必须继续尝试寻找GOAP在我使用情景中的优势。
如果我消耗了大量精力来讨论这一技术栈的优越,但最后未能展现其对于我实际需要的价值,那就得不偿失了。因此,先让我尝试费些笔墨说服我自己。
GOAP在战斗情境中体验的优势是十分自然的——正如前文讨论只狼AI时所说。
GOAP对战斗情景的处理不同于行为树或状态机中对战况的建模。
在实际战斗行为树的编辑中,行为树实质上还是一种对战况的逐层决策+顺序执行。我个人倾向于将其视为一种组织形式更加线性的状态机。即每一组顺序执行叶子节点为最小的子状态,而将涉及Select、Sequence、中断的逻辑视为状态间的跳转。由此实现一个近似的Mapping。
但在了解GOAP的过程中,可以发现其带来了一个较大的范式冲击。
即在GOAP中,我们不再关心Agent要如何切换状态而选取合适的行为。我们只需要定义Agent可能感知到的自己的状态信息和环境信息,并为其指派其能使用的基础行为。再往后就是智能体自己的决策了。
毫无疑问,这带来了一种微妙的难以掌控感,即我们难以准确预期我们所创建智能体的基础行为组合,也不知道其最终将呈现什么样的表现。
当然,对于上述这点,也存在一系列的尝试。即人们期望为Agent封装更丰富的状态,好让其能通过相对固定的行为在指定状态之间流转;或者人们会把一系列元行为封装为一个完整的大行为,或严格建模其序列关系,从而使得其更加可控。
上述常见的操作在某些层面上会将GOAP的灵活性抛却,将其降维回依据状态线性执行行为的AI中。但,在很多场景,GOAP依旧能体现其独一无二的优势。
1、动态规划
GOAP所执行的并非是一个完整的状态行为,而是一个Planning出来的Action队列——这保证了GOAPAgent的行为能以更灵活的方式进行打断和恢复。
以战斗为例,假设AI决策期望用一组连续行为来压玩家起身,而这时玩家的宠物或队友释放了具有轻微威胁的小技能来尝试压制。这时如果是状态机和行为树,通常的处理方式是让怪物硬抗下攻击,或转移至防守状态下,将原先行为计划放弃或使用定制化的复杂逻辑进行恢复。
回到GOAP侧,其理论上支持基于突发情况优先级,在Planning队列中临时插入一组闪避的动作,并评估这一动作对既有行为队列的影响,比方说插入一个向前的滚翻,在解除危机的同时,进一步满足欺近玩家的目标。
再回到我期望使用的日常NPC情景,在NPC具有即有日程,并存在Planning用于满足日程需要时,我们希望存在一种理想的随机表现方式,允许其临时响应环境信息,如天气信息、玩家行为、或突发的事件,并能视实际的执行情况决定后续计划是否执行,是否略过。
2、目标驱动
目标驱动是一种区别于过程驱动的设计范式,而其在GOAP的AI设计上也有一定的体现
虽说现实中好像并不存在什么和目标驱动形成明显对照的设计理念,但我们可以在这个讨论中虚空树一个靶子,即过程驱动(听起来就像面向过程的编程范式vs面向对象面向数据
不过事实也是如此,过程驱动确实可以总结几类AI设计的特性。甚至可以说,在过去经历的两个大型项目中,我实际上都给AI系统做过从过程驱动到目标驱动(或者是数据驱动)的迭代,我们可以讲一讲故事。
在项目A中,遇到的情景是搭建一个城市中的路人NPC氛围。项目内的早期方案是为每一组NPC实体创建行为Info,并让其随机刷新,在刷新后顺序执行Info所标识的行为。
基于这一方案,要求设计者在创造之初便规划好NPC可能的行为,并由此铺开工作量,整体是令人难以接受的。而后续我们展开的改良采用了目标驱动的思路,通过在场景中定义一系列目标,并构建NPC在目标之间的迁移逻辑,实现了基础的配置量简化。
在项目B中,情况稍显不同,在以宠物为主题的游戏中,AI设计偏向于呈现不同宠物的决策风格和特性,由此搭建了高度定制化的行为触发模式。其很大程度上满足了表现上限,但通用性却落了下乘。
同样在这个项目中,由于临时引入了AI驱动剧情和日常NPC表现的需要,我们尝试了一定的改良。即将信息的传递从逐一定制改向通用化,并使用数据驱动响应的方式(这里的数据便可以视为预封装好的目标数据),由此提高了资产的可复用性,同时为剧情表演使用通用逻辑驱动AI表现提供支持。
避免歪楼太远,回到讨论GOAP上,GOAP如其名天然是一个目标驱动的AI范式。也正因此,其更适合处理这类通用的、需要较长连续表现的AI。
以基于行为树(或其它固定决策结构)实现的目标驱动型氛围AI为例。
- 硬编码难以Cover足够多的氛围表现形式
- 在部分处理中,我们会将此类表现以子树,或外部智能对象(UE5Mass方案)的方式编排
- 但毫无疑问,代价是在一定程度上失去了Agent以不同形式和外界交互的灵活性。
- 比方说,我们可以通过在子树上定制决策分支,来实现演出的具体效果。假设这是一个牧场,效率的NPC和懒惰的NPC都能动态与之交互实现氛围表现。但效率的NPC倾向于利索地工作,并可能在完成工作后早早离开下班;而懒惰的NPC可能像我一样在工位上持续摸鱼,并在9点后勉强完成工作并混到加班费。
- 如上所述,不同的情景可在牧场这一目标点所提供的行为子树中做出分支。但每条分支也都需要硬编码,而当相似的情景扩散到更多目标、更多类型NPC时,其工作量将逐渐难以预期。
- 硬编码难以处理连续目标规划和临时的目标穿插
- 在制作氛围NPC时,我们往往会期望其生活逻辑语法有迹可循。这组常见的逻辑有,早上前往公司工作,等到中午时下楼吃饭;先去批发市场装货,随后开车运送给雇主。
- 通常,在氛围AI的设计中,我们会基于Schedule日程来组织NPC的工作。即将逻辑连续的表现硬编码为顺序的演出目标,从而避开AI主动规划的流程。
- 而与之相对应的,AI并不关心目标的执行情况,因此也无法在既定的规划外进一步呈现变化。
- 以一个在线游戏中相对高级的AI表现场景为例,如果在游戏中举办庆典活动,因此希望临时抽调部分NPC来填充活动氛围,但又不希望NPC的基础活动规律受到干扰,那我们除了手动配置之外有什么合适的办法吗?
上面是拍脑袋简单想到的几个情景,来自于我既往设计中的一些困扰。
而这些在相对老式AI框架中实现目标驱动时遭遇的问题,对GOAP而言均能迎刃而解
3、行为粒度
这一点也源自一个令人苦恼的设计场景。
在早先设计的游戏中,曾想制作一个叫做“怪人入侵”的环节,在这个环节中,城市里会随机刷新怪人战役,并造成群众的惊吓。
而这一设计最终因为多种原因被废弃。其一是探索场景的无缝战斗略有压力,其二则是路人氛围的表现难以做到足够优质,得以混过监修。
为了让大火清楚这个情景,我们能从 望月的实机PV 中找到有趣的例子。
在这一段中,展示了市民们因突发情况而疏散的AI表现,算是相对常见的处理。即让NPC寻找附近的逃生点并直接离场。
我们可以认为,如果是在较小规模的城镇箱庭,即并不关注于NPC连贯表现的情境中,NPC能够较快疏散完成,从而实现相对自然的表现。但对于大世界而言,空间的尺度会让疏散这一表现显得微妙,即我们并没有足够合适的手段让这些突发响应,自然地过渡回常态的NPC目标。
对于上述这个问题,我们可以将其视为一种范式的差异性。在基于固定结构的决策AI中,我们能设立的目标往往是个更具体的东西,就比方说为了较好的整合表演的需要,其变成了一种包含 “时间地点人物事件”的完整目标结构,即我们往往用“逃离现场”来定义响应危险事件的目标行为。
但在更细粒度的AI中,在脱离和环节强绑定的目标建模中,我们能将“脱离危险”作为AI的直接决策目标。从而形成更符合现实情景的AI表现。
这也是GOAP所能带来的优势。
如果我继续推进尝试,我想我应该能举出更多合适的例子。但姑且,基于上述给出的简要观点,现在我已经足以说服自己了。
因此,我也不希望这相对缺乏干货的部分进一步挤占文章版面和我的精力,好让我们回归写这篇文章所想要讨论的正题。
- GOAP的基本原理与使用
- 如何基于GOAP搭建一个有趣的NPC系统
下周一定继续(TBD)
Comments NOTHING