Stop navgen seating waypoints past a ledge lip - #250
Merged
Conversation
navgen samples hull 1, the player clip hull. That is the world expanded by the player box, so its floor reaches half a player width past every real ledge edge, and the sampler read that as standable ground. On e1m6 it seated n93 at '-207 305 24'. The true lip at that y is x -193, so the seat sat 14 units out over a 304 unit drop with lava at -128. Measured along y 305, hull 1 reports floor at z 24 from x -207 eastward while the world floor is -306 until x -191. The engine never agreed. SV_movestep calls SV_CheckBottom, which point traces the box corners against the world, so walkmove refuses the step, and Argus_MoveHazard refuses it too. A bot routed onto such a seat can neither arrive nor give up. A co-op companion on e1m6 spent its whole session at that lip: 213 stalls and 215 jumps in 175 s, mode 0 on 310 of 327 samples, three goals, never a death. So run the engine's own test rather than a guess at one. Section 4c applies SV_CheckBottom against the world with the same constants and the same order. Corners solid just under the feet is the fast accept. Otherwise the midpoint must find floor within 2 * STEP, and every corner must sit within STEP of it. e1m6 regenerated. 536 lip overhang samples dropped, 198 nodes to 188, the lip seat relocated from '-207 305 24' to '-175 305 24' on real ledge, seats over a 96 unit void 32 to 0, worst spawn reach 85 to 95 per cent. Stalls ran 220, 213 and 200 across three tapes on the old graph, and 6, 2 and 5 on the new one. Other maps are NOT regenerated. Those graphs are accumulated and tuned and each wants its own ladder. Dry runs confirm the rule does not fragment them: dm4 98 per cent worst spawn reach with 212 seats dropped, dm6 95 per cent with 209, e1m1 99 per cent with 501. HONEST RESIDUAL, and the reason e1m6 is still not co-op ready. The old graph's only route to the gold key crossed the lava pit THROUGH n93. Removing the fake seat removes the fake route, so routefails run 400 per tape where they ran 9. That crossing is a func_door which rises on a trigger_once chain and stays up, and in a botmatch nothing fires it, so the route genuinely does not exist at runtime. Modelling the mover in navgen would only move the lie to a different height. Three things tried and reverted on their own ladders, each with its post mortem on the issue. A swimmer reach ceiling measured from the water surface, which readmitted the exact seat the graveyard names. A reach test on the Argus_NearestNode fast path, which is a real hole but cost e1m2 co-op half its coverage, 55 cells to 24 on two tapes. A routefail shelf on the co-op key commitment, which did not touch the storm because the retries come from the goal already on the stack, and cost e1m2 routefails 0 to 77 and stalls 40 to 73. Refs #249 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
This was referenced Sep 5, 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.
navgen samples hull 1, the player clip hull. That is the world expanded by the player box, so its floor reaches half a player width past every real ledge edge. The sampler read that as standable ground.
On e1m6 it seated n93 at
-207 305 24. The true lip at that y is x -193, so the seat sat 14 units out over a 304 unit drop with lava at -128.The engine never agreed.
SV_movestepcallsSV_CheckBottom, which point traces the box corners against the world, sowalkmoverefuses the step andArgus_MoveHazardrefuses it too. A bot routed onto such a seat can neither arrive nor give up. A co-op companion on e1m6 spent its whole session at that lip: 213 stalls and 215 jumps in 175 s, mode 0 on 310 of 327 samples, three goals, never a death.The fix
Section 4c runs the engine's own test instead of a guess at one, with the same constants and the same order. Corners solid just under the feet is the fast accept. Otherwise the midpoint must find floor within
2 * STEP, and every corner must sit withinSTEPof it.e1m6, regenerated
-207 305 24-175 305 24536 lip overhang samples dropped. The seat moved onto real ledge rather than disappearing. Stalls ran 220, 213 and 200 across three tapes on the old graph, and 6, 2 and 5 on the new one.
Other maps are not regenerated
Those graphs are accumulated and tuned, so each wants its own ladder. Dry runs confirm the rule does not fragment them.
dm4 in engine, 180 s: cells 75, stalls 18, routefails 9, no freezes, against 72 / 51 / 17 on the pre-change binary.
Honest residual
e1m6 is still not co-op ready, and this change does not make it so. The old graph's only route to the gold key crossed the lava pit through n93. Removing the fake seat removes the fake route, so routefails run 400 per tape where they ran 9. That crossing is a func_door which rises on a
trigger_oncechain and stays up, and in a botmatch nothing fires it, so the route genuinely does not exist at runtime. Modelling the mover in navgen would only move the lie to a different height. What e1m6 needs is level progression handling, which is much larger work. Tracked on #249.The trade this PR takes is a wedged bot for an honest graph. Stalls fall from about 210 to about 5, coverage moves 13 cells to 9, and routefails rise. By the project's own gate order that is the right way round, but the routefail rate is worth watching on a multi bot server, since
an_busyserialises the router.Tried and reverted, each on its own ladder
1585 1185 208, the exact seat the graveyard entry names. Both that seat and dm3's lip sit 36 above their surface, so no height rule separates them.Argus_NearestNodefast path. It is a real hole, the neighbour loop applies no reach test and returns early at 120 units. It improved dm3 but cost e1m2 co-op half its coverage, 55 cells to 24 on two tapes.Refs #249
🤖 Generated with Claude Code