CD Code Digest Hub /CS:GO

Bot

11 分钟阅读 6 个章节 1 张图

CS:GO 的 Bot 是伪装成玩家的服务端实体:CCSBot 继承自 CCSPlayer,它不走网络,而是每帧自己构造一条 CUserCmd,直接交给玩家层的 ProcessUsercmds(跳过了引擎解码与游戏层的命令校验),之后与真人共用同一条命令执行路径。这意味着 Bot 受同样的移动、武器、规则约束。

相关页面:Bot 决策:感知、瞄准、档案与沟通 · 导航网格 · 玩家 · 输入与预测 · 主循环与 Tick · 投掷物与 C4

相关源码文件#

  • 通用模板:game/shared/cstrike15/bot/bot.h、game/shared/cstrike15/bot/bot.cpp、game/shared/cstrike15/bot/bot_manager.cpp、game/shared/cstrike15/bot/bot_profile.cpp
  • CS 实现:game/server/cstrike15/bot/(40 个文件),核心为 game/server/cstrike15/bot/cs_bot.h、game/server/cstrike15/bot/cs_bot_update.cpp、game/server/cstrike15/bot/cs_bot_manager.cpp、game/server/cstrike15/bot/cs_bot_statemachine.cpp、states/*.cpp

注意区分:仓库中还有通用的 game/server/NextBot 框架,但 CS:GO 服务端工程没有引用它;CS:GO Bot 使用的是 CBot<CCSPlayer> 这一套(本次在 server_cstrike15_inc.vpc 中未检索到 NextBot)。

1. 类型结构#

  • template <class PlayerType> class CBot : public PlayerType:提供移动/开火等“按键”原语,要求子类实现轻量的 Upkeep 与重量的 Update:game/shared/cstrike15/bot/bot.h:134-156、game/shared/cstrike15/bot/bot.h:159-193。
  • class CCSBot : public CBot< CCSPlayer >:game/server/cstrike15/bot/cs_bot.h:462;实体类名 cs_bot:game/server/cstrike15/bot/cs_bot.cpp:21。

2. 每帧驱动#

证据:

  • EndGameFrame 中调用 TheBots->StartFrame(),注释说明放在物理模拟之后,以免可见性检查重复计算骨骼:game/shared/cstrike15/cs_gamerules.cpp:9886-9893;EndGameFrame 本身在 GameFrame 末尾调用:game/server/gameinterface.cpp:1507-1512。
  • CCSBotManager::StartFrame:暂停或不允许 Bot 时返回;调用通用 StartFrame;半场换边期间之外维护 Bot 数量:game/server/cstrike15/bot/cs_bot_manager.cpp:300-320。
  • CBotManager::StartFrame:对每个 Bot 每帧 Upkeep;当 (tickcount + entindex) % g_BotUpdateSkipCount == 0 时 ResetCommand + Update(把重计算错开到不同 tick);最后 UpdatePlayer:game/shared/cstrike15/bot/bot_manager.cpp:103-153。
  • UpdatePlayer:冻结时清零按键与速度;用当前视角、前后/侧向/竖直速度与按键位 BuildUserCmd,做玩家避让,然后 ProcessUsercmds( &m_userCmd, 1, 1, 0, false ) 把命令排队:game/shared/cstrike15/bot/bot.h:860-889。

因此 Bot 的命令同样在下一次 Physics_RunThinkFunctions 中由 PlayerRunCommand 执行(见 输入与预测)。

3. 行为:状态机#

BotState 只有 OnEnter/OnUpdate/OnExit/GetName:game/server/cstrike15/bot/cs_bot.h:56-63。具体状态包括空闲(行动选择中枢,注释说明 Bot 不会停留在该状态)、搜寻、攻击、调查声音、购买、移动、取包、下包、拆包、捡人质、隐藏、逃离炸弹、跟随、使用实体、开门、逃离火焰:game/server/cstrike15/bot/cs_bot.h:66-442,各状态实现在 states/ 目录。

SetState 退出正在进行的攻击、调用旧状态 OnExit 与新状态 OnEnter 并记录时间戳:game/server/cstrike15/bot/cs_bot_statemachine.cpp:23-56。CCSBot::Update 在做完卡住检测、反应队列、威胁评估(必要时切到 Attack)、武器选择等通用逻辑后,调用当前状态的 OnUpdate:game/server/cstrike15/bot/cs_bot_update.cpp:232、game/server/cstrike15/bot/cs_bot_update.cpp:311、game/server/cstrike15/bot/cs_bot_update.cpp:373、game/server/cstrike15/bot/cs_bot_update.cpp:475-480、game/server/cstrike15/bot/cs_bot_update.cpp:880。轻量的 Upkeep(源码注释称“lightweight maintenance, invoked frequently”)每个 tick 都运行,负责平滑瞄准与视角弹簧,网格生成中或死亡时直接返回:game/shared/cstrike15/bot/bot.h:155-156、game/server/cstrike15/bot/cs_bot_update.cpp:29-142。Update 内各阶段的完整顺序、感知与开火判定见 Bot 决策。

Bot 通过游戏事件感知世界,例如 C4 每次 C4Think 都触发 bomb_beep 让 Bot“听到”:game/shared/cstrike15/weapon_c4.cpp:403-410;烟雾弹引爆时向 Bot 管理器登记烟雾半径,用于视线判断:game/shared/cstrike15/smokegrenade_projectile.cpp:177。事件如何分发到每个 Bot、各声源的可闻距离见 Bot 决策。导航网格在每个 GameFrame 更新:game/server/gameinterface.cpp:1472;其结构、加载与寻路见 导航网格。

4. 数量管理#

ConVar含义证据
bot_quota(默认 10)目标 Bot 数game/server/cstrike15/bot/cs_bot_init.cpp:63
bot_quota_modenormal:固定数量;fill:真人 + Bot = quota;match:Bot = quota × 真人数game/server/cstrike15/bot/cs_bot_init.cpp:64

MaintainBotQuota 根据模式计算期望数量,没有真人也没有旁观者时期望为 0:game/server/cstrike15/bot/cs_bot_manager.cpp:1435-1497。手动添加走 BotAddCommand:game/server/cstrike15/bot/cs_bot_manager.cpp:1035。离线模式下 Bot 难度相关 ConVar 由游戏模式表限定(见 比赛模式)。

约束与边界#

  • 本页只覆盖类型结构、每帧驱动、状态机框架与数量管理。视觉/听觉与反应队列、瞄准与开火、BotProfile.db 格式及字段作用、路径跟随与卡住恢复、购买、语音聊天与无线电、炸弹/人质等战术事件响应见 Bot 决策;Bot 语音与玩家无线电共用的响应规则与场景播放见 场景与响应规则;导航网格的数据结构、.nav 格式与加载、分阶段生成、A* 寻路见 导航网格。注意 game/shared/cstrike15/bot/nav_path.cpp 未被编入 CS:GO 服务端,实际编译的是内容几乎相同的 cs_nav_path.cpp:game/server/server_cstrike15_inc.vpc:345-356。
  • .nav、BotProfile.db、BotChatter.db 都属于内容,不在仓库中。缺少 .nav 时,添加 Bot 会在 PC 上触发一次自动生成(主机平台直接拒绝),生成期间不允许 Bot 加入:game/server/cstrike15/bot/cs_bot_manager.cpp:1037-1060。
  • 仍未展开:game/server/NextBot 框架(CS:GO 未使用)、投掷物的目标选择与投掷状态机、人质护送与跟随细节、合作模式(Guardian / Coop Mission)专用逻辑。