Skip to content

Conversation

@sunzenshen
Copy link
Contributor

Description

Bot behaviors for playing CTG mode.

Toolchain

  • Windows MSVC VS2022

// Intended for use by ghost carrier team, to emulate a team that knows where enemies are likely to ambush
// Compensates for bots' lack of meta knowledge by making them prefer routes not reserved by enemies
// Adheres to cheat against bots but not against humans philosophy by not considering human players' positions
cost += CNEOBotPathReservations()->GetPredictedFriendlyPathCount(area->GetID(), GetEnemyTeam(m_me->GetTeamNumber())) * neo_bot_path_reservation_penalty.GetFloat() * 2;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is why I changed the SAFEST_ROUTE parameters for other path calculations not related to the ghost. There wasn't any existing handling with this case beyond some stubs related to combat areas, so this was the cleanest way I could think of for choosing paths as a ghoster team.

m_isGoalCharger = m_healthKit->ClassMatches( "*charger*" );

if (!CNEOBotPathCompute(me, m_path, m_healthKit->WorldSpaceCenter(), SAFEST_ROUTE))
if (!CNEOBotPathCompute(me, m_path, m_healthKit->WorldSpaceCenter(), DEFAULT_ROUTE))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See neo_bot_path_cost.cpp for why these route type changes.

@sunzenshen sunzenshen added the Bots Related to bot players label Jan 12, 2026
@sunzenshen sunzenshen marked this pull request as ready for review January 13, 2026 01:38
@sunzenshen sunzenshen requested a review from a team January 13, 2026 01:38
@sunzenshen
Copy link
Contributor Author

sunzenshen commented Jan 20, 2026

Rebased on top of the bot command branch, so now the following debug commands are available:

sv_neo_bot_cmdr_enable 1;
sv_neo_bot_cmdr_debug_pause_uncommanded 1;
neo_ctg_round_timelimit 99;

This PR doesn't really need bot commands for testing, but might be worth thinking of test scenarios where the CTG behaviors and bot commands may interact.

I guess one possible interaction to look into after a first pass of feedback is that a bot holding the ghost will not report enemy positions to teammates, as they will be in the follow behavior. Maybe I should move the enemy reporting code into neo_bot_tactical_monitor and make it a general behavior to report ghoster targets (if the bot has the ghost equipped), instead of making it limited to the ghost carrier behavior.

@sunzenshen
Copy link
Contributor Author

I guess one possible interaction to look into after a first pass of feedback is that a bot holding the ghost will not report enemy positions to teammates, as they will be in the follow behavior. Maybe I should move the enemy reporting code into neo_bot_tactical_monitor and make it a general behavior to report ghoster targets (if the bot has the ghost equipped), instead of making it limited to the ghost carrier behavior.

I ended up refactoring the ghost callout logic into a publicly accessible helper function so that the bot commands follower behavior can reuse the same routines.

@AdamTadeusz
Copy link
Contributor

One problem I've noticed with the bots "seeing" the ghoster is that they will immediately lock onto them and pop their cloak as if they are about to engage in combat, even if the ghoster is on the other side of the map, which causes the non ghoster team to not really check their angles at all. I realise that a more sophisticated solution will require a lot more work so this isnt a deal breaker for me, but I think its something we should consider in the future.

One way to cheaply check whether the ghoster is "around the corner" and worth pursuing with the kind of determination bots show at the moment from across the map could be to check whether the ghoster is in the bot's PVS given how the potentially visible set tends to extend past corners for some distance, though I don't know how this check works with the ghoster always being networked. And again I don't think this is something that has to be fixed in this PR necessarily

}
}

void CNEOBotGhostEquipmentHandler::EquipBestWeaponForGhoster( CNEOBot *me )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if we will keep this feature, but perhaps the bots can consider the value of sv_neo_ctg_ghost_beacons_when_inactive when deciding what weapon to equip

Copy link
Contributor Author

@sunzenshen sunzenshen Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I considered this idea and even started implementing it, but then I started thinking that honestly the bot callouts for their bot teammates are accurate enough that I'd rather not give bots another unfair advantage over human players. I think it's fine to keep the bots following the base rules for CTG even when sv_neo_ctg_ghost_beacons_when_inactive is true, as I think it's more fun when you can disrupt a bot's callouts by aggro'ing them, etc.

sv_neo_ctg_ghost_beacons_when_inactive is pretty much a cheat for human players who are too shy to pick up the ghost, and bots may not need that extra incentive for now. Bots are also much more fluent than humans at swapping to their sidearm and engaging targets. I think it's fine if the bots have a consistent time penalty of having to switch to their sidearm from the ghost.

(We can reconsider this in a new PR, but I'd like to keep this discussion out of scope for this PR.)

AdamTadeusz
AdamTadeusz previously approved these changes Jan 22, 2026
@sunzenshen sunzenshen requested a review from a team January 23, 2026 04:51
Instead, rely on neo_bot_ctg_enemy behavior to guide enemies to ghost carrier by pathing using the ghoster's position.
Also rename ConVar enabling the path reservation system to be more generic
@sunzenshen
Copy link
Contributor Author

sunzenshen commented Jan 23, 2026

One problem I've noticed with the bots "seeing" the ghoster is that they will immediately lock onto them and pop their cloak as if they are about to engage in combat, even if the ghoster is on the other side of the map, which causes the non ghoster team to not really check their angles at all. I realise that a more sophisticated solution will require a lot more work so this isnt a deal breaker for me, but I think its something we should consider in the future.

One way to cheaply check whether the ghoster is "around the corner" and worth pursuing with the kind of determination bots show at the moment from across the map could be to check whether the ghoster is in the bot's PVS given how the potentially visible set tends to extend past corners for some distance, though I don't know how this check works with the ghoster always being networked. And again I don't think this is something that has to be fixed in this PR necessarily

I noticed this behavior too and it has been bugging me, so now that you mention it, I think the simpler workaround that will really help the opposing the ghoster team is to actually remove the exceptions that allow them to see the ghoster all the time. While technically this is not in line with how humans can see the ghost carrier, I feel that not letting the bots see the ghost carrier actually improves their threat handling behavior. Previous PRs like #1572 already make the bots more aggressive when attacking the ghost carrier, and as you mentioned, having the bots not over-focus on the ghost carrier actually helps them pay more attention to more dangerous and unknown threats. (Plus as noticed by some testers, this will help alleviate the weird looking wall penetration attempts when the ghost carrier is behind thin voids of the maps that would not be intuitive for humans but that bots traceline to determine penetration.)

I also kind of felt that the combined FOV and Visibility exceptions were also a cheap workaround to having the bots attack the ghost carrier in the old seek and destroy behavior, and now that we have a separate behavior for enemies of the ghost carrier, we can consider more sophisticated tracking in that class. For now I just have the enemies move towards the coordinates of the ghost carrier on throttled timings between 0.2-1 second intervals, and that seems to be good enough for now for having the enemies intercept the ghost carrier.

@DESTROYGIRL DESTROYGIRL added the CTG Related to the Capture The Ghost gamemode. label Jan 23, 2026
@sunzenshen sunzenshen requested a review from a team January 24, 2026 04:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bots Related to bot players CTG Related to the Capture The Ghost gamemode.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants