Repository navigation
ntre_skyline_ctg: navmesh rework - #164
Merged
sunzenshen merged 3 commits intoOct 14, 2026
Merged
Conversation
One file. Against master: 1463 -> 1085 areas, 1,792,918 -> 1,038,899 bytes; 3 nav ladders, as master; stored BSP size now matches the map. - Areas the engine blocks at round start are cut around the obstacle, and standing room is carved round props where test bots stuck. - 35 rooftop fall-edge areas are PRECISE + CLIFF; the two areas at ladder 1's foot are AVOID. - Master's three areas with no way back (3089, 3513, 4444) are gone. - Walk links a player hull cannot cross are cut both ways: past wall trims, handrails, vent supports, a tree, the large wire pipe, and a gap link across the trench at (419, -571); strips inside handrails, a post and a wall, and four areas on a thin 45 deg plate at (1275, -440), are removed. - The clip near (1042, -1005) gets a CROUCH strip under it; the stair corner near (-2265, -1900) is reshaped so paths run west of it. - The rooftop strip at (-1508, 78, 213) has its own area (4478). - Links cut one way by earlier passes get their missing direction back where the hull audit reads them clear both ways (8), or are cut both ways where it reads them blocked; the 100 u climb 12 -> 701, which no class plans, is cut. - Re-analyzed in game after the edits. Engine hull audit of this file: oneway 0, cut 0, area 0, check 0, entity 0, keep 2 (the west stair 617 / 871 up to the rooftop strip, and 31 / 633 beside the desk ghost spawn 10 lies on), sinks 0 for every class. 120-match A/B against master, same bot code (30 bots, 10 ghost pins x 6, 1 round, 8 wide): events a match 32.9 -> 4.3, stuck events 28.9 -> 2.4, stuck episodes 5.2 -> 0.8, fall deaths 1.20 -> 0.87; kills 25.5 / 25.2; all 120 matches ended clean.
Ghost spawn 1 at (-3317, 135, 43) rests on a desk, and the engine's line-of-sight goal test skips the floor area under it, so a path to the ghost ends in the west-wall strip beside it. That strip was one 400 u area (3975), and a path from the south crossed into it at its south end (-3425, -80), 240 u short of the ghost. Split it back at y 75 / 125 / 200 into master's 3975 (shortened), 3978 and 3981, plus 3982 for y 200..300, so the area beside the ghost is 50-75 u long. Delete 11 rail-top slivers on the rooftop strip (1180, 1181, 1189, 1191, 1192, 1194, 2132, 2154, 2162, 2183, 2207): no link in or out since area 3 was split, none within 160 u of an objective. Areas no spawn reaches over any link: 29 in 19 pockets -> 18 in 8. 1085 -> 1077 areas, 1,038,899 -> 1,027,891 bytes. Re-analyzed in game. Engine hull audit: oneway 0, cut 0, area 0, check 0, entity 0, keep 2, sinks 0 for every class. Ghost pinned at spawn 1, previous revision v this one, 13 matches each: pickup median 13.7 -> 10.7 s (master 10.9 s, 6 matches); matches with bots at the strip's south end before the pickup 13 -> 1. 100-match A/B against the previous revision, same bot code (30 bots, 10 ghost pins x 5, 1 round, 8 wide): events a match 4.2 / 4.3, stuck episodes 0.9 / 0.9, fall deaths 0.84 / 0.88, kills 25.3 / 25.2; no spot over 1 event a match; all 100 matches ended clean.
The rework merged master's 4268 (x -800..-775, y -450..-400) into 4267, so 4267's drop east to the floor 3909, 168 u below, ran under the catwalk 4441 / 4442 that crosses above 3909. A path dropping there aims at a point under the catwalk; on upstream master's bot code bots walked the catwalk back and forth toward it until the stuck monitor fired. Split 4267 at y -450 again as master has it: 4267 keeps the drop, 4268 links to 4441 and 647 only. 1077 -> 1078 areas. Re-analyzed in game. Engine hull audit: oneway 0, cut 0, keep 2, one-way drops 194, sinks 0 for every class. Offline gate: pass, reachability as before. Upstream neo master 092203f36 (Release), 30 bots, ghost pinned at each of the 10 spawns x 5, 1 round, 8 wide, 50 matches an arm: stuck events within 90 u of (-700, -430), master mesh / previous revision / this one: 0.06 / 2.68 / 0.28 a match (in 15 / 26 / 10 matches). Map-wide stuck events 50.4 / 17.7 / 14.2, fall deaths 2.16 / 1.16 / 1.30; all 150 matches ended clean, 0 asserts.
sunzenshen
marked this pull request as ready for review
October 13, 2026 01:21
sunmachine
approved these changes
Oct 14, 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.
ntre_skyline_ctg: navmesh rework
One file,
neo/maps/nav/ntre_skyline_ctg.nav.Dependencies and status
Needs: none. Measured on neo master
092203f36with no open PR (A/B below). The bot changes this mesh carries data for arein master now:
NAV_MESH_AVOID.NAV_MESH_PRECISE: 35 rooftop fall edges (alsoCLIFF) andtwo at the stair corner near (-2265, -1900). On neo master, fall deaths from these 37 areas: 1.06 a match on master's mesh, 0.18 on this one.
Helped by (measured better with it; the mesh does not wait on it):
At a glance
What changed
obstacle or split, and standing room is carved around props where test bots stuck on them.
rooftop edges, are
PRECISE+CLIFF. The other three (9, 251, 4035) are large through-areas: marked, bots queuedat one waypoint there (area 9: 37 stuck events a match) with no fewer falls, so they stay unmarked.
three are removed.
lanes) found no clear lane on four links bots got stuck on: past an exterior wall trim, an ivy trim, and a large pipe
prop. Two areas left with no way in are removed. Against the mesh before (10 pins): stuck events 101.7 -> 76.4 a match
at reduced weapon damage.
The audit of the final file cut more pairs both ways where no lane is clear either way: the nook 3654 to 408 near
(1388, 475, -128) (a wall trim; 3654 keeps its link to area 73), a stair handrail at (-1212, 130), a tree at
(-1875, 968), two vent supports at (112, 150) and (425, -38), and the large wire pipe at (625..760, 225..300), whose
sloped end and a post split the areas on its top from the floor east of it. The ramp 4294 at (350..525, -600..-575)
and the roof slab 12 north of it were linked across the 130 u trench between them, past a girder railing. The audit
read 7 of 13 lanes clear there, but with the link back in, test bots logged 884 stuck events on the ramp in 20 of 20
matches, so it is cut both ways.
wall at (-2212, -117), a 25 u nook in a player clip at (788, 488), and four areas on a thin 45 degree plate 100 u above
the floor at (1275, -440) that no spawn reached.
could not pass under it. The strip under it is a
CROUCHarea. With the ghost pinned at 6 spawns, 2 matches each:stuck events at the spot 26 -> 0, on the map 8.9 -> 6.0 a match, no new spot.
crouched. The rail stretch of the area north of it is removed and its north piece is
PRECISE, so paths runthrough the open area to the west.
floor 3909, 168 u below, ran under the catwalk 4441 / 4442 that crosses above 3909. A path dropping there aims at a
point under the catwalk, and bots walked the catwalk back and forth toward it until the stuck monitor fired. 4267 is
split at y -450 again as master has it: 4267 keeps the drop, 4268 links to the catwalk and the floor west of it only.
On neo master, 50 matches a mesh: stuck events within 90 u, 2.68 a match (26 matches) before the split, 0.28 (10
matches) after; master 0.06 (and 0.30 fell off the path).
part (y -150..-53), and the rest is two areas, the strip 4478 and 4471 east of it, linked both ways to each other, to
3 and to the west stair. With the ghost pinned on the strip (ghost spawn 4), 6 of 6 matches picked it up on each
mesh, median 44 s on master and 31 s on this one.
area with a line-of-sight test that the desk blocks for the floor area under it, so every path to the ghost ends in
the 25 u strip along the west wall beside it. Master has that wall as eight strips; an earlier pass merged them into
one 400 u strip, and a path from the south then crossed into it at its south end near (-3425, -80), 240 u from the
ghost. The strip is split back at y 75, 125 and 200, so the area beside the ghost is 50 to 75 u long, as on master
(3978 and 3981 keep master's ids and corners). With the ghost pinned there, 13 matches a mesh: pickup median 13.7 s
on the mesh before this split and 10.7 s on this one (master 10.9 s, 6 matches), and bots ran to the strip's south
end before the pickup in 13 of 13 matches before, 1 of 13 after.
each: master linked them to area 3, and with 3 split they had no link in or out.
AVOID.hull audit reads them clear both ways: three between level floor and five drops back from climbs. The climb at
(-1012, 227) through a stair handrail is cut instead, and so is the 100 u climb from 12 to 701 near (150, 60), across a
25 u gap, which no class plans.
How it was tested
y 499, where master's ran under the desk (35 u of headroom). With the ghost pinned there, 6 of 6 matches picked it up
on each mesh, median 23 s on master and 22 s on this one. No area is added on the desk top: bots take the ghost from
the floor beside it.
strips at z 170 around (-1725..-1200, -200..300), 23,375 sq u, which lie along the deck's handrails, inside the rails'
collision, floor cut back around the office chairs near (-3350..-2900, -1600..-1250), the stair corner's rail stretch,
a rail top at z 214, the floor under the desk at ghost spawn 10, and two
CROUCHstrips near (-475..-400, 1175..1225,-256). Each of the two strips has a leg of a vent support (a 4 x 3 u post up to the duct at z -180) inside the box the
engine tests over its center, so the engine dropped both from pathing for the whole round; they went with the other
round-start blocked areas.
trigger_hurtvolumes: a pit, the roof, and six tanks. In the A/B below, 2.46 fall deaths amatch on master's mesh and 1.28 on this one (paired ratio x0.64 [0.54, 0.76], lower in 35 of 50 pairs, higher in 7). From
the 37
PRECISEareas (ids as master's): 1.06 and 0.18 a match.BLOCKED_LINKS map=ntre_skyline_ctg level_pairs=1557 oneway=0 keep=2 cut=0 area=0 check=0 dynamic=0 entity=0 one_way_drops=194 sinks(any/recon/assault/support)=0/0/0/0. The two kept pairs read blocked and are walked: 617 / 871,the west stair up to the rooftop strip, whose lanes start in the slope (with the pair cut, no bot picked up the ghost
pinned on the strip in 6 matches; master 6 of 6), and 31 / 633, the floor beside the desk at ghost spawn 10, the
spawn's nearest area.
092203f36with no open PR, Release build plus theharness's logging. Byte-identical copies of the map, one carrying each
.nav, matches interleaved: CTG, the ghostpinned at each of the 10 ghost spawns in turn, 5 matches each (50 a mesh), 30 bots, default weapon damage (1.485), 1
round, every player at one rank tier rotated across the pins, 8 matches at a time. Stuck events are
OnStuckplusFAIL_STUCK, without the spawn crush at round start and weapon scavenging. Paired ratio: geometric mean of(this mesh + 1) / (master + 1) over the 50 pairs, with a 95 % bootstrap interval.
By rank tier, stuck events master / this mesh: Private 56.9 / 12.2, Corporal 37.0 / 13.5, Sergeant 50.2 / 7.1, Lieutenant
50.1 / 11.8. Ghost pickup median, master / this mesh: ghost spawn 1 (the desk) 12 / 12 s, ghost spawn 4 (the rooftop
strip) 46 / 26 s, ghost spawn 10 (the desk at (-1047, 511)) 22 / 23 s, all 5 of 5 on each mesh. In two more batches of
the same shape (master against this PR before the catwalk split, then master, that file and this one), all events went
49.9 -> 17.9 and 57.7 -> 18.3 a match; 250 more matches, all ended clean with 0 asserts.
Master's leading spots, events a match on master -> this mesh (neo master): the stair corner near (-2264, -1854) 12.4 -> 0;
ladder 1's foot near (-1009, -377) 7.6 -> 0.7; the office chairs near (-3074, -1405) 4.1 -> 0; the clip near (1000, -992)
2.0 -> 0; the double post near (-309, -289) 2.0 -> 0; the deck handrail near (-1731, 0, 170) 1.5 -> 0; the stair
handrail near (-968, 311) 0.4 -> 0.1. The helicopter prop on the rooftop strip: 0.37 on master, 0.18 on this PR's mesh
over the three batches. This mesh's leading spots are master's as well, listed under "Known, not changed": the slope south of
area 73 (3.3 a match here, 1.0 on master in this batch) and the pipe prop at area 675 (2.8, master 2.3).
Earlier measurement on the harness's research build (neo master plus the open bot PRs of the time and further research bot changes), before the catwalk split
That table is master against the mesh before the ghost spawn 1 split and the sliver removal, 10 pins x 6. Those two
edits were then measured against that mesh the same way, 10 pins x 5: all events 4.2 -> 4.3, stuck events 2.6 -> 2.5,
fall deaths 0.84 -> 0.88, ghost picked up 49 -> 48 of 50, 50 of 50 clean each.
Known, not changed
the area, against the world, in about 2 of 5 matches on either mesh. The areas and links there are the same on master
and here (this mesh only marks 675
PRECISE). On neo master over three batches: 2.8 events a match on master's mesh(150 matches), 3.6 on this PR's mesh before and after the catwalk split (200), the same move each time; 0.02 on the
research build, whose bot code the spot depends on.
(1450, 540, -128) until the stuck monitor fires, on either mesh; the areas 73, 3656 and 3667 and their links are master's.
Over three batches on neo master: 2.7 events a match on master's mesh, 2.8 on this one, in 44 and 69 of 150 matches.
Bots cross from 73 into the slope 1.6 times a match on master's mesh and 2.6 on this one, so events per crossing are
lower here (1.1 against 1.7); the rate follows traffic.
edge and wedge in the air between two round props for the rest of the round. 5 times in about 3,100 matches.
In a targeted test, marking the edge
PRECISEkept bots on it (position samples off the edge 6 -> 0, 24 matches anarm), but they then stood and fought on the marked strip twice as long; the mark is left out of this mesh and the trap
left to bot code.
On neo master: no event and no fall death within 80 u on either mesh in 350 matches (three batches).
(338..425, 325..425, 48), 48 u, and 4464 -> 4465 near (-1670, 790, 35), 39 u. Each has a planned way back up nearby.
On neo master, 350 matches: one bot stepped down 1102 -> 3915 and back up; 4 events within 110 u in 200 matches on
this PR's mesh, none on master's.
the rail and the stair's post has no nav area. On neo master: 12.4 events a match within 100 u on master, none on
this mesh.