Skip to content

ntre_saitama_ctg: navmesh rework - #146

Merged
sunzenshen merged 4 commits into
NeotokyoRebuild:masterfrom
sunzenshen:navmesh-saitama-release
Oct 14, 2026
Merged

sunzenshen merged 4 commits into
NeotokyoRebuild:masterfrom
sunzenshen:navmesh-saitama-release

Conversation

@sunzenshen

@sunzenshen sunzenshen commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

ntre_saitama_ctg: navmesh rework

One file, neo/maps/nav/ntre_saitama_ctg.nav. It was measured on upstream master plus the draft NeotokyoRebuild/neo#2176 (then only its unwanted-ladder release, now its changes 1 and 7).

Dependencies and status

Needs (worse than master, or broken, without it):

Helped by (measured better with it; the mesh does not wait on it):

  • More tweaks to bot ladder approaches, climbs and dismounts neo#2176 ("Fix bot ladder approaches, climbs and dismounts", draft): bots going down the ladder in the elevator hatch end back on the car roof in 95 % of descents on upstream ladder code, as on master, and in 5 % with it; going up ladder 13 its bots finished 27 of 27 climbs in its ladder tests, master 15 of 53. Its description lists one ladder here where it does worse: ladder 13 down, when six bots crowd the hatch top.
  • Bots re-check a skipped-to goal when pushed off their path neo#2200 ("Bots re-check a skipped-to goal when pushed off their path", draft): bots that fall through the hatch into the slot beside it (62 stuck events in its survey, 8 with it).

Pending before review:

  • Nothing: ready for review.

At a glance

master this PR
nav areas 1348 1035
file size 511,205 bytes 321,672 bytes (-37 %)
areas no spawn can reach 25 (7 pockets) 7 (3 pockets), 5 of them the fire pit's edge strips
areas the engine blocks at every round start 31 0
one-way walk links between level floor (no drop explains them) 3 5, all deliberate (the fire pit's exit-only bands)
areas marked PRECISE + CLIFF 0 5
nav ladders 4 7 (master's 4 unchanged, 3 added)
bot stuck events a match (see below) 52.3 26.1

Four commits:

  1. Rework - the mesh itself.
  2. Id alignment with master - ids only, so an id-keyed diff against master reads sensibly.
  3. Fire-pit edges - paths stay back from both of the pit's lethal edges.
  4. Review fixes - one-way links, lost drop backs, a prop staircase, and areas inside props (see below).

1. What changed

  • Regenerated, and sliver areas merged into their neighbors on the same floor.
  • Areas the engine blocks at every round start (31 on master) are removed. The engine drops any area with a brush, prop or displacement 35-59 u over its center from pathing for the whole round, so paths through them fail.
  • Props. Floor under props bots stood pressed against is cut out.
  • Ten walk links a player hull cannot cross are cut: a desk, an office chair, pipes and a power box, a forklift, a monitor, world brushes and two nodraw clips (two of them had over 200 stuck events each in earlier test runs). The five areas left with no way in are removed.
  • The slab at the top of ladder 2 (75, over the freight elevator) reaches half a hull from the wall, and ladder 2's two top landings link to it. Before, bots set down at ladder 3's foot stood in a strip no area covered.
  • Three ladders master does not have. Every CONTENTS_LADDER brush on the map now has a nav ladder:
    • the ladder props on the rabbitfrog vehicle in the NSF spawn room, from the floor to a new CROUCH area on the vehicle's roof (66 u under a beam, so only Supports must crouch);
    • the south face of the wall under area 720 (ladder 4 climbs its north face), from the closed alcove behind it; master's links from that alcove through its east wall cross a wall and are not kept;
    • the short ladder at (-664, 3386).
  • Pockets no class can climb into are removed: the spawn room's ceiling beams (98 u over the vehicle roof) and two ledges (68 u and 88 u). A 51-59 u ledge behind a crate is linked as a Recon climb.
  • The fire pit (see below). No area or link crosses the pit, on master or here. Its west grate rim (two 25 u strips, 3362 / 3363) is marked PRECISE + CLIFF, and for now no path leads onto it: the links into the rim are cut, the links out are kept, so a bot that lands there walks off it westward.
  • Re-analyzed in game after the edits, so the per-area visibility lists bots use for what they can see are current.

2. Id alignment

1043 of the 1047 areas carry the id of the master area they match; master's four ladders keep ids 1-4. Areas are matched only within 64 u of height, so the new vehicle roof gets a new id instead of the id of master's ceiling beam above it. Geometry, connections, attributes and the analysis data are unchanged by this step (verified topology-identical).

3. Fire-pit edges

After the rim's entrance cut, the areas bots could still stand on at the pit's lethal edges were 403 / 2660 on the west side, 32 u from the lip, and 128 on the east side, 24 u from it (found with an offline check that lists every area with a side whose drop lands in a lethal hurt volume). Each lethal side gets the rim's treatment: a 25 u strip along it is split off (403 at x 1275, 128 at x 1700), marked PRECISE + CLIFF, and has no links in; its links out stay. On the west the strip joins 2660 and the rim in one exit-only band. Paths now stop 56 u from the lip, and ghost spawn 9 stays on 403, reachable. The two strips are the only new ids (3859, 3860); 1043 of the 1049 areas keep their master id. Re-analyzed in game.

4. Review fixes

An outside review of the mesh listed walk links that run one way only, climbs whose drop back was cut, and floor reached only by climbs no bot plans. Every one-way pair was swept with a player hull both ways by an engine hull audit (a harness-only test build: a hull is stood every 4 u on every area and swept every 4 u across every link), and the mesh's level links were checked the same way.

From the review:

  • One-way level links. Two pairs blocked both ways are cut both ways (box pallets near (-1290, 3140), a large crate near (-240, 3170)); the missing direction of six pairs that are clear is restored (423 / 3302, from master, 673 / 219, 1206 / 219, 1207 / 258, 1359 / 11, 1651 / 188). Three half cuts ended in areas no player hull fits in, which are deleted: a 10 u strip inside the wall near (1565, 2255), and the floor under an office chair and a desk near (-610, 1915) and (-65, 1835).
  • Exit-only links kept on purpose: the fire pit's west band (3362 -> 2660, 3362 -> 3859, 3363 -> 3859, 3859 -> 403) and east strip (3860 -> 128), as in commit 3.
  • Climbs whose drop back was cut. The drop back is restored onto six wall-top strips (5-10 u wide; the audit stands a hull on each) and onto the car roof near (-210, 12). The climb onto a desk top near (-340, 2150) past an office chair is cut (no lane clear); the desk top keeps its way in and out over the desk's other side.
  • The 154 u climb from 16 to 3259 (from master) is cut. It alone reached 3258 / 3259, a sloped top over the control room near (790, 60): a flood fill of the map's collision from it finds no way on with 40 or 62 u jumps, so both areas are removed.
  • The prop staircase near (300, -420) (a switchback of two flights, 11 u risers): the mesh had its foot, landing and top joined only by 76 u links across each flight, which no class plans, so the landing and the top (4 areas, 3 hiding spots) could not be reached. Each flight gets a sloped area linked both ways to the landings, and the 76 u links are cut.

Beyond the review, from the same audit (bot positions from 138 matches on this mesh):

  • Ten more areas no player hull fits in, each with 83-100 % of the audit's stand samples blocked by a prop, and no more than 6 bot position samples: inside the forklift, a file cabinet, gas pipes, two banks of monitors, a crate, a hand cart, the desk and chair beside the one above, and shelving. The corner behind the file cabinet near (-737, 2537), reached only through it, goes too: its edge with the room is shut by an office chair.
  • The link behind the sofa near (-625, 2112), blocked both ways, is cut; bots never crossed it.
  • Kept: a link by box pallets near (1334, 2750) with one 4 u lane blocked, which bots crossed 58 times.

Every kept area keeps its id; the two flights are new (3861, 3862). Re-analyzed in game.

How it was tested

  • Reachability:
    • every spawn can reach every other spawn
    • every objective is reachable from a spawn
    • no area is blocked at round start (checked in game: master logs 31)
    • three pockets are unreachable: the fire pit's west edge band (the rim and the strip beside it, 4 areas) and its east edge strip (1 area), both on purpose, and a crate top with the floor behind it (2 areas), reached only by a 50 u drop from a bridge, kept as on master
    • by each class's climb limit (the most a bot plans: Recon 68 u, Assault 48 u, Support 43 u), Recon reaches every area but those 7, Assault all but 15 and Support all but 17: the rest are raised tops 43-55 u up that only a Recon climbs onto
    • no area a class can enter and not leave; no one-way link between level floor but the five exit-only ones above
  • Engine hull audit of the final mesh: no linked area a player hull cannot stand in; level links blocked on every lane both ways: one (the box pallets above, kept). BLOCKED_LINKS map=ntre_saitama_ctg level_pairs=1493 oneway=0 keep=5 cut=1 area=0 check=2 entity=0; the two checks are the new flights, too steep for the audit's stand test
  • Ladders. Pinned-ghost probes at both ends of the two new ladders with a way in (the vehicle roof and the alcove), 3 runs a spot on each mesh, 12 bots at a tenth of weapon damage, on the same build as below: master 6 of 12, this mesh 12 of 12. Master reaches neither the vehicle roof nor the alcove (0 of 3 each); on this mesh bots reach the roof in 16-17 s, 7-10 of them a run including Supports, and the alcove in 56-110 s. The third new ladder, the short one at (-664, 3386), is climbed in play (about 0.2 times a match).
  • Master against this mesh, same bot code. Byte-identical copies of the map, one carrying each .nav, run back to back. Upstream master (at #2168) plus #2176, with harness logging added. CTG, 2 rounds of 3 minutes with the ghost pinned at each of the 17 ghost spawns in turn, 2 runs each, 30 bots, default weapon damage, 8 matches at a time; every match reached match end with 0 asserts. The stuck count is OnStuck plus FAIL_STUCK move failures, excluding the spawn crush at round start and the weapon-scavenging behavior.
    • stuck events 52.3 -> 26.1 a match (paired x0.49, 95 % interval [0.35, 0.67], 27 of 34 pairs down, 7 up)
    • FAIL_NO_PATH_EXISTS move failures 4.2 -> 3.7 a match; "fell off the path" failures 0.6 -> 0.4
    • kills 49.1 -> 48.8 a match (paired x1.00 [0.97, 1.04])
    • bots still see and shoot across the mesh: 87 % of kills are between bots in different nav areas and 69 % in non-adjacent ones, against 89 % / 70 % on master (kill distance median 237 u against 252 u)
  • The review fixes against commit 3, the same design on upstream master plus #2176 and #2186, 34 pairs: stuck events 17.6 -> 16.9 a match (paired x0.95, 95 % interval [0.66, 1.38], 17 down / 16 up); at the edited spots 9 -> 6; "fell off the path" failures 1.8 -> 0.1 a match; kills 49.1 -> 50.0; ghost captures 12 -> 14 of 68 rounds; no fall deaths; 87-88 % of kills between bots in different areas. Every match reached match end with 0 asserts and no crash. No bot used the new flights in these matches (none had on the old mesh either).
  • Earlier revisions, the same comparison: without the edge strips (commit 3), 34 pairs, x0.50 [0.36, 0.67] (26 down / 8 up; kills 49.2 -> 48.3, ghost captures 18 -> 26 of 68 rounds, team kill ratio 1.04 -> 0.97); without the rim's link cut, 34 pairs at 8 wide, x0.58 [0.43, 0.77] (25 down / 9 up); and at 16 matches at a time, 51 pairs each, x0.49 [0.36, 0.67] without the fire-pit marks and x0.51 [0.39, 0.66] with them.

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. To test one spot in game, the ghost is placed on it and bots are sent to get it.

  • The ghost is placed on the spot by a server cvar. A harness-only neo patch, used on test builds and not part of this PR or any neo PR, adds sv_neo_ghost_spawn_pos "x y z", which replaces the position of the round's ghost spawn. The map file is not edited.
  • A pickup at the spot means bots can reach it. The pickup position is checked against a box on the landing, because a large radius counts master as reaching the vehicle roof from the floor 126 u below it.
  • Master's mesh runs beside this one on a byte-identical copy of the .bsp under a second name that loads its own .nav, so the same pin runs on both meshes in one batch.

The fire pit

Every fall death on this map, on master and on this mesh alike, is a bot burning in the fire pit with the ghost on spawn 9, beside the pit (none at the other 16 spawns). On upstream code, spawn 9 only, 8 matches each: master 21 deaths, this mesh 13 (30 and 22 in an earlier batch of the same size).

  • Why bots go in. A dead bot's weapon lands on the pit floor. The next bot to scavenge for a weapon plans a path to it; no nav area reaches it, so the path's last leg is a straight walk from the edge of the mesh to the weapon, off the grate rim. Each death drops another weapon there. Neither the mesh nor the rim's marks can stop a leg that runs off the mesh, so the fix is in bot code: Bots skip weapons they cannot reach when scavenging neo#2186 makes scavenging skip weapons no nav area reaches. With it, spawn 9's fire-pit deaths go to 0 on both meshes (36 -> 0 over 14 match pairs).
  • No path leads onto the rim, for now. The mesh has never crossed the pit: no area lies over it and no link spans it, on master or here. The only nav at its edge is the west grate rim, two 25 u strips that lead nowhere else. This PR keeps bots off the rim for now: the links into it are cut, and the links out are kept so a bot that lands there can walk off. Both strips stay marked PRECISE + CLIFF. This alone does not change the deaths above (the scavenging leg does not follow nav links); it keeps bots from being sent to the pit's edge.
  • No path leads near either edge. The third commit does the same for a 25 u strip along each of the pit's lethal edges (above), so no path comes closer than 56 u to the lip on either side. Checked against the mesh without it, on the same build plus the SeekWeapon PR (40 pairs): no stuck event on any area at the pit's edge on either mesh, no fire-pit death on either.

Known, not changed

  • The west ladder tower (ladder 2 up through the freight elevator's roof hatch to the slab, ladder 3 on to the top floor) holds about half of the stuck events left on this mesh, as on master. Bots start down ladder 2 about 20 times a match and about 95 % of those descents end back on the slab: the climb's early jump-off fires at the top of the ladder and its kick lands the bot on the slab again, and with that gated, a forward press made while the view is still level climbs the bot back over the top. The bot then follows its path along the floor below from the slab, into the slab's north wall or up ladder 3 to the top floor's north wall, until the stuck monitor fires. This is ladder-descent code, not the mesh; taking ladder 2 off the slab's down list was measured earlier and was worse (bots piled up on the slab, x1.81), so every ladder stays connected.
  • Captures. Ghost captures went 18 -> 26 of 68 rounds in the main batch and 22 -> 20 in the earlier one (40 -> 46 of 136 together); team kill ratios moved 1.04 -> 0.97 and 1.07 -> 0.97.

One file. Against master: 1348 -> 1047 areas, 511,205 -> 326,226
bytes; areas no spawn can reach 25 -> 4; areas the engine blocks at
every round start 31 -> 0; nav ladders 4 -> 7.

- Regenerated, and sliver areas merged into their neighbors on the
  same floor.
- Areas the engine blocks at round start are removed, and floor under
  props bots stood pressed against is cut out.
- Ten walk links a player hull cannot cross are cut (a wall, a
  nodraw clip, pipes, a desk, a forklift ...), and the areas left
  with no way in are removed.
- The slab at the top of ladder 2 (area 75) reaches half a hull from
  the wall, and ladder 2's two top landings link to that slab.
- Three ladders master lacks: the short ladder at (-664, 3386); the
  ladder props on the rabbitfrog vehicle in the NSF spawn room, up to
  a CROUCH area on its roof (66 u under a beam); and the south face of
  the wall under area 720, from the closed alcove behind it. Master's
  links out of that alcove through its east wall are not kept.
- Pockets no class can climb into are removed: the spawn room's
  ceiling beams and two ledges (68 u, 88 u).
- The fire pit: its west grate rim (two strips, the only nav at the
  pit's edge) is marked PRECISE + CLIFF, and for now no path leads
  onto it (the entrance links are cut, the exits kept). No area or
  link crosses the pit, as on master.
- Re-analyzed in game after the edits.
Renumbers area and ladder ids only, so an id-keyed diff against
master reads sensibly: 1043 of the 1047 areas carry the id of the
master area they match; master's four ladders keep ids 1-4. Areas
are matched only within 64 u in height, so the new vehicle roof does
not take the id of master's ceiling beam above it. Geometry,
connections, attributes and the analyzed visibility data are
unchanged (verified topology-identical).
Bots should neither cross the fire pit nor go near its edges. After
the rim cut, the areas bots still stood on at the pit's lethal edges
were 403 / 2660 on the west (32 u from the lip) and 128 on the east
(24 u), found by harness/analysis/nav_death_areas.py. A 25 u strip
along each lethal side gets the rim's treatment: 403 is split at
x 1275 (its east half, 3859, and 2660 join the exit-only band with
the rim) and 128 at x 1700 (its west strip, 3860); the strips are
PRECISE + CLIFF and have no links in, their links out stay. Paths now
stop 56 u from the lip. Ghost spawn 9 stays on 403, reachable. No
area lies inside the pit's trigger_hurt. Re-analyzed in game; ids as
the previous commit, the two strips are new.
An outside review of this mesh found walk links that run one way
only, climbs whose drop back was cut, and floor reached only by
climbs no bot plans. Each one-way pair was swept with a player hull
in both directions by the engine's hull audit:

- Cut both ways the two pairs blocked both ways (box pallets, a large
  crate); restore the missing direction of the six pairs that are
  clear. Delete three areas the half cuts ended in that no player
  hull fits in: inside a wall, an office chair, and a desk.
- Restore the drop back from seven wall-top strips and a car roof
  whose climb was kept. Cut the climb onto a desk top past an office
  chair (no lane clear).
- Cut the 154 u climb from 16 to 3259 (from master) and delete the
  two areas it alone reached, the sloped top over the control room:
  nothing a player can jump onto reaches it.
- Mesh both flights of the prop staircase near (300, -420): the
  foot, landing and top were joined only by 76 u links across each
  flight. The 76 u links are cut.

The fire pit's edge bands keep their exit-only links (the rim and
the two edge strips).

Beyond the review, from the same audit: delete ten more areas inside
props (forklift, file cabinet, gas pipes, monitors, a crate, a hand
cart, the desk and chair, shelving) and the corner behind the file
cabinet that only one of them reached; cut the link behind the sofa,
blocked both ways.

Existing areas keep their ids; the two flights are new. Re-analyzed
in game (same graph, fresh visibility).
@sunzenshen
sunzenshen merged commit c407683 into NeotokyoRebuild:master Oct 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants