Counter-Strike: Global Offensive/Bot Behavior Trees: Difference between revisions
mNo edit summary |
(Added back button. Section 'Assigning BTs to Bots'. Section 'Related ConCommands'. ExpandBoxed long code.) |
||
Line 2: | Line 2: | ||
{{stub}} | {{stub}} | ||
{{update}} | {{update}} | ||
In {{game name|csgo|name=Counter-Strike: Global Offensive}}, [[bot | {{back|Counter-Strike: Global Offensive Level Creation}} | ||
In {{game name|csgo|name=Counter-Strike: Global Offensive}}, [[bot]]s 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 use [[Valve|Valve's]] proprietary [[Dota 2 Workshop Tools/KeyValues3|KeyValues3]] format (<code>.kv3</code>), which is a text-based format with somewhat strict syntax. They typically use the <code>bt_</code> prefix, to signify that file is a ''Behavior Tree''. They are stored in <code>csgo/scripts/ai</code>. One can create and use his own behavior trees, see below. | |||
Officially, behavior trees are used for the game modes [[File:Csgo icon coopstrike.png|16px|link=]] [[Creating a Co-op Strike Map|Co-op Strike]], [[File:Csgo icon guardian.png|16px|link=]] [[Creating a Guardian Scenario Map|Guardian]] and [[File:Csgo icon deathmatch.png|16px|link=]] [[CS:GO Gamemodes: Deathmatch|Deathmatch]]. | |||
= Format = | 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]. | ||
== Using a Behavior Tree == | |||
The [[ConVar]] <code>'''mp_bot_ai_bt'''</code> can assign a behavior tree to all bots on the server. Its value is a string representing the path to a .kv3 file, starting from <code>csgo/</code>. For example, the following line is used for official Deathmatch and can be found in <code>csgo/cfg/gamemode_deathmatch.cfg</code>: | |||
<pre>mp_bot_ai_bt "scripts/ai/deathmatch/bt_default.kv3"</pre> | |||
For the Co-op game mode, {{ent|info_enemy_terrorist_spawn}} entities have the KeyValue <code>behavior_tree_file</code> that can be used to specify a behavior tree only for bots spawning at this entity. | |||
== Related Console Commands == | |||
{| class=standard-table | |||
! ConVar !! Default Value !! Description | |||
|- | |||
| <code>cv_bot_ai_bt_debug_target</code> | |||
| -1 | |||
| Draw the behavior tree of the given bot. | |||
|- | |||
| <code>cv_bot_ai_bt_hiding_spot_show</code> | |||
| 0 | |||
| Draw hiding spots. | |||
|- | |||
| <code>cv_bot_ai_bt_moveto_show_next_hiding_spot</code> | |||
| 0 | |||
| Draw the hiding spot the bot will check next. | |||
|- | |||
| <code>mp_bot_ai_bt</code> | |||
| "" | |||
| Use the specified behavior tree file to drive the bot behavior. | |||
|- | |||
| <code>mp_bot_ai_bt_clear_cache</code> | |||
| ''ConCommand'' | |||
| Clears the cache for behavior tree files. | |||
|} | |||
== Format == | |||
The first line of a <code>.kv3</code> file is always a header specifying the KV3 version. For CS:GO, use this header: | The first line of a <code>.kv3</code> file is always a header specifying the KV3 version. For CS:GO, use this header: | ||
<source lang="javascript"> | <source lang="javascript"> | ||
Line 15: | Line 49: | ||
== Subtrees == | === Subtrees === | ||
= Commands = | == Commands == | ||
== Control Flow == | === Control Flow === | ||
== Movement == | === Movement === | ||
== Items == | === Items === | ||
== Sensing == | === Sensing === | ||
== Other == | === Other === | ||
= Examples = | == Examples == | ||
== Default Deathmatch Behavior Tree == | === Default Deathmatch Behavior Tree === | ||
Found in <code>csgo/scripts/ai/bt_default.kv3</code> | Found in <code>csgo/scripts/ai/bt_default.kv3</code>. | ||
{{ExpandBox| | |||
<source lang="javascript"><!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d} format:generic:version{7412167c-06e9-4698-aff2-e63eb59037e7} --> | <source lang="javascript"><!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d} format:generic:version{7412167c-06e9-4698-aff2-e63eb59037e7} --> | ||
{ | { | ||
Line 204: | Line 239: | ||
} | } | ||
</source> | </source> | ||
}} |
Revision as of 15:05, 29 September 2021

Remember to check for any notes left by the tagger at this article's talk page.
In Template:Game name, 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 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
. One can create and use his own behavior trees, see below.
Officially, behavior trees are used for the game modes Co-op Strike,
Guardian and
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.
Using a Behavior Tree
The ConVar mp_bot_ai_bt
can assign a behavior tree to all bots on the server. Its value is a string representing the path to a .kv3 file, starting from csgo/
. For example, the following line is used for official Deathmatch and can be found in csgo/cfg/gamemode_deathmatch.cfg
:
mp_bot_ai_bt "scripts/ai/deathmatch/bt_default.kv3"
For the Co-op game mode, info_enemy_terrorist_spawn entities have the KeyValue behavior_tree_file
that can be used to specify a behavior tree only for bots spawning at this entity.
Related Console Commands
ConVar | Default Value | Description |
---|---|---|
cv_bot_ai_bt_debug_target
|
-1 | Draw the behavior tree of the given bot. |
cv_bot_ai_bt_hiding_spot_show
|
0 | Draw hiding spots. |
cv_bot_ai_bt_moveto_show_next_hiding_spot
|
0 | Draw the hiding spot the bot will check next. |
mp_bot_ai_bt
|
"" | Use the specified behavior tree file to drive the bot behavior. |
mp_bot_ai_bt_clear_cache
|
ConCommand | Clears the cache for behavior tree files. |
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"
}
]
}
]
}
}
]
}
}
}
}