Difference between revisions of "CS:GO Bot Behavior Trees"

From Valve Developer Community
Jump to: navigation, search
(Created page with "{{construction-notice|Currently writing this article, please don't edit. ty! -~~~|align=center|float=right|width=30%}} In {{csgo}} Counter-Strike: Global Offensive, bot...")
 
m
(One intermediate revision by the same user not shown)
Line 1: Line 1:
{{construction-notice|Currently writing this article, please don't edit. ty! -[[User:9yz|9yz]] ([[User talk:9yz|talk]])|align=center|float=right|width=30%}}
+
{{lang|CS:GO Bot Behavior Trees}}
 
+
{{stub}}
In {{csgo}} [[Counter-Strike: Global Offensive]], [[bot|bots]] can be given a behavior tree to follow. A behavior tree dictates how the bot senses things (vision, hearing, damage sensing), moves, attacks, and does other actions. They can be customized for the [[Creating a Co-op Strike Map|Co-op gamemode]] (with [[info_enemy_terrorist_spawn]]) and the [[Creating a Guardian Scenario Map|Guardian gamemode]], and are also used internally for [[CS:GO Gamemodes: Deathmatch|Deathmatch]].
+
{{update}}
 +
In {{game name|csgo|name=Counter-Strike: Global Offensive}}, [[bot|bots]] can be given a behavior tree to follow. A behavior tree dictates how the bot senses things (vision, hearing, damage sensing), moves, attacks, and does other actions. They can be customized for the [[Creating a Co-op Strike Map|Co-op gamemode]] (with {{ent|info_enemy_terrorist_spawn}}) and the [[Creating a Guardian Scenario Map|Guardian gamemode]], and are also used internally for [[CS:GO Gamemodes: Deathmatch|Deathmatch]].
  
 
Behavior trees were first [https://blog.counter-strike.net/index.php/2019/09/25510/ added to the game] on September 16, 2019. Since September 1, 2020, [https://blog.counter-strike.net/index.php/2020/09/31532/ behavior trees can be packed into BSP files]
 
Behavior trees were first [https://blog.counter-strike.net/index.php/2019/09/25510/ added to the game] on September 16, 2019. Since September 1, 2020, [https://blog.counter-strike.net/index.php/2020/09/31532/ behavior trees can be packed into BSP files]
Line 202: Line 203:
 
}
 
}
 
}
 
}
 
 
</source>
 
</source>

Revision as of 12:38, 24 September 2021

English

In Counter-Strike: Global Offensive Counter-Strike: Global Offensive , bots can be given a behavior tree to follow. A behavior tree dictates how the bot senses things (vision, hearing, damage sensing), moves, attacks, and does other actions. They can be customized for the Co-op gamemode (with info_enemy_terrorist_spawn) and the Guardian gamemode, and are also used internally for Deathmatch.

Behavior trees were first added to the game on September 16, 2019. Since September 1, 2020, behavior trees can be packed into BSP files

They use Valve's proprietary KeyValues3 format (.kv3), which is a text-based format with somewhat strict syntax. They typically use the bt_ prefix, to signify that file is a Behavior Tree. They are stored in csgo/scripts/ai.

Format

The first line of a .kv3 file is always a header specifying the KV3 version. For CS:GO, use this header:

<!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d} format:generic:version{7412167c-06e9-4698-aff2-e63eb59037e7} -->


Subtrees

Commands

Control Flow

Movement

Items

Sensing

Other

Examples

Default Deathmatch Behavior Tree

Found in csgo/scripts/ai/bt_default.kv3

<!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d} format:generic:version{7412167c-06e9-4698-aff2-e63eb59037e7} -->
{
	config = "scripts/ai/deathmatch/bt_config.kv3"
	root =
	{
		type = "decorator_bot_service"
		memory_to_expire =
		[
			{
				key = "ShortTermAttackMemory"
				time = 0.7
				distance = 0
			},
			{
				key = "LongTermMemory"
				time = 10
				distance = 500
			},
			{
				key = "ShortTermInvestigateMemory"
				time = 3
				distance = 200
			}
		]
		child =
		{
			type = "decorator_buy_service"
			output = "ShouldBuy"
			child =
			{
				type = "parallel"
				children =
				[
					{
						type = "decorator_repeat"
						child =
						{
							type = "parallel"
							children =
							[
								// memorize enemies through vision
								{
									type = "subtree"
									file = "scripts/ai/modules/bt_memorize_enemies_vision.kv3"
									name = "MemorizeEnemiesVision"
								},
								// memorize noises happening right now
								{
									type = "subtree"
									file = "scripts/ai/modules/bt_memorize_noises.kv3"
									name = "MemorizeNoises"
								},
								// record the nearest memorized event to investigate
								{
									type = "subtree"
									file = "scripts/ai/modules/bt_memorize_nearest_investigation.kv3"
									name = "MemorizeNearestInvestigation"
								}
							]
						}
					},
					{
						type = "decorator_repeat"
						child =
						{
							type = "selector"
							children =
							[
								// Buy if we have to
								{
									type = "condition_is_empty"
									input = "ShouldBuy"
									negated = 1
									child =
									{
										// sequencer: evaluate first to last child, in order
										type = "sequencer"
										children =
										[
											{
												type = "action_wait"
												wait_time_min = 3
												wait_time_max = 3
											},
											{
												type = "action_buy"
											},
											{
												type = "decorator_remove_key"
												input = "ShouldBuy"
											}
										]
									}
								},
								// Else: face the damage source if we're taking damage
								{
									type = "decorator_sensor"
									entity_type_filter = "DAMAGE"
									output = "Damage"
									priority = 0
									child =
									{
										type = "condition_is_empty"
										input = "Damage"
										negated = 1
										child =
										{
											type = "action_aim"
											input = "Damage"
											acquire_only = 1
										}
									}
								},
								// Else: attack if we see an enemy
								{
									type = "subtree"
									file = "scripts/ai/modules/bt_attack.kv3"
									name = "Attack"
								},
								{
									type = "subtree"
									file = "scripts/ai/modules/bt_heal_if_needed.kv3"
									name = "HealIfNeeded"
								},
								// Else: investigate the closest memorized event
								{
									type = "subtree"
									file = "scripts/ai/modules/bt_investigate_closest_memorized_event.kv3"
									name = "InvestigateClosestMemorizedEvent"
								},
								// Else: hunt
								{
									// sequencer: evaluate first to last child, in order
									type = "sequencer"
									children =
									[
										{
											type = "action_equip_weapon"
											weapon = "BEST"
										},
										{
											type = "decorator_random_int"
											min = 0
											max = 1
											output = "BombSiteIndex"
											child =
											{
												type = "action_choose_bomb_site_area"
												input = "BombSiteIndex"
												output = "HuntAreas"
											}
										},
										{
											type = "action_choose_team_spawn_area"
											output = "HuntAreas"
										},
										{
											type = "action_choose_random_waypoint"
											input = "HuntAreas"
											output = "TargetHuntArea"
										},
										{
											type = "action_move_to"
											destination = "TargetHuntArea"
											movement_type = "BT_ACTION_MOVETO_RUN"
											route_type = "BT_ACTION_MOVETO_FASTEST_ROUTE"
										}
									]
								}
							]
						}
					}
				]
			}
		}
	}
}