游戏邦在:
杂志专栏:
gamerboom.com订阅到鲜果订阅到抓虾google reader订阅到有道订阅到QQ邮箱订阅到帮看

开发者谈《盗贼之海》的AI设计解析系列之二

发布时间:2019-09-27 09:02:37 Tags:,

开发者谈《盗贼之海》的AI设计解析系列之二

原作者:Tommy Thompson 译者:Willow Wu

在本系列的第一篇中,我探索了AI系统在游戏中的运作方式,三大主要活动任务是如何生成的,以及开发人员如何才能让服务器承载所有的AI活动,合理分配资源。获得Rare公司的邀请后,我有很多话题想讨论。开发者就游戏发行时的一些AI相关问题为我们做出了解答。首先,我们将探索在藏宝岛上游荡的猪、蛇和骷髅:它们是如何运作的?骷髅AI行为背后有什么样的惊人秘密?除此之外,我们还会深入探究Rare利用虚幻4引擎创造出的独特水上导航系统,以及了解一下阻止AI鲨鱼游到陆地上是一件多么困难的事。

陆生动物的AI构建

让我们先简单查看下这些动物。就如系列第一篇所说的,《盗贼之海》的其中一种主要任务来自于灵魂秘社:你得去往一个或多个指定岛屿,杀掉高级别的骷髅,用他们的头骨换取奖励。这就要求游戏在必要时将大量骷髅刷新在某个地点,但如果你这时已经取得了淘金者或商人联盟的悬赏物,正在返程的途中,骷髅也会出现。

Sea of Thieves(from gamesindustry.biz)

Sea of Thieves(from gamesindustry.biz)

1.骷髅AI

那么,这个系统是如何运作的?它依赖于一种叫做行为树(behaviour trees)的常用AI范例,这是虚幻4引擎中自带的AI工具。正如我在AI 101系列最新一集中说到的,行为树的特点是可以扩展逻辑,形成多个分支,所以在特定的场景中,AI将做出一个或多个反映场景的决策。此外,他们可以对世界的变化做出快速反应,更新自己行为选择以适应变化。我们在第一篇中说过,很多陆地活动角色,比如岛上的骷髅、动物(我等会儿就展开)都是用虚幻4原本内置的AI工具链。但是骷髅有个特别的地方我想探究探究,自创办《AI与游戏》系列以来,我未曾见过如此独特的设计。

当AI角色出现在游戏中时,尽管你想要确保它们能够使用某些与玩家角色相同的机制——尤其是类人AI角色——但当你构建AI时,通常的思维是角色会使用另一种运行方式的来执行这些行为,跟玩家的操作逻辑完全不同。你会有一个指示执行某个动作或行为的逻辑,在虚幻引擎中,你可以在蓝图中的行为树编写任务,逻辑通常会调用代码中的现有函数——玩家会用这个函数来执行类似的指令。就拿《盗贼之海》举例,你想要在受伤之后补血,这时你会打开物品栏,拿出一条香蕉,按下RT键或者鼠标左键吃掉,这就触发了玩家代码库中的Heal()函数。一般来说如果你想让一个AI角色——比如骷髅——做一样的事,你的逻辑或者是直接运行一样的Heal()函数或者是运行一个为非玩家角色编写的类似函数,并且你要确保吃香蕉动画能够让玩家理解对方也在做同样的事情。所以总结来说就是看起来是在做同样的事情,但实际运行方式是完全不同的。

所以你们可以想象一下我当时有多震惊——坐在Rare办公室里,开发者Rob Massella和Sarah Noonan告诉我骷髅AI其实是在模仿玩家的输入。因此,他们不是简单地触发特定的行为代码,而是相当于用虚拟的手柄/键盘输入,像人类一样“玩”游戏。此外,骷髅使用的基类控制器跟人类玩家是一样的(或用虚幻4术语来说就是Actor,可放入关卡中的对象都是Actor),这意味着双方不仅共享某些动画,而且还共享输入接口。我们再回到香蕉的例子,一个想补血的骷髅,它实际上是按下了虚拟按键,从物品栏中拿出香蕉然后吃掉。

值得一提的是,地面上的运动使用的是岛上的导航网格系统,通过它实现四处走动。这种设计非常惊艳——通过额外的基础数据工作,将AI的特定交互或行为解析为玩家输入,这样就确保了骷髅只能成为玩家的影子,玩家不能做的动作它们也不能做。某种程度上来说这也是有道理的,鉴于他们是……呃,死不了的人类,但更重要的是,这有助于简化骷髅AI的测试——如果你看到他们做一些玩家做不到的事情,你就知道哪里肯定出了问题。从理论上讲,这意味着如果开发者为玩家添加了新的游戏机制,一旦写完了代码,骷髅也有新的内容了!

考虑到这种设计可能需要一些时间去习惯,Andy Bastable向我解释说负责玩法设计的团队会给新手开发者布置一个小任务,帮助他们掌握工具链。开发者要做的就是创建一个“流浪乐队”,一群骷髅必须聚集在一块土地上,拿出他们的乐器,开始一起演奏一首歌。

现在,所有的AI行为都是在服务器端进行管理的,就像你们在之前的Tom Clancy《全境封锁》案例研究中所看到的那样,这样确保了每个设备上的玩家在与AI角色交互时都拥有同样的游戏体验。但还有平衡问题需要解决,正如我在第一篇中提到的,游戏内置的系统会根据玩家的情况调整骷髅的数量和难度。骷髅的行为和基本的游戏参数(如血量和可用武器)可以改变,种类也相当多,迫使玩家使用多种攻击策略来击溃他们。在第一次玩的时候,骷髅移动速度比较慢,攻击性不强,只会用利爪或者是长刀攻击。随着玩家在灵魂秘社的等级逐渐提高,骷髅拥有了以前没有的技能:它们可以更快地发动攻击、更高效地追击、面对攻击懂得后退、用香蕉治愈自己,甚至开始使用手枪和喇叭枪攻击。这一切都是通过使用数据库来实现的,它可以在运行时将函数写入AI角色中,决定这个骷髅会做出什么样的行动。其中包含了50多个独特的参数,促使骷髅出现多样化的属性和行为。

2.动物行为

尽管游戏需要在指定岛屿上制造威胁,但这些地方除了敌人还有各种野生动物:猪、鸡和蛇。它们可以是你在躲避骷髅军团追杀时遇到的又一个大麻烦,它们可以是商人联盟的悬赏物,也可以只是为环境加一点生气。

这些角色也使用行为树,尽管它们的架构与骷髅非常相似,但它们好对付得多:玩家只有在靠近蛇时它才会主动攻击,而猪和鸡则会马上逃离。就跟骷髅一样,数据库的使用能够帮助开发者指定特定动物的行为表现。

在第一篇中我就说过,考虑到负载管理,动物的处理方式与骷髅基本一致,如果它们正在消耗的这些服务器资源用在别的地方更值得,系统可以在必要时让它们进入休眠或者消失。

鲨鱼&导航系统

我们分析了所有陆地上的AI角色,那么海里的呢?让我们来看看玩家的第一个真正威胁——埋伏在海洋深处的鲨鱼,很多很多鲨鱼。

从设计的角度来看,鲨鱼是为了给玩家增加一个新的挑战,确保你不会在水中无所事事,时刻警惕着危险。它们只在小范围、必要时生成。也就是说,你不会在开放世界里偶然遇到一只在海里游泳的鲨鱼,相反,一条鲨鱼会被传送到你附近。如果游戏你觉得你在水里闲得太久了,鲨鱼就会尾随你。

因此,尽管鲨鱼的行为树结构相对简单——它们只会对猎物进行围捕或攻击——但有两个明显的问题需要解决。第一是导航:你要怎么确保AI鲨鱼知道如何在水中移动。通常来说,我们会使用导航网格工具来实现在静态表面物体的移动。这对陆地角色来说是行得通的,因为导航网格是一个二维的平面,模拟物体在三维空间的移动。然而,这并不适用于形状不断变化的表面或体积不断变化的空间,例如水和空气——这意味着你需要定制的一个特别的解决方案。这并不是只有《盗贼之海》遇到的问题,我最近研究的《地平线:零之曙光》也有类似的麻烦——Guerilla Games不得不为空中的敌人单独做一个导航系统。

Rare公司正面攻克问题的方法是构建另一个导航系统,集成到虚幻引擎中现有的导航框架中,但专门针对水下运动。然而在这之前,还有一个设计问题需要解决:鲨鱼不能停下来。虽然不同种类的鲨鱼之间有所差异,但大多数现实中的鲨鱼需要保持运动才能呼吸。所以AI角色也需要复制这种行为:以不同的速度在预定轨迹上游动,期间还要不断微调鲨鱼的运动方向。所以运动系统不仅要确保AI角色能像鲨鱼一样在水中穿梭,它还必须还原鲨鱼的动态细节。

除非鲨鱼被指示去攻击玩家,否则它们一般都是在按弧形轨迹游泳。这是通过计算既定直径的圆弧来实现的,它会影响鲨鱼在运动时的转弯速度,设计师可以调整鲨鱼沿着圆弧运动的速度。同时,速度值被发送到运动组件,这样玩家就能从动画中感觉到鲨鱼运动速度的变化。导航系统指定一个二维或三维空间的地点,然后创建一个适合该位置的自然弧线,让鲨鱼游过去。

开发团队在鲨鱼的转弯速度上下了很多功夫。以这种方式运动可以防止鲨鱼在高速时转向过快。如果鲨鱼需要做一个急转弯,考虑到它即将攻击玩家,速度会慢下来——当然不可能会减速到静止——并确保它在再次加速之前与玩家速度保持一致。但是鲨鱼的运动有一个可接受的误差范围,它们有时会超过它弧线所指向的目标,但前提是它们不会与任何障碍物相撞——我马上讲到。这么处理很好,鲨鱼的运动看起来会更自然。

大部分的运动都是在2D空间设定下,这意味着玩家和鲨鱼在水中是处于同一深度。如果没有,鲨鱼会像往常一样按弧形路线游,但会另外生成一条简单的贝塞尔曲线,让它可以游上或游下到相同的深度。

这很酷,但是会出现一个大问题:相撞。鲨鱼需要避开船只和岛屿,它们依靠虚幻引擎的环境查询系统来发现附近的障碍物,但它们也有短距离的触须式传感器,以防它们会迎面撞上船。这是非常重要的,由于它的游泳轨迹是弧线形,它有极小的可能会在某个小岛上搁浅……这显然是开发过程中一个更为棘手的问题。

为了维护代码库,鲨鱼导航的源代码是虚幻引擎现有导航、移动和AI控制器代码的扩展。由此一来,开发人员的工作就比较轻松了。因为鲨鱼导航的设计目标之一就是让它的运行方式与陆地的基本一致,并且为了测试加以简化,你可以在本系列的后几篇看到关于此的更多内容。

总结

即使是3A游戏中的一个最简单的AI角色,制作起来都可能要耗费大量精力,如果中途出现偏离预期的情况则更是如此。事实证明,仅仅是加入一个会游泳的AI角色都这么麻烦,那游戏的这么多海洋威胁是如何运作的呢?对《盗贼之海》AI的研究还不止于此,还有一些恐怖的AI敌人可能会让我们葬身大海,在系列的第三篇,我们将会面对:

·海怪,游戏发行以来它就成了玩家摆脱不了的噩梦。
·巨齿鲨,新DLC“饥饿深渊”出现的巨兽。
·还有骷髅船,它第一次出现是在诅咒之帆DLC中,现在它们对玩家的船只展开更猛烈的攻势了!

本文由游戏邦编译,转载请注明来源,或咨询微信zhengjintiao

In part 1 on my series looking at Rare’s Sea of Thieves, I explored the range of AI systems at play, how missions are generated for players at each of the three quest givers and how all of this is subsequently managed at server level to suit. Having been invited to Rare’s offices there was so much to talk about and in this entry, we’re going to hear first-hand from the developers themselves about the AI in the game at launch. First we’ll explore the pigs, snakes and skeletons roaming the treasure-laden islands; how they work and the surprising secret that powers the skeleton AI behaviour. Plus we dig deep into the completely distinct navigation system built into Unreal Engine 4 by Rare that allows for navigation in open waters and just how difficult it is to stop AI sharks from swimming onto land.

Land AI Architectures

So lets’ begin by examining the land-based creatures. As explained in part 1, one of the main mission types in Sea of Thieves is the Order of Souls: where you must visit one or more specific islands in the world to kill high-ranking skeletons and sell their skulls for treasure. This requires skeletons to spawn in the world when necessary, but they can also just appear throughout your time on a given island if you’re in the midst of retrieving items for a gold hoarders or merchant alliance quest.

Skeleton AI

So how do they work? Well they’re reliant on a commonly used AI paradigm called behaviour trees, which is the default AI tool built into Unreal Engine 4. As explained in my recent AI 101 episode on the topic, behaviour trees allow for branching of logic so that in certain situations, the AI will make one or more decisions that reflect the scenario. Plus they can react to changes in the world quickly and update their chosen behaviour to suit. Now as mentioned in part 1, many of the land-based AI characters such as the skeletons and the animals on the islands – which I’ll come to in a minute – are all using the original built-in AI toolchain. But there’s something special going on in the skeletons that I wanted to talk about, something unique that during my time working on AI and Games, I’ve simply never came across before.

Y’see, when an AI character in game, while you might want to ensure they’re using some of the same mechanics and features as human players – especially if they’re humanoid – when building the AI you’re thinking about the behaviour you want the character to execute often in a completely distinct way from how you would as a player. You’ll have the logic that dictates when a certain action or behaviour is going to be executed and in Unreal you’ll write specific tasks in the behaviour tree in blueprint that handle the execution on a minute level often calling existing functions in the code that players may call to do a similar thing. Say for example in Sea of Thieves you want to heal yourself after being injured, then you would open the inventory, grab a banana then hit the right-trigger or left mouse button to eat it, which triggers the Heal() function in the codebase for human players. Typically if you want an AI character – such as a skeleton – to do the same thing, the logic would be to simply run either the same Heal() function or a similar one for that non0player character and ensure the appropriate banana-chomping animation is used to enable players to understand what is happening. Ultimately, it looks like it’s doing the same thing, but under the hood they’re completely distinct.

So imagine my surprise when – having sat down with developers Rob Massella and Sarah Noonan – that the skeletons are mimicking player input. So instead of simply triggering specific code behaviours, they’re pressing virtual equivalents of the controller/keyboard inputs and effectively ‘playing’ the game like humans are. Plus, the skeletons use the same base controller (or in UE4 terms, the same actor) as a human player, meaning they not only shares some of the players animations but also the input interface. So returning to the banana example, for a skeleton to heal itself, it’s actually pressing virtual buttons that enable it to grab a banana from its inventory and subsequently eat it.

Though it’s worth mentioning that movement on the ground isn’t using virtual representations of the sticks, they’re just using the navigation meshes baked onto the islands to walk around. What’s amazing about this is that by doing the extra legwork to parse a given interaction or behaviour for the AI into the appropriate player inputs, it ensures that skeletons can only execute actions if a player can do it as well. This kinda makes sense, given they’re… well… undead humans, but more imporantly it helps streamline testing of the skeleton AI, since if you can see them doing something that a player can not, then you know somethings gone wrong. But also, in theory it means that if new gameplay mechanics are added for the player then – once a bit of extra coding has been completed – the skeletons will be able to do it as well!

Given this can take a bit of getting used to, Andy Bastable explained to me that the gameplay team had a little ‘assignment’ that they would give to new developers to help them get to grips with the toolchain. Developers are tasked with creating a ‘Mariachi band’, whereby a group of skeletons must come together on a piece of land, pull out their instruments and start playing a song together.

Now all of the AI behaviours are managed server-side – much like what we saw in my case study on Tom Clancy’s The Division – given it ensures players on each device have the same experience as they interact with them. But there’s still the issue of balance, which as I mentioned in part 1 is addressed by having systems in place that makes sure skeletons scale in difficulty in accordance with the experience. Not only can the behaviours and base gameplay parameters such as hit points and available weapons change, but the types of skeletons are fairly broad with Overgrown, Shadow and Gold skeletons forcing players to mix up their play styles to defeat them. On starting playing for the first time, skeletons are quite slow, not particularly aggressive and can only use claws to attack or maybe a sword. As players increase their ranking in the order of souls, skeletons are given access to abilities they didn’t have before: they can strafe faster, hunt you more efficiently, back off if under attack, heal themselves with bananas and even start to use the pistol and blunderbus to attack. This is all achieved through use of data assets that can plugged into the character AI at runtime that defines how this specific skeleton will operate, with over 50 unique parameters that help diversify their attributes and behaviour.

Animal Behaviours

So while the game needs to provide threats to players on any given island, there’s also all of the ambient wildlife: the pigs, chickens and snakes. They can either prove a pain in the ass while you’re avoiding a hoard of skeletons, be a resource you need to gather for Merchant Alliance quests or just add a bit of life to the surrounding environment.

In any case, they too use behaviour trees and while their architectures is largely similar to the skeletons, it is much more reduced in scale: with snakes attacking the player if in proximity and pigs and chickens just running away from you. The architecture is consistent across each type, with the data assets assigned to them helping to dictate how that specific animal will operate with the behaviour tree.

As mentioned in part 1, these are treated in much the same way as skeletons for load management and can be disabled or despawned when necessary if they’re consuming resource on the server that could be put to better use elsewhere.

Sharks & Navigation

Now having explored all the AI characters on land, what about at sea? So let’s check out the first real threat players are faced with in the murkey depths, sharks. Lots and lots of sharks.

From a design perspective, the sharks are intended to add a new layer of challenge for players by ensuring you don’t sit idle in the water. They only operate within a short range and spawn in when necessary. Meaning you won’t just stumble into a shark swimming the seas in the open world, instead you will effectively cause a shark to teleport into the game near your position then stalk you if the game feels like you’re sitting in the water for too long.

So while the shark behaviour trees is relatively straightforward – they only really cricle their prey or attack it – there are two distinct problems that needed to be addressed. The first big problem is navigation: how do you ensure an AI shark knows how to move through a volume of water. We typically use a navigation mesh to support movement on a static surface. This works OK on land in for characters such as the skeletons given the nav mesh is a two-dimensional surface that models movement on a three-dimensional space. However, this doesn’t scale to surfaces that are constantly changing shape or for volumes of space such as water and air – meaning you need to create a custom solution to resolve it. This isn’t a unique problem for Sea of Thieves, as we saw in my recent case study on Horizon Zero Dawn, where Guerilla Games had to build a separate navigation system for the flying enemy characters.

Rare challenged the problem head-on by building a navigation system that would integrate into the existing navigation framework in Unreal Engine but catered specifically for underwater movement. But before they could do that, there was a second design problem that needed to be addressed; a shark can’t stop moving. Whilst it varies between species, the majority of real-life sharks need to maintain movement in order to breathe. So the AI equivalent needs to replicate this behaviour: making lots of small corrective changes in direction at varying speeds. So the movement systems needed to ensure not only could the AI navigation through water like a shark, it had to move actually move like a shark would too.

So first things first, unless the sharks are instructed to attack a player, they typically swim in arcs. These is achieved by effectively calculating the arc of a circle of a given diameter, this impacts the turning rate of the shark as it’s moving and the designers can tweak the speed with which it moves along it – with that speed value also being sent to the movement components such that the animation reflects the current movement speed. The navigation systems give the sharks location in either 2D or 3D space to move towards, then create a natural arc that will fit that location.

A lot of effort is put into the turning rate of the sharks. The turn rates are constrained in such a way, that it prevents sharks from turning too sharply at high speed. If a shark needs to make a tight corrective turn, given it’s about to attack the player, it will slow down – but never to the point it stops of course – and ensure it’s lined up with the player before speeding up again. But also there’s a small window of acceptable error for shark movement, they can sometimes overshoot a target they’re arcing towards, but provided they’re not going to collide with any obstacles – which I’ll come back to in a second, then that’s fine, given it makes the sharks move more naturally.

This is all largely assuming movement in 2D space, meaning that the player and the shark are at the same depth in the water. In the event they don’t line up, the shark will plot the same paths as usual, but generate a simple besier curve to allow it to swim up or down to the same depth.

Now this is pretty cool, but there’s still one big problem left to deal with: collisions. Sharks need to avoid both ships and islands and are reliant on the environmental query systems in Unreal to spot obstacles in proximity, but they also have short range whisker-like sensors just in case they’re going to swim face-first into a boat. This is pretty important given that there’s still a small chance as it swims an arc that it runs risk of beaching onto an island…. which was apparently a much bigger issue during development!

To keep the codebase maintained, the source code for shark navigation is an extension of existing navigation, movement and AI controller code built into Unreal Engine. As such, it made life easier for the developers given it was designed to behave in much the same way as land-based navigation when called to execute and streamlined it for testing purposes, which is something that you can expect to hear more about later in this series.

Closing

Even the simplest of AI characters needed for AAA titles can prove to be a challenge, and even more so once they deviate from the expected formats in games. Even having AI that swim can prove to be a problem and it was exciting to see how these water-based threats were put together. But our journey through the Sea of Thieves on AI and Games is far from over. There are still some monstrous AI enemies that threaten to drag us down to Davy Jones Locker and in part three of the AI of Sea of Thieves we’re going to tackle them face on:

·The kraken, the mighty beast that has haunted players since launch.
·The mighty Megalodon released during the Hungering Deep expansion.
·And the Skeleton Ships first seen thrashing the waves in the Cursed Sails, that now more aggressively seek players to plunder!

(source:gamasutra.com


下一篇: