[翻译] 求生之路AI系统讲稿

之前在某网站上无意间看到关于求生之路(L4D)的AI系统讲稿ppt,所以特地去研究阅读了一下,看了第一遍后感觉也是懵懵懂懂的(英文真的令人头疼),算是大概了解了下流程,所以决定写一篇文章,好好记录一下具体讲了些啥。
当然由于本人知识存储或者英文翻译带来的理解不同可能会造成曲解,也请见谅!
讲稿可以从我的学习资料中找到。

一. 四个方面

具体讲解之前,先介绍一下求生之路这款游戏。

求生之路是Valve公司发行的一款第一人称设计游戏,使用的是起源引擎进行开发(半条命、CSGO等都是这款引擎)。求生之路中,剧情设定是在现代城市的恐怖氛围中,有成群的受感染的僵尸大军和恐怖的BOSS级变种人会持续来寻找攻击你,最多能组成四名"幸存者"一起同心协力杀出一条血路找到出口。

下面开始正题!

讲稿内容主要围绕着四个方面进行探讨,分别是:

该章具体围绕僵尸AI的寻路路径规划、行为决策进行展开。

该章简单描述了一下电脑AI在幸存者阵营的决策处理。

该章介绍了一个"AI Director"的系统,通过该系统来产生一定随机性以及重复可玩性。

该章具体讲述了如何把控游戏的整体节奏感,让每名幸存者都有不同的"情感强度"。

二. Deliver Robust Behavior Performances

首先讲到的是僵尸AI的移动路径规划。我们可以先看张图

对于环境中的移动,采用的是:

  • 在导航网格中使用A*算法
  • 创建层次不齐的路径选择
    这就引出了一个问题:如何让其移动时显得流畅
(1). 路径最优化


主要的思路就是:收缩路径上冗余的结点

同时带来了好处和坏处:

  • 好处: 创建了最小限度以及最直接的路径
  • 坏处: 在规划路径时对CPU性能消耗是不俗的
        在游戏中有些路径会经常被重新计算
        这样的跟随路径看上去很机械化
(2). 反应型跟随路径


主要思路就是:朝着“向前看”的方向走更远的路径
       采用局部躲避障碍

  • 好处: 路径重绘是节省的
        局部回避处理了一些小的物理道具、其他电脑bot以及角落等
        对于僵尸们的蜂拥而至有着完美配合
        结果产生的动作是易变的
  • 坏处: 可以避免过多路径的产生,但是需要重新绘制路径

看一下行径的过程

我们将路径最优情况和反应型跟随路径进行一下对比

(红线: 最优情况  蓝线: 反应型)

可以看到 反应型跟随路径产生的路径结果和最优情况的路径非常相接近
所以这就导致了在L4d中所有游戏角色都是采用反应型路径跟随

(3). 攀爬功能
  • 为了让游戏中常见的成群僵尸显得危险,他们有能力可以进行快速攀爬。
  • 攀爬是一种算法规则,使用相似的技术来局部躲避障碍
  • 攀爬算法主要解决两个问题:
    • 在游戏中错综复杂的几何路径导航
    • 借助可移动物理小道具来导航

以下是目标呈现图:

方法

电脑Bot会周期性地对其路径上前方出现的障碍物进行检测

寻找上限

一旦障碍物被发现,进行另一个寻找bot上方垂直有效空间的包围体检测

寻找高处通路

通过一系列由低到高的包围体检测扫描竖直空间,来发现第一个畅通无阻的包围体路径

寻找高处通路高度

另一种自下寻找畅通无阻的踪迹,可以找到高处通路的精确高度

寻找高处通路边缘点

最后用一系列向后步进的向下包围体检测高处通路边缘

攀爬展示

从数十个不同高度增量的攀爬动画中选择最接近的匹配动画

(4). 行为和决策
  • 运动: 在场景中控制角色移动到一个新的位置(如冲突解决等)
  • 身体: 控制动画状态
  • 视角: 控制视线,视角以及"我是否能看见xxx"的问题. 维护可识别的实体集
  • 目的: 包含并管理一个并发行为系统(HFSM + Stack)
    • 行为: 包含并管理动作系统
    • 动作: 自发行为模块. 一个动作可以包含一个可并发执行的子动作
动作执行的封装
  • OnStart: 当动作刚刚开始就执行并且可以立即返回转换
  • Update: 动作的执行工作并且可以返回转换到一个新的动作
  • OnEnd: 当动作被转换结束时执行
  • OnSuspend: 当该动作被另一个动作挂起时执行并且可以返回一个转换
  • OnResume: 当动作被挂起后处于暂停时执行并且可以返回一个转换(可能该动作不再有效了)
动作转换
  • Continue(): 没有转换,在下一帧继续执行该动作
  • ChangeTo( NextAction, “reason”): 退出当前动作并且转换到NextAction
  • SuspendFor( NextAction, “reason”): 将当前动作暂时不处理(悬挂)转而进入NextAction
  • Done(“reason”): 动作已经完成. 恢复被悬挂的动作
  • “reason”: 由字符串记录转换发送的原因(例如: “被我追赶的玩家已经死亡”). 字符串原因可以帮助动作系统更加明了并且对于实时进行调试输出是非常珍贵的
动作转换的封装
  • 返回动作的结果会强制执行原子转换,因为在更改为新动作的决策和实际更改之间不能运行任何行为代码
  • 对于从动作A转换到动作B只有一种方法就是由A返回一个转换给B
  • 在没有动作A的认知情况下,没有方法可以强制产生一个由动作A到动作B的转换
  • 将相关的行为代码封装在动作中
事件传播
  • 事件传播是对所有组件而言的
  • 在目的子系统中,事件是:
    • 首先被最内部的子动作操作处理
    • 如果子动作没有回应,事件将会被设至"悬挂动作"
    • 如果"悬挂动作"都没有任何一个回应,事件将会送至父动作
事件举例

OnMoveToSuccess, OnMoveToFailure, OnStuck, OnUnStuck, OnAnimationActivityComplete, OnAnimationEvent, OnContact, OnInjuered, OnKilled, OnOtherKilled, OnSight, OnLostSight, OnSound, OnPickUp, OnDrop

  • 动作可以实现事件触发(Event Handler),为游戏事件提供特定的上下文响应
上下文查询系统
  • 动作可以实现查询方法,为提出的问题提供特定的上下文答案
  • 将可以向行为或动作系统提出的查询定义为“黑匣子”
  • 查询从最内部动作向外传播,直到给出一个答案,这与事件传播相同
  • 允许并发行为进行协调
    • 例如: 我们有机会捡起一个物体,如何?
查询举例
  • SelectMoreDangerousThreat( me, subject, threat1, threat2): 允许电脑Bot发现对其他人最危险的威胁
  • ShouldPickUp (是否应该捡起)
  • ShouldHurry (是否应该快点跟上)
  • IsHindrance (是否是障碍)

三. Provide Competent Human Player Proxies

幸存者Bot
  • 允许我们假定4个玩家幸存者团队进行游戏调整和平衡
  • 在野外非常有帮助
  • 让4个幸存者Bot进行压力测试进而加快时间进度
信任/公平
  • 玩家需要相信电脑bot的在己方时是公平的
  • 模拟不完美的感官认知
  • 模拟瞄准
  • 反映时间
  • 可靠性并且可预测决策
    • 困难点: 拯救倒地的人类
信任
  • 游戏的合作性要求幸存者团队的紧密协作和对队友行动的选择有潜在信任
  • 幸存者Bot会优先考虑人类队友而不是bot
  • 游戏内的“小作弊”以保证一些不希望发生的事件不会发生
    • 幸存者Bot不会不友好地进行开火伤害
    • 幸存者Bot不会使用燃烧瓶
    • 如果一个幸存者Bot出于任何原因离当前地方很远,它将会在人类玩家中没有看向它时传送至小队附近
幸存者Bot进行了复杂性封装
  • 两个并发行为系统: MainLegs

    • Main: 首要进行决策, 注意力, 目标选择和攻击
    • Legs: 受Main所控制,负责与团队保持紧密联系,除非另有指示
  • 许多分层的行为状态对各类游戏事件做出反应

    • 例如: 打断、恢复
  • 复杂的上下文决策

    • Tank/Witch/Boomer/Smoker/Hunter/Mob冲锋、巡逻;幸存者队友道具清理、自救、救人、武器选择、营救、陷害、跛行;处理复杂3D地形、移动物理障碍、火堆、梯子、电梯;以上任意组合
  • 基于实际游戏体验来复刻人类表现

    • 构建的行为系统为重现玩家在玩游戏时做出的决定和动作。

四. Promote Replayability

  • 可重玩性促使玩家长期在游戏上投入, 从而使游戏社区持续增长

    • 持续增长的在线社区促进销量提升
    • 创造新的周边业务
  • 例如: CS、Team Fortress、Day of Defeat

    • 销售收入伴随在线社区增长
    • 极少的地图满足玩家若干年的反复挑战
    • 由玩家团队之间的交互所创造的不可预测的体验推动了可重玩性
  • 在求生之路中程序化的敌人和生成的战利品会极大的提升耐玩度

    • 构建不可预知的遭遇战斗,类似于CS、TF、DoD
    • 游戏挑战被视作技巧挑战而不是背板
  • 静态的敌人和战利品不利于可玩性

    • 玩家擅长记忆静态位置
    • 消除了未知情况的悬念
    • 造成每次游戏都选择"最优策略"
    • 玩家期望每人都有相同的熟练记忆
    • 扼杀团队合作会导致成竞争
  • 即使有多类手动设置的触发器、脚本也无济于事

    • 玩家会学会一切。一旦他们没遇到A,他们就会准备迎接B或C等
  • 我们如何实现基于程序化并且有趣的怪物分布呢?

    • 使用结构性未知
    • 使用系统集合中的"AI Director"
  • 首先, 对于生成结构性未知的工具总结

    • 导航网格
    • 流程距离
    • 潜在可见性
    • 可活动区间
导航网格
  • 描述可行走空间
  • 起源于CS中电脑Bot的寻路
  • 有助于空间推理和空间局部信息获取
    • 区域A是否已经被角色B看见?
    • 获取X对于区域Y是否潜在性可见?
    • 靠近却不被幸存者看见的区域在哪?
    • 到达某区域需走多远?
流程距离
  • 在导航网格中从起始安全房间到其他每个区域的移动距离
  • 引导逐渐增加流程梯度总会将你带到出口房间
  • “逃跑路径” = 从起始点到出口的最短距离
  • 用于作为敌人和战利品生成的参照,并且可用于回答"这个区域在幸存者团前方还是后方"的问题
可活动区间(AAS)
  • 包围幸存者团队的导航区域集
  • AI Director根据AAS在环境中移动创建、销毁刷怪点
  • 利用一个很小的对象池允许对成百上千的敌人复用
潜在可见性
  • 对任意一个幸存者潜在可见的区域组成的集合

可活动区间

通过结构性未知做程序化生成
  • 并非随机,也不是固定
  • 基于空间或时间变化依据策划定义的随机量的生成函数
    • 例: 怪物批次
    • 在90到180秒见随机间隔发生
    • 在幸存者"后方"随机生成
  • 结构化未知 = 上述算法有限次叠加组合
求生之路的结构性未知策略
  • 巡逻怪(高频)
    • 普通被感染者会游荡巡逻直到看见幸存者
  • 聚众怪(中频)
    • 一大群(20-30个)被感染者周期性的冲向幸存者
  • Boss(低频)
    • 强力的被感染者会驱使幸存者改变策略
  • 武器库(低频)
    • 更有效的武器集
  • 批量杀伤性武器(中频)
    • 炸弹、燃烧瓶、止痛药、肾上腺素等
巡逻怪生成策略
  • 在区域中简单存储为一个数量(N)

  • 地图开始时基于逃生路径长度和期望密度随机决定数量

  • 区域进入AAS

    • (如果可行) 创建N个被感染者
  • 区域离开AAS, 或有等待群聚的怪

    • 区域中的巡逻怪被删除且N因此增大
  • 巡逻怪数量(N)清零

    • 当区域对任意幸存者可见时
    • 当Director处于Relax模式时
    • 绿色区域进入AAS且巡逻怪开始生成
    • 红色区域离开AAS且被感染者将被清除
群聚怪生成策略
  • 在一定时间间隔内随机生成(普通难度为90-180秒)
  • Boomer Vomit强制暴走怪开始袭来,重置随机间隔
  • 群聚怪规模在刚打到顶峰后间隔片段从谷低值开始再次增长, 用以平衡群聚怪连续程度
特殊感染怪生成策略
  • 在随机时间间隔点单个生成
  • 依不同特殊类型使用对幸存者不可见的有效AAS
    • Boomer因其不善于追赶故迎面袭击
    • Smoker尝试选择高于幸存者队伍的地段
从哪开始袭击
  • 抄幸存者后路

    • 仅选取处于幸存者队伍流程距离或其后的有效AAS
    • 巡逻怪和特殊感染怪、Boss经常抄前路、75%的群聚怪选择抄后路
  • 抄幸存者前路

    • 仅选取处于幸存者队伍流程距离或其前方的有效AAS
  • 近距Boomer Vomit Victim

    • 仅选取处于Boomer Vomit Victim流程距离附近的有效AAS
  • 任意位置

    • 任意有效AAS
    • 若特定集合不存在有效区域则以此策略默认
Boss生成策略
  • 在逃生路上每隔N个单位生成一个,进入地图开始时+/-随机数量
  • 三个Boss事件乱序并执行: Tank、Witch、无
  • 不允许连续相同的生成(例:Tank,然后还是Tank)
武器库
  • 地图策划在每张地图中创建若干个可能的武器库,AI Director从中挑选哪些将存在
批量杀伤性武器
  • 地图策划在每张地图中穿插若干组可能的批量杀伤性武器,AI Director从中挑选哪些组将存在
为何策划放置?
  • 预设位置适用于此类物体
  • 允许可视化叙事/交代
  • 解决道具放置问题(斜靠着墙,置于枪架上等)
程序化内容
  • 促进可玩性
  • 带来线性的,引人入胜的多人游戏体验
  • 增加游戏制作团队产出
  • 鼓励社区自制内容

五. Generate Dramatic Game Pacing

  • 什么叫 “引入注目的游戏节奏感”?
    • 在运行时依算法调节游戏节奏以最大化让玩家投入进游戏(玩家体会激动、刺激)
  • 灵感来源于CS
    • 在CS中节奏比较固定,在平静的紧张氛围下,不时会出现一些剧烈的时刻
    • 一成不变的战斗是令人疲惫的
    • 长时间的不活动是无聊的
    • 出乎意料的峰谷交错节奏产生了耐玩的体验
    • 相同的场景,通常是相同的地图,但每一轮都有与众不同的经验。
自适应节奏算法
  • 创建类似于CS这样成功的跌宕起伏强烈节奏的
  • 算法:
    • 评估每个幸存者的"心情程度"
    • 跟着四名幸存者中心态程度最大值
    • 如果数值过高,这段时间移除主要威胁
    • 否则创建一大批令人感到威胁的怪
  • 另外一个关键系统"AI Director"
评估每名幸存者的"心情程度"
  • 将每名玩家心情值量化
  • 提高幸存者心情值
    • 当被攻击时,会受到一定比例伤害
    • 丧失战斗能力(倒地)
    • 当幸存者在平台边缘被怪推搡时
    • 当附件的怪死掉时,与距离成比例
  • 幸存者"心情程度"随时间衰减直至0
  • 当有怪威胁到幸存者时不进行处理
依幸存者激动程度调节怪生成策略
  • 逐渐提高
    • 持续生成对幸存者造成威胁直到超过幸存者心情值的最高峰
  • 维持
    • 当幸存者心情值达到波峰持续3到5秒全力进攻
    • 确保最小"逐渐提高"的过程
  • 逐渐降低
    • 切换至最小威胁(“放松阶段”)并监控玩家心情值直至衰减至波峰范围外
    • 这种状态对于当前的战斗交战是必要的,可以在不消耗整个放松阶段的情况下发挥出来。高峰淡出不会允许放松阶段开始,直到一个行为发生产生了自然打断。
  • 放松
    • 维持最小的威胁30-45秒,若幸存者已基本跑到下一处安全房间则重新回到"逐渐提高"
满状态威胁阶段怪
- 巡逻怪
- 群聚怪
- 特殊感染怪
最小威胁阶段(放松)
- 无巡逻怪直到小队平静时  
- 无群聚怪
- 无特殊感染怪(残余部队将继续进攻)  
不受节奏阶段影响的Boss怪
- 如果Boss消失,整体节奏感就会影响很多
- 遭遇Boss会让整个节奏感进行改变
AI Director如何依幸存者团队“心情程度”调节生成策略

自适应引人入胜的节奏感在于幸存者队伍
  • 不需要压倒性的压力就可以让队伍体验紧张的战斗节奏
  • 因玩家每次的行动和程序化生成都千差万别,每次游戏过程体验不同
算法调整节奏而不是难度
  • 节奏幅度(难度)恒定,频率(节奏)会改变
简单的算法可产生深刻的节奏
  • 幸存者心情程度只是粗略估计,然而调节节奏感是有效的
这只是个起点
  • 扩大AI可用的动词库
  • 进一步探索程序内容生成的机会
  • 如何在其他游戏项目中使用这些系统?

翻译完毕…乘着每天下班回家后的1-2个小时功夫终于翻译完了…当然有些地方理解以及翻译可能存在误解,有不理解的可以自行找到对应PPT理解…

  • 9
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值