Repository navigation
Bots re-check a skipped-to goal when pushed off their path - #2200
Draft
sunzenshen wants to merge 4 commits into
Draft
sunzenshen wants to merge 4 commits into
sunzenshen wants to merge 4 commits into
Conversation
The path follower skips ahead to a goal that is clear from where the bot is. A bot pushed off its path keeps steering at that goal from wherever it ends up, and when the straight line from there runs into a wall or a prop it wedges until the stuck monitor fires. On Avoid()'s 0.5 s cadence, when the bot stands on neither the goal's area nor the one before it, run the stock IsPotentiallyTraversable check to the goal. If it is blocked, back the goal up to the nearest earlier ground waypoint that is walkable from the feet; when that waypoint is within the goal tolerance, or none is walkable, invalidate the path so the bot re-paths. A re-path can lead back into the same prop, so after an action a goal near the one acted on, or feet near where the bot stood, is held for 3 s, and after two actions it is left to the stuck monitor.
This was referenced Oct 5, 2026
sunzenshen
force-pushed
the
bot-path-goal-recheck-pr
branch
from
October 12, 2026 04:09
388098f to
1c8bf05
Compare
…embers) Both this branch and NeotokyoRebuild#2176 add constants, constructor lines and header members next to the same places in NextBotPathFollow; keep both.
NeotokyoRebuild#2197's prop detour sets the path goal to the waypoint past the props and steers around them to reach it, so the straight line from the bot to that goal runs through the prop on purpose. The re-check would see it as blocked and back the goal up or re-path, undoing the detour.
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
Background
PathFollowerskips ahead to a later waypoint whenever the straight line to it is clear from where the bot stands. That choice is right when it is made, but the bot keeps steering at that goal from wherever it ends up. When a bot is shoved by a teammate, carried off by a fight, or slides off a step, the straight line from its new position can run into a wall corner, a door leaf or a prop. The bot then presses into it, often for 5 s or more until the stuck monitor fires, and sometimes for 30 s or more. Onntre_rise_ctgbots pressed into an open door leaf at a stair-top landing for 5-7 s; onntre_ghost_ctga chasing bot stayed pinned against a wall-mounted pipe meter for 35 s. A navmesh edit does not help, because the waypoint was reachable when the path was planned.What this PR changes
Avoid()'s existing 0.5 s cadence, a bot on the ground whose goal is an ordinary ground waypoint, and which stands on neither the goal's area nor the area before it, runs the stockIsPotentiallyTraversablecheck from its feet to the goal. A bot on those two areas is still on the line the path planned, and is left alone.A bot that stays on its path's areas, or whose goal is still walkable, is unchanged. The change is in
NextBotPathFollow.cpp/.hunder#ifdef NEO, with the guard's values as named constants.How to test
map ntre_rise_ctg,neo_bot_quota 30, join spectator.Risk
Invalidate()the follower already uses after a fall or a failed climb; the behavior computes a new path on its next update.Avoid()'s timer, whichAvoid()restarts only while avoiding is on (nb_allow_avoiding, default 1); with avoiding off the re-check runs every tick for an off-path bot.Merging with #2201
#2201 adds code at the same four places in these two files (the constants block, the constructor, the helpers after
IsNearNavMesh, the header'sNEOmembers). Whichever of the two merges second resolves those conflicts by keeping both sides; nothing else changes. A trial merge of both branches builds clean. The logic does not overlap: #2201 acts inside the "goal is high above us" check on aDROP_DOWNgoal, and this re-check leaves any goal that is not an ordinary ground waypoint alone.Results
All on this branch alone against master
f426c222b(both with the harness's logging and match-end support only), Release builds, neoAssets master navmeshes, 30 bots, default weapon damage (1.485), 1 round, 15 s freeze, every player at one XP tier rotated over the spawns, 8 wide. Every match reached match end with 0 asserts; one Debug match onntre_rise_ctghad 0 asserts.Spawn sweep of the four maps with the spots the re-check was built on (
ntre_rise_ctg,ntre_ghost_ctg,ntre_saitama_ctg,ntre_threadplate_ctg) and the two with the movable props #2197 detours around (ntre_dusk_ctgoffice chairs,ntre_redlight_ctgscooter): every ghost spawn once, 51 matches an arm, paired by spawn. A third arm ran this PR without the second commit, to see what the detour condition changes.OnStuck,FAIL_STUCK)FAIL_FELL_OFFBy map, stuck a match, master -> this PR: saitama 7.4 -> 1.2, dusk 7.6 -> 2.6, threadplate 5.1 -> 2.1, redlight 4.8 -> 2.0, ghost 6.9 -> 5.9, rise 7.2 -> 6.8. By XP tier the episodes ratio is x0.26-x0.94, lower in every tier.
At the spots (events within 128 u, all arms' matches): the rise stair-top landing 4 -> 0, the ghost pipe meter 4 -> 2. Two did not improve on master's meshes. At the
ntre_saitama_ctgelevator hatch one ghost carrier in a fight logged 6 events in 4 s (2 on master). At thentre_threadplate_ctgramp corner one bot on the low floor beside the ramp, with its goal on the ramp 54 u up, re-pathed and backed up once each, then waited for the stuck monitor (8 events; 3 on master): the loop guard stopped the re-check after two actions, as designed, and that spot is left to the navmesh.FAIL_FELL_OFFrose onntre_dusk_ctg(0.4 -> 2.0 a match, 1.6 on a second pass of the same spawns) andntre_saitama_ctg(0.6 -> 1.2, 0.4 on the second pass), and was flat or lower on the other four maps. Within dusk, apart from a drop near (2160, 4250) just after the round start that every arm has (master included), the falls are at different places, with no repeated spot, and across all six maps 10 of this arm's 77 came within 3 s of the same bot's re-check action. The two re-check arms swapped order on the second pass (1.5 and 0.8 a match on the first pass, 0.9 and 1.1 on the second), so the pooled rise reads as match-to-match spread; dusk is the one to watch.The detour condition. In this PR's arm the re-check would have acted on 1328 of the 2839 half-second ticks bots spent detouring; the condition held it. In the arm without it, the re-check acted 479 times in the middle of a detour. Over that pass and a second pass of the same 51 spawns with only the two re-check arms (102 pairs), stuck events read 3.9 a match without the condition and 2.9 with it (x0.75 [0.45, 1.22]), stuck episodes x0.91 [0.67, 1.25],
FAIL_FELL_OFFx1.24 [0.98, 1.61], kills +0.1 [-0.5, +0.7]. Neither direction is clear in play, so the condition rests on the mechanism: it keeps the re-check from undoing the detour's goal.Earlier evidence, on the harness research build
Measured on our research build (master plus other open bot PRs) with the change behind a test-only switch, on the research navmeshes of the time, a survey of 29
ntre_maps, every ghost and juggernaut spawn once (212 matches an arm): at the rise landing 18 stuck events (4 bots) went to 1, at the ghost pipe meter 37 + 1 fall to 3 falls, at the saitama hatch slot 62 + 2 to 8 + 1, at the threadplate ramp corner 26 to 1 fall. A same-build check before the loop guard existed: rise stuck 7.1 -> 2.2 a match, ghost pipe meter spawn 26 -> 0,ntre_bullet_tdm27 -> 12. Without the loop guard the re-check made new repeated spots at solid props (ntre_threadplate_ctglarge crate 21 events,ntre_engage_ctgwrecked hachikoma 13); with it no spot in that survey had more than 2 re-check actions a bot.Approaches tried and dropped
ntre_bullet_tdm. The goal itself goes stale, so this PR re-checks it.Known gaps
ntre_tarmac_ctgspot is this case (area 3040, a path line that runs through a door frame). Widening the test to cover it would make the bot back up to a waypoint it stands at and loop. That spot is a navmesh problem.ntre_threadplate_ctgramp corner above: a bot off the path below its goal is re-checked twice and then left to the stuck monitor.IsPotentiallyTraversablesees, the same quarter-width probe the skip-ahead uses, so a goal blocked for the bot's full hull but clear for the probe is not re-checked.Toolchain
Linked Issues