Games104 学习笔记 15~17

目录

课程作业

https://games104.boomingtech.com/sc/course-work/

别人的笔记

https://peng00bo00.github.io/archive.html

第十五节 游戏引擎的 Gameplay 玩法系统基础

玩法系统是游戏引擎最重要的部分,它是区分游戏引擎和渲染器以及物理引擎的核心。实际上玩法系统往往会贯穿整个游戏引擎,与引擎的其它系统进行交互,这样才能满足游戏设计师的需求。

另一方面现代游戏的玩法是极其丰富的,即使是同一类型的游戏也具有多种多样的表现形式。这些丰富的游戏内容都需要通过玩法系统来进行实现。

而在游戏行业中玩法系统还面临着快速迭代的问题,同一个游戏的核心玩法在开发运营初期和后期可能会有着巨大的差别。因此玩法系统在设计时也需要考虑需求变更和快速迭代。

Event Mechanism

玩法系统的核心是事件机制(event mechanism),在游戏世界中不同类型的 GO 会通过事件/消息的方式进行通信从而驱动游戏世界的运行。

Publish-Subscribe Pattern

在游戏引擎中一般会使用 publish-subscribe 这样的模式来实现具体的通信过程。在 publish-subscribe 模式中每个 GO 有着自己的 publish 功能来向其它 GO 发送事件,同时自身的 subscribe 功能来实现接收事件以及相应的反馈。当然在 publish-subscribe 模式中还需要一个 event dispatcher 来执行高效的事件派送。因此在 publish-subscribe 模式中的三要素为事件定义(event definition)、注册回调(callback registration)以及事件派送(event dispatching)。

Event Definition

事件定义是实现事件机制的第一步,最简单的定义方式是为事件定义一个类型以及相应的参数。

因此我们可以使用继承的方式来实现不同类型事件的定义。但这种方式的缺陷在于玩法系统往往是由设计师来实现的,而对于游戏引擎来说一般无法由程序员事先确定。

在这里插入图片描述

在现代游戏引擎中会使用反射和代码渲染的方式来允许设计师自定义事件类型和相关的数据。

在这里插入图片描述
但是使用反射渲染也是要重新编译一遍,所以事件可能是纯数据存储的

或者是,引擎 runtime 把蓝图数据当成 dll 注入

还有的引擎使用 C#,允许动态挂接

或者是在脚本语言中定义 event

Callback Registration

当 GO 接收到事件后就会激活调用相应的回调函数来改变自身的状态,而为了正确地使用回调函数则首先需要对不同的回调函数进行注册。

在这里插入图片描述
回调函数的一大特点在于它的注册和执行往往是分开的。这一特点可能会导致回调函数调用时相关的一些GO可能已经结束了生命周期,因此回调函数的安全性是整个事件系统的一大难题。

在这里插入图片描述

为了处理这样的问题我们可以使用强引用(strong reference)这样的机制来锁定相关 GO 的生命周期。强引用会保证所有和回调函数相关的资源在回调函数调用前不会被回收,从而确保系统的安全。

例如父子关系,如果有一种关系是:父物体没有被销毁,那么子物体就不能被销毁,那么就可以用强引用

emmm关键是他没有给我例子说明这个强引用具体是怎么写的

当然强引用的方式在一些场景下可能是不合适的,很多时候我们希望某些资源可以正确的卸载掉。因此我们还可以使用弱引用(weak reference)的机制在调用回调函数时判断资源是否已经被卸载掉。当然弱引用机制的滥用可能会影响整个系统的性能。

例如遍历所有能看到的人,这里用弱引用,因为上几帧存的人在这一帧可能已经销毁了

这里我觉得应该指的是内存计数里面的强引用和弱引用?

他这里指的应该是一个事件有多个对象在监听,然后对事件使用引用计数,如果计数值为 0,那么这个事件可以被回收,如果计数值不为 0 就不能

然后事件系统这里的内存泄漏,在强引用的内存泄露这里,应该指的是某些代码可能会写错了,就是这些物体在创建的时候订阅了事件,但是销毁的时候可能没有考虑到所有的销毁的情况,就在某种销毁的情况的时候没有取消订阅事件,然后导致整个事件的引用次数一直不为 0,一直留在内存中

在弱引用这里,就是在事件 invoke 的时候遍历一遍订阅事件的对象列表,检查这个对象是否还 valid,不 valid 就移出

但是如果每次 invoke 之前都要判断,对性能又有影响

Event Dispatching

事件会通过分发系统来实现消息的传递。由于游戏中每一时刻往往存在着成千上万个 GO 和相应的回调函数,我们需要一个非常高效的分发系统才能保证游戏的实时性。

如果对于每一个消息,都扫描一遍 callbackfunction 列表,找到对应的callbackfunction,效率肯定不会好

假设每帧 n 个消息,每个 GO 产生 m 个 callbackfunction,有 k 个 GO,时间复杂度就是 o(nmk)

在这里插入图片描述

Event Dispatch : Immediate

最简单的分发机制是把消息瞬时发出去。这种方式的缺陷在于它会阻塞前一个函数的执行,从而形成一个巨大的调用栈使得系统难以调试;此外很多回调函数在执行时会申请一些额外的资源,这就容易导致游戏的帧率很难稳定。

在这里插入图片描述
例如场景中有一堆炸弹,某一个炸弹爆炸之后会引起另外一个炸弹的爆炸

那么调用栈就会充满了炸弹爆炸的调用

也就是形成一个巨大的调用栈使得系统难以调试

在这里插入图片描述
又例如场景中触发某一个事件会导致特效释放

这就是 回调函数在执行时会申请一些额外的资源,这就容易导致游戏的帧率很难稳定。

在这里插入图片描述
立即派发还有一个坏处是,各个系统在时间轴上不能并行

在这里插入图片描述

Event Queue

现代游戏引擎中更常用的分发方式是使用事件队列(event queue)来收集当前帧上所有的事件,然后在下一帧再进行分发和处理。

在这里插入图片描述
由于 event queue 中有不同类型的事件,因此我们还需要结合序列化和反序列化的操作来进行存储。

在这里插入图片描述
我之前在想,为什么这个 event dispatcher 不是 std::multimap<string, callbackfunction> 的结构

因为我看 piccolo 在反射这里似乎就是这样的

他这里想要序列化和反序列化,应该是为了能够方便管理内存……?或者是为了方便管理不同种类的 event?

但是我就是不知道,想要管理不同种类的话……一定要序列化和反序列化吗

我之前是用 C# 写过一个 map<string, Action>, map<string, Action<T1, T2>> 这种东西来存 event name 与 event callbackfunction 的 pair

但是我不知道……具体 C++ 这里,老师讲的时候默认是针对什么功能实现讲的

event queue 一般会使用 ring buffer 这样的数据结构来实现,这样可以重用一块统一的内存空间来提升效率。

在这里插入图片描述
现代游戏引擎中往往会同时有多个不同的 event queue 来处理不同类型的事件,每个 queue 用来保存一些相对独立的事件。这种方式可以便于我们进行调试,也可以提升系统的性能。

在这里插入图片描述
当然 event queue 也有一些自身的问题。首先 event queue 无法保证 event 执行的顺序,同时对于一些实时性的事件 event queue 可能会导致执行的延误。

例如 有些逻辑希望先处理战斗事件再处理 AI 事件,但是即使先发送战斗信息,再发送 AI 信息,也可能先 Invoke AI 事件再 Invoke 战斗事件

(这里我也没懂为什么顺序可能会乱,但是能够理解这个可能性,只是不知道这个可能性的根源)

要解决这个问题,要么就 hardcode 执行顺序,要么就在某些时候保留事件系统立即处理事件的能力,要么就在事件系统的 post tick 和 pre tick 中处理顺序

更难的问题是怎么让设计师使用这些方法

在这里插入图片描述
另外一个问题就是,所有逻辑都会慢一帧

因为都是这一帧提交到 event queue 下一帧处理

但是一些东西最好在同一帧处理,例如受击检测与受击表现

假设受击表现是一个事件套一个事件的,那么这个时候如果用 event queue,就相当于受击检测与表现之间又若干帧的延迟,打击感就不对了

这个时候可能要 hardcode 绕过 event queue

Game Logic

在事件机制的基础上就可以开始设计游戏的逻辑了。在早期的游戏开发中会直接使用 C++ 来编写游戏的逻辑来获得更高的运行效率,而随着游戏系统变得越来越复杂这种直接基于高级语言的开发方式就不能满足开发者的需求了。

除此之外游戏引擎面对的用户往往是设计师而不是程序员,对于设计师来说直接使用编程语言来设计游戏可能是过于复杂的。

How Script Languages Work

因此在现代游戏引擎中往往会使用脚本语言来实现游戏的开发工作,它的优势在于它可以直接在虚拟机上运行,脚本 crash 了之后只会影响虚拟机,而不会影响本机。

在这里插入图片描述

因此我们可以把游戏中的很多逻辑使用脚本语言来实现。

脚本语言的另一大特点是可以进行热更新。

当然脚本语言也有许多缺点,比如说它的效率一般会比较低,因此选择合适的脚本语言是十分重要的。

目前游戏行业中常用的脚本语言包括 Lua、Python、C# 等。

Object Management between Scripts and Engine

有一个问题是,物体的生命周期归底层代码管,还是归脚本管

如果归底层代码管,那么底层代码需要提供生命周期的管理

并且当脚本使用底层代码创建的 GO 的时候需要判空

在这里插入图片描述
但是在一些玩法复杂的逻辑中,物体的创建与销毁是玩法的很大一部分

如果由脚本管,引擎只是引用这些物体而不负责管理

那么脚本创建的物体的生命周期由脚本 GC 管理

脚本创建的物体的内存管理由脚本 GC 管理

如果脚本写得不好就会有内存泄露

在这里插入图片描述

Architectures for Scripting System

还有一个问题是,tick 由谁控制

一般都是引擎自己控制 tick,然后调用脚本

在这里插入图片描述
可以把引擎包成一个 sdk 库,用脚本来控制 tick

在这里插入图片描述

Advanced Script Features - Hot Update

热更新的原理是修改函数的指针

在这里插入图片描述

Issues with Script Language

弱类型的语言更难去优化

需要虚拟机去执行机器码

Lua 的 JIT 模式,just in time 模式,动态解释,即时编译,是一种优化虚拟机运行的技术。即时编译器会将频繁执行的代码编译成机器码缓存起来,下次调用时将直接执行机器码。相比原生逐条执行虚拟机指令效率更高。而对于那些只执行一次的代码仍然逐条执行。

C++ 也有分支预测

Visual Scripting

可视化脚本(visual scripting)是现代游戏引擎几乎必备的功能。和传统的脚本语言相比可视化脚本无需开发者直接进行编程,因此它对于设计师和艺术家而言更容易进行掌握。像虚幻和 unity 这样的商业级游戏引擎都实现了自身的可视化脚本功能。

  1. 变量

    类型

    作用域

  2. 表达式

    使用节点来表达表达式

  3. 控制流

    顺序

    条件

    循环

  4. 函数

    传入参数

    方法体

    返回值

  5. 成员变量

    成员方法

可视化脚本也有一些自身的问题。首先可视化脚本很难进行协作,在大型开发团队中很难把每个开发者定义的脚本直接组装到一起,往往需要通过大量人工的重新排序才能得到正确的结果;同时当脚本中的节点过多时整个脚本在视觉上可能会非常繁琐,让人难以阅读。

Script and Graph are Twins

可以先把图编译成脚本,脚本再编译成机器码

或者直接把图编译成机器码

在这里插入图片描述

Character, Control and Camera

角色(character)、控制(control)以及镜头(camera)是构成玩家体验最重要的元素。

Character

角色是指游戏中如何设置玩家控制角色以及 NPC 的运动和各种状态。

在现代游戏中角色的运动往往涉及大量不同的动画和状态改变,我们需要非常多的细节才能设计出符合人认知的角色运动。同时在游戏世界中角色还需要和环境中的各种元素进行互动,往往需要结合游戏引擎其它系统进行设计。

因此角色系统一般需要一个非常复杂的状态机模型来描述角色状态的切换和转移。

Control

控制系统的核心问题是要兼容玩家不同的输入设备。

来自控制器的信号通过控制系统会转换成游戏可以识别的输入,然后通过事件机制来控制角色。

控制器还可以提供一些容错的体验,例如辅助瞄准

同时我们还可以利用控制器的反馈功能来进一步提升玩家的游戏体验。

Camera

镜头会直接描述玩家视角中看到的场景和事物。

从实现角度来说,我们只要设置好相机的位置和视角就可以直接利用渲染系统来实现镜头的功能。

在游戏场景中最常见的情况是相机要绑定在玩家控制的角色身上,随着角色的运动一起运动。同时我们还需要保证相机在运动的过程中不要出现穿墙等各种问题。

镜头系统的一大难点在于如何根据角色的状态来调整相机的相关参数,使游戏画面更接近于人眼的真实反映。

同时镜头系统也需要考虑各种相机特效的实现,包括镜头抖动、动态模糊、相机自身的惯性等。

在复杂场景中往往还会有多个相机同时存在,因此我们也需要管理这些相机和相关参数。

整个镜头系统对于提升和改善玩家的游戏体验起着至关重要的作用。

因此游戏引擎中的镜头系统需要允许用户使用脚本或是可视化脚本来编辑相机的各种属性和参数。

QA

如果接入了可视化脚本,是否就不需要传统脚本了?

不一定

未来平台会不会趋向禁止热更

像 IOS 为了平台安全性不希望热更

未来不知道

会不会有逻辑和表现分离的开发模式

一般都是逻辑和表现分离的

实操中很难

第十六节 游戏引擎 Gameplay 玩法系统:基础 AI

QA

需要给蓝图事件定义优先级吗

也可以,但是如果你的游戏逻辑依赖于事件的优先级处理,这样的话事件系统会与具体的游戏逻辑耦合过强,不方便游戏逻辑的拓展

并且也不方便并行化

一般都会假设每个事件都是独立的

AI Basic

Navigation

游戏AI是玩法系统重要的组成部分,其中最基本的功能是允许玩家选择目的地进行导航(navigation)。

Navigation Steps

导航算法需要考虑游戏地图的不同表达形式,然后寻找到从起点到目的地的最短路径,有时还需要结合一些其它算法来获得更加光滑的路线。

在这里插入图片描述

Map Representation

因此我们首先需要考虑游戏中如何来表达地图,我们可以认为地图是玩家和NPC可以行动的区域(Walkable Area)。

Walkable Area 的范围对于不同属性的角色是不一样的,例如物理碰撞,攀爬坡度/高度,跳跃距离等属性

游戏中常见的地图形式包括路点网络图(waypoint network)、网格(grid)、寻路网格(navigation mesh)以及八叉树(sparse voxel octree)等。

Waypoint Network

waypoint network 是早期游戏中最常用的地图表示方式。我们可以把地图上的路标使用节点来表示,然后可通行的节点使用边来连接起来就形成了一个网络结构。

在这里插入图片描述
当玩家需要进行导航时只需要选择距离起点和目的地最近的两个路标,然后在网络图上进行导航即可。

在这里插入图片描述

waypoint network的优势在于它非常易于实现,而且我们有成熟的路径搜索算法可以直接应用在网络图上;但它的缺陷在于路网图需要不断地和开发中的地图进行更新,需要艺术家上手布置。而且使用路网进行导航时角色会倾向于沿路径中心前进而无法利用两边的通道。因此在现代游戏中路网的应用并不是很多。

在这里插入图片描述

Grid

网格同样是表达游戏地图的经典方法,常用的网格地图包括方格地图、三角形地图或是六边形地图等。

使用网格来表示地图时只需要把不可通行的区域遮挡住就可以了,因此网格可以动态地反映地图环境的变化。

请添加图片描述
显然网格地图同样非常容易实现,而且支持动态更新,也便于调试;而它的缺陷在于网格地图的精度受制于地图分辨率,而且比较占用存储空间,最严重的问题是网格很难表示重叠区域之间的连接关系,例如在一个区域上方架了一座桥,桥上面可以走,桥下面也可以走。

如果地图变大了,访问效率就会变低,因为每一行的长度很大,那么要访问的地址跳跃会很大

突然想到,对于那种移动速度慢的,能不能把一个大的网格分成一个个 tile,那么每次先存取 tile 然后在这个 tile 中存取要移动的点,这样就可以提高空间邻近性了

Navigation Mesh

为了克服网格地图的这些问题,人们开发出了寻路网格这样的地图表达形式。在寻路网格中可通行的区域会使用多边形来进行覆盖,这样可以方便地表达不同区域直接相互连接的拓扑关系。

在这里插入图片描述
在这里插入图片描述

在寻路网格中我们还会要求每个多边形都必须是凸多边形,这样才能保证角色在行进中不会穿过网格。

凸多边形还有一个好处是,两个多边形之间有且只有一个共享的边,这个边叫作 portal,凹多边形不能保证这一点

在这里插入图片描述
寻路网格是现代游戏中广泛应用的地图表达形式,而它的缺陷主要在于生成寻路网格的算法相对比较复杂,而且它无法表达三维空间的拓扑连接关系。

在这里插入图片描述

Voxel Voxel Octree

如果要制作三维空间中的地图则可以考虑八叉树这样的数据结构。

在边界细分

在这里插入图片描述
八叉树的存储也比较费,寻路也麻烦

Path Finding

得到游戏地图后就可以使用寻路算法来计算路径了,当然无论我们使用什么样的地图表达方式我们首先都需要把游戏地图转换为拓扑地图,然后再使用相应的算法进行寻路。

转换为拓扑地图:

在这里插入图片描述
最短路问题:

在这里插入图片描述
游戏中的寻路只需要看上去对就好了

深搜广搜

深搜需要找到所有的最短路,广搜需要遍历一遍所有地图才能给出最短路,都是一样比较昂贵的

于是可以使用迪杰斯特拉算法

Dijkstra

Dijkstra 算法可以计算从起始节点出发到图上任意节点的最短路径

首先假设其他所有顶点到出发点的距离为不可达,如果有边直接连接,那么距离再赋为边的权值

然后对各点依次松弛

不能处理负权值

A Star

Dijkstra 算法可以计算从起始节点出发到图上任意节点的最短路径,但它的缺陷在于图上很多节点对于我们想要计算的路径是没有意义的。因此人们还提出了 A star 算法来进行改进,在 A star 算法中通过引入一个启发式函数来控制节点访问的倾向性,使得路径的搜索会更倾向于访问目标点。

Cost calculation: 𝑓(𝑛) = 𝑔(𝑛) + ℎ(𝑛)

𝑔(𝑛): the exact cost of the path from the start to node 𝑛

ℎ(𝑛): the estimated cost from node 𝑛 to the goal

在网格中的 AStar,可以使用曼哈顿距离作为启发函数。

而在寻路网格中则可以使用欧氏距离作为启发函数。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
启发式算法的设计对于最终计算得到的路径会产生显著的影响。当启发函数的值过低时可能会需要更多次循环才能寻找到路径,而当启发函数值过高时则可能无法找到最短路径。因此在实际应用中需要进行一定的权衡。

请添加图片描述

Path Smoothing

直接使用寻路算法得到的路径往往包含各种各样的折线不够光滑,因此我们还需要使用一些路径平滑的算法来获得更加光滑的路径。

游戏导航中比较常用 funnel 算法来对折线路径进行平滑,它不仅可以应用在二维平面上也可以应用在寻路网格上。

https://blog.csdn.net/fengkeyleaf/article/details/118832924

我感觉来说,就是对于一个点 apex,从 apex 连向每一个 portal 的两端,得到的两条射线称为漏斗;由近及远,挨个遍历 portal,保存记录漏斗角度最小的那个 portal;如果某一次的漏斗的右边界在已保存的最小漏斗的左边界的左边,那么就代表需要拐弯,那么 apex 的下一个导航点就是已保存的最小漏斗对应的 portal 的左端点;如果某一次的漏斗的左边界在已保存的最小漏斗的右边界的右边,那么也代表需要拐弯,那么 apex 的下一个导航点就是已保存的最小漏斗对应的 portal 的右端点;刷新了 apex 之后,清空漏斗记录,重新开始寻找最小漏斗;当遍历到最后一个 portal 的时候,将当前导航点与终点相连

虽然别人的讲解中是用来寻路的

但是这不妨碍也用来 smoothing,我猜应该是已知一些导航点,现在想要简化这些导航点,就根据这些导航点找到导航点所在的多边形,然后对这些多边形在使用漏斗算法寻路,得到的就是简化的路径

对于游戏来说,在导航网络中寻路找到的网格是不共面的,所以这个漏斗算法还需要优化一下

NavMesh Generation

如何从游戏地图上生成寻路网格是一个相对困难的问题。

一般来说想要生成寻路网格首先需要将地图转换为体素,然后在体素地图上计算距离场得到区域的划分,最后就可以在划分好的区域中生成一个凸多边形网格作为寻路网格。

在这里插入图片描述
使用洪水算法对 walkable area 在空间上(或者说在 z 轴上?)进行类似 Voronoi 的划分

在这里插入图片描述

从一个个区域生成凸多边形也是需要算法的

在这里插入图片描述

NavMesh Advanced Features
Polygon Flag

除此之外我们还可以在多边形上设置不同的 flag 来触发不同的动画、声效以及粒子效果。

在这里插入图片描述
一般不会在生成的 nav mesh 上标注 flag,而是会先在生成之前的地图上标记,然后生成 nav mesh 之后将这些标记映射到 nav mesh 上

我猜应该是因为 nav mesh 可能在运行时动态生成吧

Tile

对于动态的环境我们可以把巨大的场景地图划分为若干个 tile。当某个 tile 中的环境发生改变时只需要重新计算该处的路径就可以得到新的路径。

这样就可以避免动态环境中,场景改变的时候每次都要重建整个场景的 nav mesh

但是这样有个问题是,怎么将每个 tile 上的 nav mesh 的顶点对齐

Off-mesh Link

还需要注意的是使用自动化算法生成的寻路网格是不包括传送点这样的信息的,有时为了提升玩家和场景的互动我们还需要手动设置这些传送点。当然这会导致寻路算法更加复杂。

Steering

得到最优路径后就可以根据路径来控制角色前进了。但在实际游戏中角色可能包含自身的运动学约束使得我们无法严格按照计算出的路径进行运动,这一点对于各种载具尤为明显。因此我们还需要结合 steering 算法来调整实际的行进路径。

例如车有惯性和转弯半径等

steering 算法可以按照行为分为以下几种:追赶和逃脱(seek/flee)、速度匹配(velocity match)以及对齐(align)。

Seek/Flee

seek/flee 的要求是根据自身和目标当前的位置来调整自身的加速度从而实现追赶或是逃脱的行为,像游戏中的跟踪、躲避或是巡逻等行为都可以使用 seek/flee 来实现。

Velocity Match

velocity match 的目的是利用当前自身和目标的相对速度以及匹配时间来进行控制,使得自身可以按指定的速度到达目标位置。

Align

align 则是从角度和角加速度的层面进行控制,使得自身的朝向可以接近目标。

Crowd Simulation

群体模拟(crowd simulation)是游戏 AI 必须要处理的问题。在游戏场景中往往会具有大量的 NPC,如何控制和模拟群体性的行为是现代游戏的一大挑战。

游戏场景中群体模拟的先驱是 Reynolds,他同时也是 steering 系统的提出者。目前游戏中群体行为模拟的方法主要可以分为三种:微观模型(microscopic models)、宏观模型(macroscopic models)以及混合模型(mesoscopic models)。

Microscopic Models

微观模型的思想是对群体中每一个个体进行控制从而模拟群体的行为,通常情况下我们可以设计一些规则来控制个体的行为。

在这里插入图片描述

Macroscopic Models

宏观模型的思想则是在场景中设计一个势场或流场来控制群体中每个个体的行为。

在这里插入图片描述

Mesoscopic Models

混合模型则综合了微观和宏观两种模型的思路,它首先把整个群体划分为若干个小组,然后在每个小组中对每个个体使用微观模型的规则来进行控制。这样的方法在各种 RTS 游戏中有着广泛的应用。

Collision Avoidance

群体模拟中的一大难点在于如何保证个体之间不会出现碰撞的问题。比较常用的方法是对每个个体施加一定的力来控制它的运动,这样就可以操纵群体的运动行为。

例如人群

另一种处理的方法是基于速度障碍(velocity obstacle, VO)来进行控制。

VO 的思想是当两个物体将要发生碰撞时相当于在速度域上形成了一定的障碍,因此需要调整自身的速度来避免相撞。

在这里插入图片描述
在这里插入图片描述

当参与避让的个体数比较多时还需要进行一些整体的优化,此时可以使用 ORCA 等算法进行处理。

Sensing

感知(sensing)是游戏 AI 的基础,根据获得信息的不同我们可以把感知的内容分为内部信息(internal information)和外部信息(external information)。

内部信息包括 AI 自身的位置、HP 以及各种状态。这些信息一般可以被 AI 直接访问到,而且它们是 AI 进行决策的基础。

而外部信息则主要包括 AI 所处的场景中的信息,它会随着游戏进程和场景变化而发生改变。

Static Spatial Information

在这里插入图片描述
smart object 类似一些场景交互物体,例如打碎一堵墙可以开辟道路

tactical map 是战术的掩护点地图

Dynamic Spatial Information

外部信息的一种常用表达方式是 influence map,场景的变化会直接反映在 influence map 上。当AI需要进行决策时会同时考虑自身的状态并且查询当前的 influence map 来选择自身的行为。

在这里插入图片描述

例如 influence map 记录地图上某点的威胁系数

Sensing Simulation

游戏 AI 进行感知时还需要注意我们不能假设 AI 可以直接获得所有游戏的信息,而是希望 AI 能够像玩家一样只利用局部感知的信息来进行决策。

如果每帧都 sensing 的话,就会成为性能瓶颈

所以可以设置 sensing 的精度,也可以设置 sensing 的 tick,也可以在单位之间共享 sensing 信息

在这里插入图片描述

Classic Decision Making Algorithms

在上面这些知识的基础上就可以开始构建游戏AI系统了。游戏AI算法的核心是决策(decision making)系统,经典的决策系统包括有限状态机(finite state machine, FSM)和行为树(behavior tree, BT)两种。

状态机和行为树是一步一步走的

HTN,GOAP,蒙特卡罗树搜索,深度学习,更像是目标驱动的,为了完成一个目标所以需要做一些动作

Finite State Machine

在有限状态机模型中我们认为 AI 的行为可以建模为在不同状态之间的游走,不同状态之间的切换称为转移(transition)。以吃豆人游戏为例,游戏AI可以使用一个包含3个状态的状态机来表示。

有限状态机的缺陷在于现代游戏中 AI 的状态空间可能是非常巨大的,因此状态之间的转移会无比复杂。

为了克服有限状态机过于复杂的问题,人们还提出了 hierarchical finite state machine(HFSM) 这样的模型。在 HFSM 中我们把整个复杂的状态机分为若干层,不同层之间通过有向的接口进行连接,这样可以增加模型的可读性。

Behavior Tree

在现代游戏中更为常用的决策算法是行为树,它的决策行为更接近人脑的决策过程。

行为树中的执行节点(excution node)表示 AI 执行的过程,它包括条件判断以及具体执行的动作两种节点。

行为树中的另一种节点是控制节点(control node),它用来表示决策过程的控制流。 control node 包括 sequence、selector、parallel 以及 decorator 等几种。

在这里插入图片描述

sequence 是表示对当前节点的子节点依次进行访问和执行,一般可以用来表示AI在当前状态下的行为计划。

selector 同样会遍历当前节点的子节点,但不同于 sequence 的地方是如果某个子节点返回 True 则会终止遍历。

sequence 遇到子结点 false 就返回 false,否则所有子结点 true 才返回 true

selector 遇到子结点 true 就返回 true,否则所有子结点 false 才返回 false

parallel 会同时执行当前节点下的所有子节点。

行为树在进行执行时需要注意每一次执行时都需要返回根节点。

在现代游戏中还提出了 decorator 节点来丰富可以执行的行为。

例如:

Loop execution

Execute once

Timer

Time Limiter

Value Modifier

或者这也是提高可读性的举措

在这里插入图片描述

我们还可以使用 precondition 和 blackborad 来提升决策过程的可读性。

在这里插入图片描述

行为树的决策过程非常符合人的决策行为而且也易于调试,因此广泛应用在各种游戏 AI 中。当然行为树也有一些缺点,比如说每次调用时都必须从根节点出发重新执行,这样的效率是比较低的。

由于 parallel 的存在,行为树中某一时刻可能有多个节点在运行

也有一些优化是,不强求在一个 tick 里面,从行为树的根节点出发一定要返回到根节点,而是可以在 tick 结束的时候,在行为树的指针停留在某些节点,下一个 tick 再从这些节点开始

如果存在这个优化,就要求设计师必须知道这个优化,因为如果存在这个优化,就意味着每一帧这个 AI 并不一定是从行为树根节点开始思考

例如,某一个 AI 可能在某几帧都停留在一个行为里面,在这个 AI 停留在这个行为的时候,这个 AI 收到了一些事件,这个事件的行为可能是改变黑板上的值,如果这个 AI 在这一帧是从行为树的根节点开始思考,根据这个黑板上的值,AI 应该去做行为 2,但是它实际上还是卡在行为 1

目前随着 AI 技术的发展,游戏AI也开始使用一些规划(planning)算法来进行决策。这些更先进的算法我们会在后面的课程进行介绍。

状态机和行为树是前向的,一步一步走

而有另外一种方法是从目标出发,

QA

行为树和 if else 有什么区别

逻辑上是可以等价的

只是硬写 if else 和 goto 看上去难以理解

AI 如何从环境中提取数据

从图中

或者使用反射

几百个 AI 看到几百个敌人

如何处理垂直邻接面的 NavMesh 生成

在世界中人为标记,之后映射到生成的 NavMesh 中

参考资料

Navigation

• Amit Patel’s fabulous website with animated demonstration of pathfinding algorithms:
http://theory.stanford.edu/~amitp/GameProgramming/
• In-depth explanation of Detour Recast Navmesh generation algorithm:
http://critterai.org/projects/nmgen_study/
• AI Summit: ‘Death Stranding’: An AI Postmortem, Eric Johnson, Kojima Productions, GDC 2021:
https://gdcvault.com/play/1027144/AI-Summit-Death-Stranding-An
• Getting off the NavMesh: Navigating in Fully 3D Environments, Dan Brewer, Digital Extremes, GDC
2015: https://gdcvault.com/play/1022016/Getting-off-the-NavMesh-Navigating
• Mikko Mononen, Author of Recast Detour, blog on Funnel Algorithm :
http://digestingduck.blogspot.com/2010/03/simple-stupid-funnel-algorithm.html?m=1

Steering & Sensing

• Steering Behaviors For Autonomous Characters, Craig W. Reynolds, Sony Computer Entertainment
America:
https://www.researchgate.net/publication/2495826_Steering_Behaviors_For_Autonomous_Characters
• AI For Games, Ian Millington, 3rd Edition, CRC Press, 2019
• Knowledge is Power, an Overview of AI Knowledge Representation in Games, Daniel Brewer:
http://www.gameaipro.com/GameAIProOnlineEdition2021/GameAIProOnlineEdition2021_Chapter04_
Knowledge_is_Power_an_Overview_of_AI_Knowledge_Representation_in_Games.pdf

Crowd Simulation

• A review on crowd simulation and modeling, Shanwen Yang, Tianrui Li, Xun Gong, Bo Peng, Jie Hu:
https://www.sciencedirect.com/science/article/abs/pii/S1524070320300242
• Forced-Based Anticipatory Collision Avoidance in Crowd Simulations, Stephen Guy, Ioannis
Karamouzas, University of Minnesota, GDC 2015: https://www.gdcvault.com/play/1022465/Forced-
Based-Anticipatory-Collision-Avoidance
• RVO and ORCA How They Really Work, Ben Sunshine-Hill:
https://www.taylorfrancis.com/chapters/edit/10.1201/9780429055096-22/rvo-orca-ben-sunshine-hill
• RVO2 Library: Reciprocal Collision Avoidance for Real-Time Multi-Agent Simulation, Jur van den
Berg, et al.: https://gamma.cs.unc.edu/RVO2/
• Documentation of AI systems in Unreal Engine 5: https://docs.unrealengine.com/5.0/en-US/artificial-
intelligence-in-unreal-engine/

Classical Decision Making Algorithms

• Behavior Trees in Robotics and AI: an Introduction, Michele Colledanchise and Petter Őgre, 1st Edition,
CRC Press, 2018,
https://www.researchgate.net/publication/319463746_Behavior_Trees_in_Robotics_and_AI_An_Introd
uction
• The Behavior Tree Starter Kit, Alex Champandard, Philip Dunstan, Game AI Pro, 2013:
http://www.gameaipro.com/GameAIPro/GameAIPro_Chapter06_The_Behavior_Tree_Starter_Kit.pdf
• FSM: Finite-State Machines: Theory and Implementation,
https://gamedevelopment.tutsplus.com/tutorials/finite-state-machines-theory-and-implementation–
gamedev-11867
• Managing Complexity in the Halo 2 AI System, Damian Isla, Moonshot Games, GDC 2005:
https://www.taylorfrancis.com/chapters/edit/10.1201/9780429055096-22/rvo-orca-ben-sunshine-hill

第十七节 游戏引擎 Gameplay 玩法系统:高级 AI

QA

怎么看待 AI 读取玩家操作指令

可以稍微读取一下,让 AI 更智能

但是 AI 不能无限聪明,AI 也不能收集所有信息

AI 行为的权衡

AI 可以低频地更新底层的行为,高频地更新细节的行为

单机游戏中 AI 的计算成本可以高一些

能不能将 AI 行为的计算分摊到网络中

可以单独一个服务器计算 AI,或者分布式

比较费的是抓取 AI 所需的环境信息上传服务器

如果是分布式的服务器的话,还需要分成很多份上传

Hierarchical Tasks Network

层次任务网络(hierarchical tasks network, HTN)是经典的游戏 AI 技术,和上一节介绍过的行为树相比 HTN 可以更好地表达 AI 自身的意志和驱动力。

HTN 的思想是把总体目标分解成若干个步骤,其中每个步骤可以包含不同的选项。 AI 在执行时需要按照顺序完成每个步骤,并且根据自身的状态选择合适的行为。

在这里插入图片描述

HTN Framework

这里写的 World State 是 AI 对世界的主观认知,而不是对世界的客观描述

Sensors 就是传感器

在这里插入图片描述
HTN Domain 就是层级 task

Planner 是制定的计划 task

plan runner 来执行计划,在 task 结束后更新 World State

HTN Task Types
  1. Primitive Task

  2. Compound Task

primitive task 一般表示一个具体的动作或行为。在 HTN 中每个 primitive task 需要包含 precondition、action 以及 effects 三个要素。

precondition 是读取 world state,effect 是修改 world state

在这里插入图片描述
例子

在这里插入图片描述
而 compound task 则包含不同的方法,我们把这些方法按照一定的优先级组织起来并且在执行时按照优先级高到低的顺序进行选择。每个方法还可以包含其它的 primitive task 或者 compound task,当方法内所有的 task 都执行完毕则表示任务完成。

在这里插入图片描述
例子:

在这里插入图片描述

说实话感觉像 if else 或者说像行为树的 sequence 和 selector 也行

在此基础上就可以构造出整个 HTN 的 domain,从而实现 AI 的行为逻辑。

HTN Domain

在这里插入图片描述
例子:

在这里插入图片描述

感觉这个 Domain 比较像复合任务的集合

Planning

接下来就可以进行规划了,我们从 root task 出发不断进行展开逐步完成每个任务。

第一步,从 root task 开始检查 precondition,选择一个满足条件的 compound task

在这里插入图片描述
第二步,对这个当前指向的 compound task 展开

在这里插入图片描述
在这个展开的 task 中,先把 world state 拷贝一份,然后检查 precondition,如果满足 precondition,那么就假设这个 task 的 action 可以成功执行,这些被假设了成功的 task 的 effect 修改的是拷贝的 world state

在这里插入图片描述

往下一直找,如果某一个 task 的 precondition 不满足就跳过

在这里插入图片描述
在这里插入图片描述

第三步,重复第二步直到没有 task 为止

最终的计划就只包含了原子任务

在这里插入图片描述
例子:

在这里插入图片描述

Run plan

依次执行 task,直到所有 task 都成功或者有一个 task 失败

在这里插入图片描述

Replan

replan 的时机:

没有计划时

当前的计划成功或者失败时

sensor 被触发,修改了 world state 时

在这里插入图片描述

总结

在这里插入图片描述
HTN 和 BT 非常相似,但它更加符合人的直觉也更易于设计师进行掌握。

多个 task 组合,可能 precondition 永远满足不了

如果 task 过长,但是世界变化很快,那么 AI 的行为就会变化很快,看上去振动一样

Goal-Oriented Action Planning

goal-oriented action planning(GOAP)是一种基于规划的AI技术,和前面介绍过的方法相比 GOAP 一般会更适合动态的环境。

Structure

在这里插入图片描述

GOAP 的整体结构与 HTN 非常相似,不过在 GOAP 中 domain 被替换为 goal set 和 action set。

Goal Set

在这里插入图片描述

goal set 表示 AI 所有可以达成的目标。在 GOAP 中需要显式地定义可以实现的目标,这要求我们把目标使用相应的状态来进行表达。

例子:

在这里插入图片描述

Action Set

而 action set 则接近于 primitive task 的概念,它表示 AI 可以执行的行为。需要注意的是 action set 还包含代价(cost)的概念,它表示不同动作的”优劣”程度。在进行规划时我们希望AI尽可能做出代价小的决策。

在这里插入图片描述

action set 没有树状结构,所以要用 cost 来选 action

Planning

GOAP在进行规划时会从目标来倒推需要执行的动作,这一过程称为反向规划(backward planning)。

在进行规划时首先需要根据优先级来选取一个目标,然后查询实现目标需要满足的状态。为了满足这些状态需求,我们需要从 action set 中选择一系列动作。需要注意的是很多动作也有自身的状态需求,因此我们在选择动作时也需要把这些需求添加到列表中。最后不断地添加动作和需求直到所有的状态需求都得到了满足,这样就完成了反向规划。

第一步,找到第一个 precondition 满足的 goal,这里的 precondition 满足不是说 goal 已经满足了,而是指的我有条件去完成这个 goal

在这里插入图片描述
第二步,查询这个 goal 对应的 state,与 world state 比较,找到那些不满足的 state,存入堆栈

在这里插入图片描述
第三步,从 stack 中取出一个要满足的 state,从 action set 中选择一个 action

具体而言,是从哪些成功时的 effect 是满足这个 state 的 action 中,选出一个 action

具体怎么从多个满足条件的 action 中选择一个呢,应该是用 cost 吧

在这里插入图片描述
第四步,将 action 压入 plan stack,检查这个 action 相应的 precondition,如果某些 precondition 没有满足,就讲这些没有满足的 precondition 压入 unsatisfied state

在这里插入图片描述
GOAP 的难点在于如何从 action set 进行选择,我们要求状态需求都能够得到满足而且所添加动作的代价要尽可能小。显然这样的问题是一个动态规划(dynamic programming)问题,我们可以利用图这样的数据结构来进行求解。在构造图时把状态的组合作为图上的节点,不同节点之间的有向边表示可以执行的动作,边的权重则是动作的代价。这样整个规划问题就等价于在有向图上的最短路径问题。

Build States-Action-Cost Graph

node 是 state 的组合

出发点是 goal 的 state node

结束点是当前 state node

在这里插入图片描述

The Lowest Cost Path

使用 A* 来找最短路

A* 不能保证找到最优的最短路,这也是有真实感的

在这里插入图片描述

Conclusion

在这里插入图片描述

总结一下 GOAP 可以让 AI 的行为更加动态,而且可以有效地解耦 AI 的目标与行为;而 GOAP 的主要缺陷在于它会比较消耗计算资源,一般情况下GOAP需要的计算量会远高于 BT 和 HTN。

Monte Carlo Tree Search

蒙特卡洛树搜索(Monte Carlo tree search, MCTS)也是经典的 AI 算法,实际上 AlphaGo 就是基于 MCTS 来实现的。简单来说,MCTS 的思路是在进行决策时首先模拟大量可行的动作,然后从这些动作中选择最好的那个来执行。

MCTS 的核心是 Monte Carlo方法(Monte Carlo method),它指出定积分可以通过随机采样的方法来进行估计。

States and Actions

以围棋为例,MCTS 会根据当前棋盘上的状态来估计落子的位置。

从数学的角度来看,我们把棋盘上棋子的位置称为状态(state),同时把落子的过程称为行为(action)。这样整个游戏可以建模为从初始节点出发的状态转移过程,而且所有可能的状态转移可以表示为一棵树。

在这里插入图片描述在这里插入图片描述在这里插入图片描述

显然构造出完整的树结构可能是非常困难的,不过实际上我们并不需要完整的树。在使用 MCTS 时,完成每一个行为后只需要重新以当前状态构造一棵新树即可。就是说重用一些 node

Simulation : Playing a Game in Mind Quickly

模拟(simulation)是 MCTS 中的重要一环,这里的”模拟”是指AI利用当前的策略快速地完成整个游戏过程。

缺省策略 default policy 相当于预先存好的棋谱,根据这个棋谱我可以立即查到胜率

这一次模拟成功了,不代表下一次同样会成功

在这里插入图片描述

Backpropagate

我们从同一节点出发进行不断的模拟就可以估计该节点的价值(胜率)。

Evaluation Factors Q/N Q 是在 N 次模拟中赢的次数

然后把模拟的结果从下向上进行传播就可以更新整个决策序列上所有节点的价值。

例如新增一个子节点,这个子结点会导致父树往上的 Q 和 N 的增加

在这里插入图片描述

Iteration Steps

这样我们就可以定义 MCTS 的迭代步骤如下:

选择一个最有希望,可能性没有完全展开的节点,展开一个新的子节点,模拟,然后反向传播

在这里插入图片描述

因为状态空间很大,所以需要一个迭代策略

请添加图片描述

Selection — Expandable Node

在对节点进行选择时,MCTS会优先选择可拓展的节点。

可拓展的 node,指的是可能性没有穷尽的 node

在进行拓展时往往还要权衡一些 exploitation 和 exploration,因此我们可以把 UCB 可以作为一种拓展的准则。

exploitation 开发 选择高 N 并且高 Q/N 值的节点

exploration 探测 选择低 N 的节点

在这里插入图片描述

UCB (Upper Confidence Bounds)

在这里插入图片描述
父节点的 N 除以当前节点的 N,相当于得到了当前节点的访问频率的一个相对的度量,这样就让 UCB 的值与问题规模无关了,常见的一个……正则化的手法?我乱说的hhhh

C 增大,访问少的更多被选中

C 减小,Q/N 值高的更多被选中,更保守

Selection

从当前节点一直找 UCB 最大的子节点,直到当前节点是可拓展的,那么就将当前节点设为选中的节点

在这里插入图片描述

Expansion

对节点进行展开时我们需要根据可执行的动作选择一组进行模拟,然后把模拟的结果自下而上进行传播。

在这里插入图片描述在这里插入图片描述

The End Condition

当对树的探索达到一定程度后就可以终止拓展过程,此时我们就得到了树结构上每个节点的价值。

在这里插入图片描述
然后只需要回到根节点选择一个最优的子节点进行执行即可。

具体怎么判断最优

max child 找 Q 最大的 child

robust child 找 N 最大的 child

因为实际上在拓展树的时候,是使用 UCB 来找哪个需要拓展的,这里 UCB 已经考虑了 Q 和 N 所以被拓展的多的就是潜力大的

max-robust child 找 Q 和 N 最大的 child

如果没有这样一个 child,那么就继续拓展树

secure child 综合考虑 Q 和 N

在这里插入图片描述

Conclusion

总结一下,MCTS 是一种非常强大的决策算法而且很适合搜索空间巨大的决策问题;而它的主要缺陷在于它具有过大的计算复杂度,而且它的效果很大程度上依赖于状态和行为空间的设计。

在这里插入图片描述
很难理解 MCTS 的行动

如果是那种回合制,行动导致的数值反馈明显的话,就方便数学建模,方便用 MCTS

Machine Learning

ML Types

近几年在机器学习(machine learning, ML)技术的不断发展下有越来越多的游戏AI开始使用机器学习来进行实现。根据学习的方式,机器学习大致可以分为监督学习、无监督学习、半监督学习以及强化学习等几类。

强化学习(reinforcement learning, RL)是游戏 AI 技术的基础。在强化学习中我们希望 AI 能够通过和环境的不断互动来学习到一个合理的策略。

Markov Decision Process

强化学习的理论基础是 Markov 决策过程(Markov decision process, MDP)。在 MDP中智能体对环境的感知称为状态(state),环境对于智能体的反馈称为奖励(reward)。MDP 的目标是让智能体通过和环境不断的互动来学习到如何在不同的环境下进行决策,这样的一个决策函数称为策略(policy)。

在这里插入图片描述
state 是某一帧

在这里插入图片描述
action 是角色控制

在这里插入图片描述
reward 是游戏逻辑的奖励

在这里插入图片描述

MDP Mathematical Model

环境是变化的,从某一个状态到另一个状态是有概率失败的

𝑝 (𝑠′ |𝑠, 𝑎) 是采取动作 a 从状态 s 到状态 s’ 的概率

根据自定义的决策,在某个状态下我根据已经制定好的决策,可能有多种行为

𝜋 (𝑎 |𝑠) = 𝑃 (𝐴𝑡 = 𝑎 |𝑆𝑡 = 𝑠) 是在状态 s 下采取行为 a 的概率

在计算总奖励的时候,因为策略是不靠谱的,所以人为在走第一步的时候得到的奖励是正确的,在走了多步之后得到的奖励要乘以一个系数的幂

这里就是在平衡短期收益和长期收益

在这里插入图片描述
policy 的优化问题就是我们要求的,得到的 policy 就是 AI 的行为

Build Advanced Game AI

之前的游戏 AI 的行为的所有 action 都是设计师设计好的

但是深度学习得到的 action 可能是设计师意想不到的

尽管目前基于机器学习的游戏 AI 技术大多还处于试验阶段,但已经有一些很优秀的项目值得借鉴和学习,包括 DeepMind 的 AlphaStar 以及 OpenAI 的 Five 等。

Machine Learning Framework in Game

这些基于深度强化学习(deep reinforcement learning, DRL)的游戏 AI 都是使用一个深度神经网络来进行决策,整个框架包括接收游戏环境的观测,利用神经网络获得行为,以及从游戏环境中得到反馈。

在这里插入图片描述

DRL Example
  1. State

  2. Action

  3. Reward

  4. NN design

  5. Training Strategy

State

以 AlphaStar 为例,智能体可以直接从游戏环境获得的信息包括地图、统计数据、场景中的单位以及资源数据等。

Maps

Heights
Visibility: fog of war
Creep
Entity owners
Alerts
Pathable
Buildable

Units Information

Unit type
Owner
Status
Display type
Position
Number of workers
Cool down
Attributes
Unit attributes
Cargo status
Building status
Resource status
Order status
Buff status

Actions

在 AlphaStar 中智能体的行为还取决于当前选中的单位。

• What
• move
• attack
• build
• Who
• Where
• When next action

Rewards

奖励函数的设计对于模型的训练以及最终的性能都有着重要的影响。在 AlphaStar 中使用了非常简单的奖励设计,智能体仅在获胜时获得+1的奖励;

还可以判断相同情况下 AI 的操作和人类的操作的比较,如果不一样就给予惩罚项

为了避免 reward 的绝对值过大导致没有意义,实际写的时候也会给这两个部分的 reward 加权的

而在 OpenAI Five 中则采用了更加复杂的奖励函数并以此来鼓励 AI 的进攻性。

而复杂的奖励函数可以导致 AI 不同的行为倾向

在这里插入图片描述

Network

在 AlphaStar 中使用了不同种类的神经网络来处理不同类型的输入数据,比如说对于定长的输入使用了 MLP,对于图像数据使用了 CNN,对于非定长的序列使用了 Transformer,而对于整个决策过程还使用了 LSTM 进行处理。

在这里插入图片描述
定长输入,例如一些固定的资源数等等

在这里插入图片描述
图像输入,例如 2d 地图,或者 FPS 中使用深度图

在这里插入图片描述
不定长输入,例如场上的不同种类的敌人数量

在这里插入图片描述
LSTM 用于历史记忆

在这里插入图片描述

Training Strategy

除此之外,AlphaStar 还对模型的训练过程进行了大规模的革新。在 AlphaStar 的训练过程中首先使用了监督学习的方式来从人类玩家的录像中进行学习。

接着,AlphaStar 使用了强化学习的方法来进行自我训练。

在这里插入图片描述
Main agent 主分支

League exploiter

League exploiter

三种对手

试验结果分析表明基于监督学习训练的游戏 AI 其行为会比较接近于人类玩家,但基本无法超过人类玩家的水平;而基于强化学习训练的 AI 则可能会有超过玩家的游戏水平,不过需要注意的是使用强化学习可能需要非常多的训练资源。

因此对于游戏AI到底是使用监督学习还是使用强化学习进行训练需要结合实际的游戏环境进行考虑。对于奖励比较密集的环境可以直接使用强化学习进行训练,而对于奖励比较稀疏的环境则推荐使用监督学习。

Hybrid

可以使用混合策略

在控制一些宏观行为的时候可以使用神经网络,在控制细节行为的时候可以用设计师配置的行为树等等

在这里插入图片描述

参考资料
HTN

• Humphreys T. Exploring HTN planners through example, Game AI Pro 360. CRC Press,
2019: 103-122.
https://www.gameaipro.com/GameAIPro/GameAIPro_Chapter12_Exploring_HTN_Plann
ers_through_Example.pdf
• An overview of hierarchical task network planning. Georgievski I, et al. arXiv preprint
arXiv:1403.7426, 2014. https://arxiv.org/abs/1403.7426
• Advanced Real-Time Hierarchical Task Networks: A New Approach. Tomohiro M, et al.
Square enix. GDC 2021. https://gdcvault.com/play/1027232/AI-Summit-Advanced-Real-
Time

GOAP

• Enhanced NPC behaviour using goal oriented action planning. Long E. Master’s Thesis,
School of Computing and Advanced Technologies, University of Abertay Dundee, Dundee,
UK, 2007.
https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.131.8964&rep=rep1&type=pdf
• Goal-oriented action planning: Ten years old and no fear! Chris C, et al. Crystal Dynamics.
GDC 2015. https://gdcvault.com/play/1022019/Goal-Oriented-Action-Planning-Ten
• AI Action Planning on Assassin’s Creed Odyssey and Immortals Fenyx Rising. Simon G.
Ubisoft. GDC 2021. https://gdcvault.com/play/1027004/AI-Action-Planning-on-Assassin

MCTS

• A survey of monte carlo tree search methods. Browne C B, et al. IEEE Transactions on
Computational Intelligence and AI in games, 2012, 4(1): 1-43.
https://www.researchgate.net/publication/235985858_A_Survey_of_Monte_Carlo_Tree_
Search_Methods
• Enhancements for real-time Monte-Carlo tree search in general video game playing.
Soemers D, et al. 2016 IEEE Conference on Computational Intelligence and Games
(CIG). IEEE, 2016: 1-8. https://ieeexplore.ieee.org/abstract/document/7860448/
• Action guidance with MCTS for deep reinforcement learning. Kartal B, et al. Proceedings
of the AAAI Conference on Artificial Intelligence and Interactive Digital Entertainment.
2019, 15(1): 153-159. https://ojs.aaai.org/index.php/AIIDE/article/view/5238

Machine Learning

• Great Chinese tutorial on reinforcement learning: Easy-RL, 人民邮电出版社, 2022,
https://github.com/datawhalechina/easy-rl
• Classic English textbook on reinforcement learning: Reinforcement Learning: an
introduction, MIT press, 2018,
https://web.Stanford.edu/class/psych209/Readings/SuttonBartoIPRLBook2ndEd.pdf
• Classic course on reinforcement learning: Stanford Course CS234:
https://web.Stanford.edu/class/cs234/
• Key papers on reinforcement learning selected by OpenAI:
https://spinningup.openai.com/en/latest/spinningup/keypapers.html

• Classic handbook on deep learning: https://github.com/janishar/mit-deep-learning-
book-pdf
• An introduction to convolutional neural networks, O’Shea K, et al. arXiv preprint
arXiv:1511.08458, 2015. https://arxiv.org/pdf/1511.08458.pdf
• Understanding LSTM – a tutorial into long short-term memory recurrent neural
networks, Staudemeyer R C, et al. arXiv preprint arXiv:1909.09586, 2019:
https://arxiv.org/abs/1909.09586
• Attention is all you need. Vaswani A, et al. Advances in neural information processing
systems, 2017, 30. : https://arxiv.org/abs/1706.03762

Machine Learning Game Applications

• Atari: Mnih V, et al. Playing atari with deep reinforcement learning. arXiv preprint
arXiv:1312.5602, 2013. https://arxiv.org/pdf/1312.5602.pdf
• Honor of Kings : Ye D, et al. Mastering complex control in moba games with deep
reinforcement learning. Proceedings of the AAAI Conference on Artificial Intelligence.
2020, 34(04): 6672-6679. https://ojs.aaai.org/index.php/AAAI/article/view/6144
• Dota2: Berner C, et al. Dota 2 with large scale deep reinforcement learning. arXiv
preprint arXiv:1912.06680, 2019. https://arxiv.org/pdf/1912.06680.pdf
• Starcraft2: Vinyals O, et al. Grandmaster level in StarCraft II using multi-agent
reinforcement learning[J]. Nature, 2019, 575(7782): 350-354.
https://www.nature.com/articles/s41586-019-1724-z.pdf

• DRL for navigation: Deep Reinforcement Learning For Navigation. Maxim P, et al. Ubisoft.
GDC 2021. https://gdcvault.com/play/1027382/Machine-Learning-Summit-Deep-
Reinforcement
• Machine Learning in game engine: It’s Complicated: Getting ML inside a AAA Engine.
Adrien L, et al. Ubisoft. GDC 2022. https://gdcvault.com/play/1027851/Machine-Learning-
Summit-It-s
• Age of Empires IV: ‘Age of Empires IV’: Machine Learning Trials and Tribulations. Guy L, et
al. Microsoft. GDC 2022. https://gdcvault.com/play/1027936/AI-Summit-Age-of-Empires
• Imitation Learning case: Buffing Bots with Imitation Learning. Niels J, et al. modl.ai. GDC
2022. https://gdcvault.com/play/1027942/AI-Summit-Buffing-Bots-with

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值