Repository navigation
Bots follow their path on NAV_MESH_PRECISE areas - #2168
Merged
sunzenshen merged 2 commits intoSep 28, 2026
Merged
Conversation
sunzenshen
force-pushed
the
bot-nav-precise-careful
branch
from
September 27, 2026 05:20
2977330 to
4d619ac
Compare
sunzenshen
marked this pull request as ready for review
September 27, 2026 05:21
On an area marked NAV_MESH_PRECISE or NAV_MESH_CLIFF: - the path follower does not skip past a point that enters a PRECISE area, as the path builder already does not - move input follows the exact direction to the goal instead of the nearest of eight key combinations - no combat dodge, no close-range circle-strafe and no stepping away from teammates, any of which can carry a bot off a ledge No mesh on master marks PRECISE or CLIFF today.
sunzenshen
force-pushed
the
bot-nav-precise-careful
branch
from
September 27, 2026 05:21
4d619ac to
086ffc1
Compare
Review (sunmachine) showed the button scale it relied on lapses within a tick, and bot updates run every 6-13 ticks, so on most ticks the bot still moved on the eight-direction keys. Their design - hold the world direction until the next bot update and convert it against the view every tick - was measured against this branch without any move-input change: fall deaths x0.79 and x0.69 in two batches, but stuck events on PRECISE / CLIFF areas x1.84 and x1.42, with bots on a ledge now pushing into each other instead of sliding past. That trade needs more work, so it moves to its own draft PR and this one keeps the waypoint and the no-sidestep rules.
sunmachine
reviewed
Sep 27, 2026
sunmachine
left a comment
Contributor
There was a problem hiding this comment.
Holding approval until we figure this part out.
sunmachine
approved these changes
Sep 28, 2026
This was referenced Oct 1, 2026
sunzenshen
added a commit
to sunzenshen/neo
that referenced
this pull request
Oct 3, 2026
Bot movement presses the nearest of eight key combinations, up to 22.5 degrees off the goal, so a bot looking elsewhere drifts sideways - on a ledge marked NAV_MESH_PRECISE or NAV_MESH_CLIFF, off the edge. On those areas Approach() now hands the player the world direction to the goal. PhysicsSimulate() applies it on every tick until the next bot update, converted against that tick's view, so a bot turning to aim keeps its line. The stock SetButtonScale() does not do this: its 0.01 s timer lapses within a tick and it is relative to the view at update time. Design by sunmachine (review of NeotokyoRebuild#2168). Draft: measured falls down (x0.79, x0.69), but stuck events on these areas up (x1.84, x1.42) as bots on a ledge push into each other.
This was referenced Oct 4, 2026
sunzenshen
added a commit
to sunzenshen/neo
that referenced
this pull request
Oct 5, 2026
Bot movement presses the nearest of eight key combinations, up to 22.5 degrees off the goal, so a bot looking elsewhere drifts sideways - on a ledge marked NAV_MESH_PRECISE or NAV_MESH_CLIFF, off the edge. On those areas Approach() now hands the player the world direction to the goal. PhysicsSimulate() applies it on every tick until the next bot update, converted against that tick's view, so a bot turning to aim keeps its line. The stock SetButtonScale() does not do this: its 0.01 s timer lapses within a tick and it is relative to the view at update time. Design by sunmachine (review of NeotokyoRebuild#2168). Draft: measured falls down (x0.79, x0.69), but stuck events on these areas up (x1.84, x1.42) as bots on a ledge push into each other.
This was referenced Oct 5, 2026
sunzenshen
added a commit
to sunzenshen/neo
that referenced
this pull request
Oct 7, 2026
Bot movement presses the nearest of eight key combinations, up to 22.5 degrees off the goal, so a bot looking elsewhere drifts sideways - on a ledge marked NAV_MESH_PRECISE or NAV_MESH_CLIFF, off the edge. On those areas Approach() now hands the player the world direction to the goal. PhysicsSimulate() applies it on every tick until the next bot update, converted against that tick's view, so a bot turning to aim keeps its line. The stock SetButtonScale() does not do this: its 0.01 s timer lapses within a tick and it is relative to the view at update time. Design by sunmachine (review of NeotokyoRebuild#2168). Draft: measured falls down (x0.79, x0.69), but stuck events on these areas up (x1.84, x1.42) as bots on a ledge push into each other.
sunzenshen
added a commit
to sunzenshen/neo
that referenced
this pull request
Oct 8, 2026
Bot movement presses the nearest of eight key combinations, up to 22.5 degrees off the goal, so a bot looking elsewhere drifts sideways - on a ledge marked NAV_MESH_PRECISE or NAV_MESH_CLIFF, off the edge. On those areas Approach() now hands the player the world direction to the goal. PhysicsSimulate() applies it on every tick until the next bot update, converted against that tick's view, so a bot turning to aim keeps its line. The stock SetButtonScale() does not do this: its 0.01 s timer lapses within a tick and it is relative to the view at update time. Design by sunmachine (review of NeotokyoRebuild#2168). Draft: measured falls down (x0.79, x0.69), but stuck events on these areas up (x1.84, x1.42) as bots on a ledge push into each other.
This was referenced Oct 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Bots strictly follow their path on NAV_MESH_PRECISE/CLIFF areas
NAV_MESH_PRECISEis the stock nav attribute for "do not adjust for obstacles, just move along area" (nav.h), set withnav_precisein the nav editor. Stock NextBot code honors it in two places: when a path is built,Path::FindNextOccludedNodedoes not optimize past a point in a PRECISE area, andPathFollower::Avoiddoes not steer around obstacles there. But the path follower's own skip-ahead still heads past that point once it is close, and the rest of a bot's movement ignores the attribute, so it can still carry the bot off the line the mesh author marked. That matters most on a ledge beside a fatal drop, which the per-map navmesh PRs markNAV_MESH_PRECISE+NAV_MESH_CLIFF, and on a narrow crossing such as a doorway or the gap past a handrail's end.On an area marked
NAV_MESH_PRECISEorNAV_MESH_CLIFF, this PR keeps a bot on its path:NextBotPathFollow.cpp,#ifdef NEO). Skip-ahead normally heads for a later path point once the next one is close. This is the same rule the path builder already follows, applied to the follower. Without it the bot cuts the corner the author marked, then presses into the handrail or door frame it was meant to walk around.Dodge), no close-range circle-strafe (Attack), and no stepping straight away from a teammate within 32 u (AvoidBumpingFriends). Each of these moves the bot sideways without regard to what is beside it. A newCNEOBot::IsOnPreciseArea()gives them one check.Where it applies
No mesh on master marks PRECISE or CLIFF today, so on its own this changes nothing on the current maps. Where the marks go is decided per map in each navmesh PR. Two open ones already carry them:
Testing this build with either PR's
.navshows the change. On redlight, stuck events on its PRECISE areas go from 1.9 to 0.3 a match.Evidence
Bot matches with the research meshes, 30 bots, default weapon damage, CTG with the ghost pinned at 3 spawns (DM: unpinned), all arms interleaved in one batch. Temporary cvars switched each part in the test build only; this PR has no switches.
Each part against the whole PR (280 matches: skyline, apparatus, redlight, ballistrade, subsurface; this batch also had the exact move direction described below):
A second batch compared the parts (with the exact move direction) against none on 10 maps (160 matches): stuck events on PRECISE areas 2.45 -> 1.24 a match (skyline 15.3 -> 7.0, redlight 1.9 -> 0.3), overall stuck and kills unchanged.
The PR alone on master's code (120 matches: upstream plus this PR, with logging added and a test-only switch; same maps plus bullet; the other bot research is absent, so stuck counts are much higher on these maps):
That batch included the timer version of the exact move direction. On master's code the effect is mildly positive and within noise. Most stuck events there come from spots this PR does not touch, such as ladders.
The exact move direction, taken out
The first version of this PR also set the move input to the exact direction to the goal on these areas, using the stock
SetButtonScale. In review, sunmachine pointed out that the scale lapses within a tick and that bot updates run every 6-13 ticks, so on most ticks the bot still moved on the eight-direction keys. They suggested holding the world direction until the next bot update and converting it againstEyeAngles()every tick.That design was built and measured against this branch without any move-input change (the timer version as context), on skyline, tarmac, redlight, ballistrade, bullet and apparatus, 30 bots, harness logging added:
The direction held between updates cuts falls clearly, but bots on a ledge then push into each other instead of sliding past (teammate-blocked stuck events on those areas went 38 -> 135). Falling back to the keys behind another player, or while stuck, did not lower that. So the move-input change is out of this PR. sunmachine's design is in its own draft PR, #2175, where the ledge crowding can be worked on without holding this one up.
Cost
One attribute test on the bot's last known area in each place, which is already cached; nothing is traced.
Smoke
The current head with harness logging added: 12 matches on redlight, ballistrade, skyline, tarmac, bullet and apparatus, all ended cleanly, 0 asserts, no crash dumps.
Risk
Low. Only meshes that mark PRECISE or CLIFF are affected. The strongest effect, the waypoint, only changes which path point a bot heads for, never the path itself.
Toolchain
Linked Issues