概要
最近在开展一个类殖民地建设项目的前期研究,想引入类似于缺氧中的游戏AI,主要是需要按照待办的任务来按次序开展,并且多个智能体之间要能够形成合理的任务分配和协作。
由于我们想要实现的AI需要完成大量复杂任务,出于可扩展性的角度考虑,基础的状态机和行为树明显是不适合这类复杂AI的,所以至少应该从HTN和GOAP出发。读了一些文章,暂时的想法是由GOAP系统来实现单个智能体的行为,由HTN系统来实现多智能体的群体管理。
先从GOAP开始学习研究。
什么是GOAP?
目标导向的任务规划 (Goal-Oriented Action Planner, GOAP) 是一种较复杂AI的实现方案。基于此方案的游戏AI从需要实现的Goal出发,去自发地构建一个Plan。这个Plan中包含一系列有序排列的Action。智能体将按照这个Plan逐个完成其中的Action,然后再去满足下一个Goal,并不断反复。
GOAP系统组成
Goal目标
设计者希望智能体能够达成的目标,比如完成采矿,完成建造等。
游戏AI通常具有多个优先级不同的目标,一般按照预设的固定优先级来逐个满足目标。
有时候也会采用动态优先级,但根据我自己的理解,这种动态调整是一种低频调整,例如Boss在低血量状态下的行动模式调整。算法在正常执行过程中大多数时间应该是保证固定优先级的。
Action行动
设计者希望智能体能够执行的实际操作和行为。智能体要开展某个行动,必须要满足开展此行动的前提条件Pre Conditions,行动成功后,此行动将产生某种影响,具体来说是对状态的改变,这种影响叫作After Effects。
After Effects可以改变智能体自身的状态,也可以改变世界状态。
World States世界状态
世界状态是被所有智能体共享的状态,常见的例子是资源总量。现在总共有10个矿物,A智能体拿走了这10个矿物去盖了个房子,B智能体就不能使用这个矿物了。世界状态的改变会影响所有智能体的后续行为。
Agent States智能体状态
智能体状态是智能体自己的状态,比如饱食度,疲劳值等。当一个智能体的饱食度过低时,它可能会尝试进食。智能体状态只直接影响智能体自身,不影响其他智能体。
Sensor感知器
感知器主要是去观测一些变量,来判断当前的状态是否已经发生了改变。通常来说,世界和智能体都包含许多变量,但不是所有变量都会影响状态,一个状态也不只由一个变量决定。比如危险状态,并不一定只存在一种固定的模式,可能在多种情况下智能体都会转变为危险状态。因此需要Sensor去订阅我们想要观测的变量,相当于一段将变量的数据映射到状态的处理程序。
实验设计
我打算在Unity中写一个小Demo,来验证GOAP系统在单智能体情况下的运行情况。
GOAP系统主要使用SGOAP这个Unity Package,具体程序接口请参阅他们的文档和教程(https://assetstore.unity.com/packages/tools/behavior-ai/s-goap-ai-solution-167167)
实验中包含的Goal,Action等信息具体如下表所示:
目标Goal | 优先级Priority |
---|---|
Full 吃饱 | 3 |
Build 建造 | 2 |
Mineral 获取矿物 | 1 |
智能体最优先保证自己能吃饱,然后是去建造,最后是去挖矿,都不能实现就什么都不做。
行动Action | 前置条件Pre Conditions | 完成后影响After Effects |
---|---|---|
Eat 吃饭 | Hunger < 20, AtEatPlace == true | Hunger = 100, Full |
Build 建造 | Mineral >= 2, AtBuildPlace == true, BuildWaiting >= 1 | Build += 1 |
Mineral 获取矿物 | AtMinePlace == true, MineWaiting >= 1 | Mineral += 1 |
GoToEat 前往餐区 | Hunger < 20, AtEatPlace == false | AtEatPlace == true |
GoToBuild 前往建造区 | BuildWaiting >= 1, Mineral >= 2, AtBuildPlace == false | Mineral += 1 |
GoToMine 前往矿区 | MineWaiting >= 1, AtMinePlace == false | Mineral += 1 |
吃饭、建造、挖矿都需要在对应的区域完成,如果智能体当前不在工作区域,则要求智能体先移动到工作区域。饥饿值低于20之后就要去吃饭,建造需要消耗两个矿物。实验中还模拟了玩家选中需要被开采的矿物和需要建造的建筑这一操作。只有当待开采矿物和待建建筑 >= 1是智能体才会采取对应行动。
世界状态 | 智能体状态 |
---|---|
Mineral 当前矿物储量 | Hunger 智能体饱腹值 |
Build 已建造建筑 | |
BuildWaiting 待建造建筑 | |
MineWaiting 待开采矿物 |
实验预期
- 当增加待建建筑时,在没有足够矿物且没有待开采矿物时,智能体不会行动。
- 在上述情况下,增加待开采矿物直到>2,智能体应当在开采2个矿物后自行完成建造任务。
- 在上述情况下,在上述情况下,当饱腹值<20,智能体应当去餐区进食,随后回来继续完成上述任务。
实验结论
通过点击对应的Cube可以增加待开采矿物和待建造建筑。
GOAP实验DEMO
基本符合预期。
有一段进食结束之后,矿物还剩2个,但是没有直接去建造,而是又去挖了一个矿之后才去建造,看起来是个Bug,后续再研究一下。
小结
基本实现了基于GOAP的单智能体行为,后续继续探索HTN的多智能体管理,以及尝试优化现有的GOAP实现,让智能体的配置和行为开发变得更简便些。