Repository navigation
ntre_yard_jgr: navmesh rework - #154
Open
sunzenshen wants to merge 8 commits into
Open
sunzenshen wants to merge 8 commits into
sunzenshen wants to merge 8 commits into
Conversation
One file. Against master: 1931 -> 1555 areas, 3,154,593 -> 2,279,973 bytes; 0 -> 9 nav ladders; areas the engine blocks at every round start 6 -> 0; areas no spawn or objective can reach 231 -> 66. - Sliver areas merged into their neighbors on the same floor. - Areas the engine blocks at round start (a prop or a displacement over the area's center) are cut away. - The west building's roof (juggernaut spawn 1) is meshed: master has no area within 370 u of that spawn. Its two ladders (west face, ladder 10; north face, ladder 13) are climb only: their tops stand on the 38 u parapet round the roof, and a bot on the walkway inside cannot get onto them going down. Three strips on the parapet top, each a 37 u climb from the walkway, drop to open ground. - The east building's catwalk (z 72) is meshed, and six nav ladders join the building's levels: 3 and 8 from the ground to the catwalk, 4 and 9 from the catwalk to the roof at z 200, 5 and 11 from that roof to the top tier at z 345. Ladders 3 and 8 are climb only: their tops stand behind the catwalk's continuous handrail. - Ladder 12, the leaning ladder at (-276, -2904), follows its brush: 20 u wide, climbed from the south. - Hand edits where test bots got stuck: crouch areas under two stair landings and a crouch doorway, an L of barrier rails at (-1400, 700). - No-return pockets closed: ten 10 x 10 areas in the corners of barrier pairs link back to the area beside them; four step surfaces on the truck at (-795, -987) drop to the ground; the walled lot in the south-west corner (22 areas), which nothing reaches and nothing in it can leave, is removed. - Re-analyzed in game after the edits.
Renumbers area ids only, so an id-keyed diff against master reads sensibly: 1438 of the 1555 areas carry the id of the master area they match, and kept ids more than 64 u from their master location drop from 57 to 14. Master has no nav ladders; the nine ladders keep their ids (3, 4, 5, 8, 9, 10, 11, 12, 13). Geometry, connections, attributes and the analysis data are unchanged (verified topology-identical).
The north and south buildings have the same 389 u ladders as the west building, at (311, 1396) and (310, -1884), up to roofs about 720 x 435 u that no area covered. Both roofs are now meshed by hand: the walkway inside the parapet, the roof round its solid housing, and the raised platform round its two AC units, 4 u off walls and props, with corner heights from the measured floor. Ladders 14 and 15 connect them, climb only like ladders 10 and 13: their tops stand on the 38 u parapet above the walkway. Each roof has two ways down like the west roof's: 8 u strips on the parapet top, a 37 u climb from the walkway, that drop to open ground (about 13 damage). Every existing area keeps its id; the 36 new areas take ids above the previous highest. The fifth such ladder, at (2000, 1100), stands behind a playerclip wall and is left out. Re-analyzed in game.
An outside review of this mesh found the landing at (-170, 130, -60) (674 / 3904) to be a dead end: its only way out was a 173 u climb no class makes. The landing is the top of a stairs_top prop whose flight down its south side was never meshed, on master either. The review also found climbs kept after their drop back was cut, and walk links that run one way only. - Mesh the flight: one sloped area (6822) from the landing's edge (3904) to the area at its foot (3899), in their column, clear of the east rail. The engine marks it STAIRS. - Delete 4414 beside the foot of the flight: the rail stands on it (no hull fits on any of its sample points, and every link out of it is blocked), and with the flight open bots routed through it onto the rail. - Remove the climbs no class plans: 674 -> 6438 (173 u) and the four kept climbs 63 -> 5661, 301 -> 6433, 871 -> 6443 and 5640 -> 6158 (101-178 u). The areas they led to have other ways in or stay as drop-only pockets. - One-way links, each swept with a player hull in both directions by the engine's hull audit: cut both ways the two pairs blocked both ways (a flatbed trailer, a container); restore the missing direction of the two pairs clear both ways. Every other area keeps its id; the new one is numbered above the highest. Re-analyzed in game (same graph, fresh visibility).
The engine's hull audit (a player hull stood on every area and swept across every link, in the server) of the previous revision, and navconnect's link check against master: - Restore the drop back of three climbs of 34-39 u whose drop had been cut: the climb reads clear on most or all lanes. - Delete 41 areas no player hull stands in (80-100 % of stand samples blocked) or reached only through one: the 20 x 20 and 10 x 10 u squares inside the barrier round-bars, stair props, trailers, the forklift and the powersuit racks, and 2053 at the kitchen shelf near (-740, 2470), where bots that walked in stuck. Several had stuck events from bots heading into them. - Delete four parapet strips of the two new roofs that carry no link anything else needs: 11 u wide against the parapet, no stand sample clear, never visited. Kept: the parapet strips that are ladder 14's and 15's tops, and links the audit reads blocked that bots cross (the metal ladder prop near (-290, -2860), the powersuit rack, the snowrex, displacement slopes and the new stairs). Existing areas keep their ids. Re-analyzed in game (same graph, fresh visibility).
Ladders 3, 8, 10, 13, 14 and 15 were climb only: their tops stand on the roofs' 38 u parapets (10, 13, 14, 15) or behind the catwalk's handrail (3, 8), and bots could not get onto them going down. NeotokyoRebuild/neo#2176 now mounts such descents over the top edge, so each ladder's top area lists it going down again. Ladder 14's and 15's tops move from the 11 u walkway strips against the north and south parapets, where no player hull fits, to the roof floor in front of each ladder. The strips are removed, and the parapet-top exits beside those ladders, reached only from the strips, are linked from the ramp next to them (a 43.5 u climb with a drop back). Re-analyzed in game.
The north and south roofs have a 16 u ledge along the inner face of their parapet. A player within 16 u of the ledge rests on it, but no player can stand on the ledge itself: their box would be inside the parapet. The strips 6788 and 6806, the only way to the vent-top exits on the west parapets, lay on the ledge itself. Bots heading for them pressed the parapet and stuck, and the engine's hull test found no room to stand anywhere on them. They move 16 u inward, onto the band in front of the ledge where a player stands on it, and the walkway beside them gives up that band. Their links are unchanged. The climb from the ramps to the parapet-top exits beside ladders 14 and 15 read 43.5 u, from the height of the gutter in front of the ledge, over the 43 u a Support bot plans. A bot at that edge stands on the ledge, so the ramps' edge now carries the ledge's height and the climb reads 39.5 u. No area added or deleted, ids unchanged. Re-analyzed in game (same graph, fresh visibility).
Six stairs_top prop staircases had their landings meshed but not their flights, so each landing was an island: a bot that walked up the steps, chasing or cutting a corner, found no path off it, and the landing at (730, -1110) had no link out at all. Each flight now gets one sloped area in the middle of its treads, linked both ways to the landing and to the floor at its foot, as the staircase at (-179, 147) got in an earlier commit. Two drops nav_generate recorded across the unmeshed flights (447 -> 302, 693 -> 5625) are replaced by those flights. Bots duck once their center is on a CROUCH area. Under the landings every class but sometimes Recon has to duck, and at most of the mouths the landing's edge lay 1-28 u past the portal, so a standing bot hit it first. A strip of the area in front of 15 mouths is split off and marked CROUCH, so the crouch zone starts 40 u before the edge. Every existing area keeps its id; 26 new areas take ids 6823-6848. Re-analyzed in game (same graph, fresh visibility).
sunzenshen
marked this pull request as ready for review
October 13, 2026 01:17
sunzenshen
marked this pull request as draft
October 13, 2026 01:19
sunzenshen
marked this pull request as ready for review
October 14, 2026 04:19
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.
ntre_yard_jgr: navmesh rework
One file,
neo/maps/nav/ntre_yard_jgr.nav.Dependencies and status
Needs: none. Measured on neo master
092203f36with no open PR (A/B below). The bot change this mesh carries data for is in master now:Helped by (measured better with it; the mesh does not wait on it):
At a glance
What changed
Roofs and ladders
Prop staircases
The yard has ten
stairs_topprop staircases: a landing about 76 u over the ground, on a slab with 55-69 u of headroom under it, and a flight down one side. Two stand on roofs and one is outside the playable area.Id alignment
1396 of the 1570 areas carry the id of the master area they match; 15 of those sit more than 64 u from their master location. The other 174 take ids above master's highest (6470). Master has no nav ladders, so the eleven ladders keep their own ids (3, 4, 5, 8-15).
How it was tested
BLOCKED_LINKS map=ntre_yard_jgr level_pairs=2949 oneway=0 keep=0 cut=2 area=5 check=18 dynamic=0 entity=0)092203f36(Release dedicated server, harness logging only). Byte-identical copies of the map, one carrying each.nav, matches interleaved: JGR with the juggernaut pinned at each of its 3 spawn points in turn (sv_neo_jgr_spawn_force, Allow pinning the juggernaut to a specific spawn point neo#2169, merged), 16 matches each (48 a mesh), 30 bots, default weapon damage (1.485), 1 round, 8 matches at a time, one XP tier a match rotated over the spawns. 96 of 96 matches reached match end with 0 asserts and no crash. The stuck count isOnStuckplusFAIL_STUCKmove failures, excluding the spawn crush at round start and the weapon-scavenging behavior; a stuck episode is one bot's stuck events less than 10 s apart, counted once. Ratios are paired by spawn and match, with 95 % intervals.Both meshes read higher on neo master than on the research build (below): most of the stuck events are at the wall under the attacker deck, 91 % of them on a straight-line fallback on both meshes, and the rise in "fell off the path" is the drop off the attacker deck's west ramp (both under "Known, not changed"). By juggernaut spawn: 0 x0.55 [0.36, 0.82], 1 x0.63 [0.51, 0.77], 2 x0.73 [0.45, 1.16].
How the pinned-ghost probes work
The offline checks show that the mesh links an area to a spawn. They do not show that a bot will walk there: a link can cross a gap the player hull cannot fit through, or lead along a route path planning never picks. To test one area in game, the area is made the objective and bots are sent to get it.
sv_neo_ghost_spawn_pos "x y z"(Debug ConVar for overriding the ghost spawn position neo#2202, merged) replaces the position the round's chosen ghost spawn would have used, so any point becomes the CTG objective. The ghost is dropped a little above the area and settles onto it as it would from a real spawn. The map file is not edited..navby map name, so the harness copies the.bspbyte for byte under a second name that loads its own.nav. The same pin then runs on both meshes in one batch.On this map. Yard has no ghost spawns or capture zones, so here the probe also needs the server forced into CTG and two harness patches that spawn the ghost and send bots to it without a capture zone; those are harness-only, used on test builds and not part of this PR or any neo PR. The probes ran on the harness's research build, which has those patches.
Known, not changed
Path::Computefalls back to a straight line and labels it complete, and seek-and-destroy accepts it. Bot code, not the mesh: Bots skip goals no route reaches neo#2190 ("Bots skip goals no route reaches", draft) rejects such a goal and tries another; its research version cut all stuck events x0.70 [0.51, 0.99] on master's mesh and x0.67 [0.51, 0.85] on this one's first revision (12 pairs each).Earlier measurements (on the harness's research build, and the mesh before its roofs, review fixes, ladder descents and staircases)
.nav, run back to back. JGR with the juggernaut pinned at each of its 3 spawn points, 30 bots, default weapon damage, 8 matches at a time, 24 pairs. The stuck count isOnStuckplusFAIL_STUCKmove failures, excluding the spawn crush at round start and the weapon-scavenging behavior.FAIL_NO_PATH_EXISTS3.6 -> 3.8 a match; "fell off the path" 6.0 -> 5.5; kills 102.6 -> 106.2 a match, a minute of live round x1.02 [0.99, 1.05]; fall deaths 0 / 0; no asserts, no crashes in 48 matchesPath::Computefalls back to a straight line and labels it complete, and the bot walks it into whatever is in between; on this map that is mostly bots roaming to a spawn point they cannot reach (see "Known, not changed"). Split by the path the bot followed: on a real route x0.48 [0.39, 0.58]; on a straight-line fallback x0.93 [0.80, 1.06]The first revision of this PR had the rework, the west roof and the east building's ladders, with every ladder whose top stands behind a parapet or rail climb-only. Later revisions meshed the north and south roofs, applied the outside review's and the hull audit's fixes, linked those ladders going down, moved the roof exits onto standing room and meshed the staircases. Each later step was measured against the one before it, the same way.
FAIL_NO_PATH_EXISTS1.29 -> 0.08, x0.69 [0.54, 0.84]; the landing at (730, -1110), which had no link out in the previous revision, no-path 1.17 -> 0; the staircase at (251, 477) 1.81 -> 0.75, x0.70 [0.54, 0.91]; the west roof's 0.62 -> 0.04, x0.80 [0.69, 0.92]).Approaches tried and dropped