Skip to content

ntre_transit_ctg: navmesh rework - #145

Merged
sunzenshen merged 3 commits into
NeotokyoRebuild:masterfrom
sunzenshen:navmesh-transit-release
Oct 14, 2026
Merged

sunzenshen merged 3 commits into
NeotokyoRebuild:masterfrom
sunzenshen:navmesh-transit-release

Conversation

@sunzenshen

@sunzenshen sunzenshen commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

ntre_transit_ctg: navmesh rework

One file, neo/maps/nav/ntre_transit_ctg.nav.

Dependencies and status

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

  • None. No open bot code PR has to be reviewed or merged before this mesh: the one spot that needed bot code, the track bed beside the parked pilot car's nose, is fixed by Re-path when a bot lands below its path neo#2185 ("Re-path when a bot lands below its path", merged). On code without it that spot has 4.1 stuck events a match on this mesh against 2.3 on master, and 0.25 with it (see "Known, not changed"). The mesh was measured with and without More tweaks to bot ladder approaches, climbs and dismounts neo#2176 ("Fix bot ladder approaches, climbs and dismounts", draft), then only its unwanted-ladder release, and the gain does not depend on it; the map's two nav ladders are master's.

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

  • None measured.

Pending before review:

  • Nothing: ready for review.

At a glance

master this PR
nav areas 743 513
file size 289,515 bytes 232,783 bytes (-20 %)
areas no spawn can reach 40 (3 pockets) 18 (1 pocket)
areas the engine blocks at every round start 9 0
one-way walk links between level floor 1 0
nav ladders 2 2 (records unchanged, climbed and descended as on master)
bot stuck events a match (see below) 55.5 19.4

Three commits:

  1. Rework - the mesh itself.
  2. Id alignment with master - ids only, so an id-keyed diff against master reads sensibly.
  3. Review fixes - one-way links, a track-bed climb, and areas inside props (see below).

1. What changed

  • Regenerated, and sliver areas merged into their neighbors on the same floor (743 -> 518 areas).
  • Links the player hull cannot cross are cut. Six walk links that ended against a wall, a prop or a long drop (the warning-stripe wall by the east ladder, an ashtray, a barrier rail, a shelf, and a 160 u drop past a world brush from the west ladder's top landing), and links across railings. Along the platform edges the drop to the track bed now only crosses where the barrier rail has its opening.
  • Props. Areas are split or trimmed around six props bots stood pressed against, and one spot by the west ladder's top where a player cannot stand is cut out.
  • The 9 areas the engine blocks at every round start are removed, or split where removing them would strand what lies behind.
  • The breakable grate beside the south glass pane. The area that ran through it is removed. The grate is intact at round start and bots do not shoot it open, so paths through it ended against it. The crawlspace behind it is still reached from its other entrance; traffic between the halls uses the passage by the north pane.
  • The parked pilot car. The areas under the car's body are removed, and the track bed areas stop half a hull short of its nose. The car is chamfered towards the nose, and a player fits in the floor beside it on each side: bots that step off the walkway end up there. Each side keeps one area (master's 625 and 626), linked with the track bed to the north. Master's climbs from those two pockets up to the walkway and the platform are not kept: bots fail them in the narrow pocket.
  • Ladders keep master's records: both ladders are climbed and descended from both side landings, as on master.
  • 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

514 of the 518 areas carry the id of the master area they match, including the two pocket floors (625, 626). 10 kept ids sit more than 64 u from their master location or on another level. An id-keyed diff shows 4 added areas and 229 removed. Geometry, connections, attributes and the analysis data are unchanged by this step (verified topology-identical).

3. Review fixes

An outside review of the mesh listed walk links that run one way only and a climb whose drop back was cut. 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. Three ended in 20 u squares inside ticket machines near (-370, -1300), (-310, -1300) and (30, 1310), where every stand sample is blocked: the squares are removed. The link through the vending machine near (-270, -560), one-way on master too, is cut.
  • The track bed beside the east platform near (120, 1070) was one area (master had three) running along the barrier rails at x 84 and the opening at their north end, so its 40 u climb to the platform crossed the rails and its drop back had been cut. It is split at y 1096, the rails' end plus half a hull; the north piece is linked both ways with the platform through the opening, the south piece not at all.

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

  • Two more 20 u squares no player hull fits in, inside a bench near (-190, 290) and a barrier near (310, 1070), are removed.
  • The 20 u roof of the bus stop kiosk near (-110, -790), reached only by 80 u climbs no class makes, is removed: a flood fill of the map's collision from it finds no way on with jumps of up to 62 u.
  • Left for the runtime avoidance of physics props (a separate bot change): the links past a recycle bin near (-220, -1450) and an office chair near (-840, 370), which the audit reads blocked as the props stand at round start. Also left: the breakable glass pane near (260, 620), intact at round start.

Every kept area keeps its id; the track bed's north piece is new (2355). 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
    • the one unreachable pocket is the east train's roof (see below)
    • by each class's climb limit (the most a bot plans: Recon 68 u, Assault 48 u, Support 43 u), Recon and Assault reach every area but 60, Support all but 64: the east train's roof (18), the west train's roof (42, see below), and for Support the tops of four garbage bins, 43.7 u up
    • no area a class can enter and not leave; no one-way link between level floor
  • Engine hull audit of the final mesh: no linked area a player hull cannot stand in, no level link blocked both ways but the three by movable or breakable props above. BLOCKED_LINKS map=ntre_transit_ctg level_pairs=750 oneway=0 keep=0 cut=0 area=0 check=0 entity=3
  • Ladders. Pinned-ghost probes at every ladder end (both side landings at each top, and each foot), 3 runs a spot on each mesh, 12 bots at a tenth of weapon damage: all 6 ends reached in 18 of 18 runs on master and on this mesh, with the same time to first reach (21-39 s median). The probes ran on a revision that differs from this one only by the two pocket floors by the pilot car, far from both ladders.
  • 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 5 ghost spawns in turn, 30 bots, default weapon damage, 8 matches at a time. The stuck count is OnStuck plus FAIL_STUCK move failures, excluding the spawn crush at round start and the weapon-scavenging behavior.
    • stuck events 55.5 -> 19.4 a match (paired x0.33, 95 % interval [0.25, 0.43], 20 of 20 pairs down)
    • FAIL_NO_PATH_EXISTS move failures 6.7 -> 8.4 a match (spread over the map, mostly the attack behavior's chase path failing to reach its target)
    • kills 50.3 -> 48.5 a match; team kill ratio (Jinrai / NSF enemy kills) 0.85 -> 0.92
    • fall deaths: none on either mesh in any batch (the map has no trigger_hurt, and the walkway drops are 40 u)
    • bots still see and shoot across the mesh: 91 % of kills are between bots in different nav areas and 82 % in non-adjacent ones, against 91 % / 81 % on master (kill distance median 472 u against 447 u)
  • Without #2176. The same comparison with #2176's behavior switched off (stock ladder code), 15 pairs: x0.39 [0.27, 0.53], 14 of 15 pairs down, none up (43.5 -> 17.3 a match); kills 50.1 -> 49.1.
  • The review fixes against commit 2, the same design, 25 pairs each:
    • upstream master plus #2176 and #2186: stuck events 17.4 -> 14.8 a match (paired x0.87, 95 % interval [0.62, 1.24], 14 down / 9 up); at the edited spots 14 -> 0 (the track bed by the east platform 11 -> 0); kills 49.0 -> 50.0; no fall deaths
    • the same plus #2185: 14.0 -> 10.4 (x0.76 [0.54, 1.07], 17 down / 8 up); at the edited spots 10 -> 1; kills 50.2 -> 50.2
    • the pilot car's nose (below), which the review fixes do not touch: 3.3 / 4.3 a match without #2185, 0.3 / 0.5 with it
    • every match reached match end with 0 asserts and no crash; 91-92 % of kills between bots in different areas on both
  • Earlier revisions of this mesh (without the two pocket floors, or without the east one) measured x0.28-0.42 against master in five more comparisons of 15-20 pairs; the east pocket floor alone made no measurable difference (30 pairs, x1.02-1.10, interval across 1).

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 position of the first pickup is checked, because a ghost on a ladder's top landing could fall down the shaft; here it stayed on its pin every run.
  • 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.

Known, not changed

  • The pilot car's nose. The walkway beside the west track is 41 u wide with a 40 u drop to the track bed. Bots step off it three to four times a match on either mesh, keep the path along the walkway, and some walk along the track bed into the V between the walkway and the car's chamfered nose, where they stand until the stuck monitor fires. On this mesh that is 4.1 stuck events a match, against 2.3 on master (35 matches each). It is a path-following matter: the bot keeps a path it can no longer follow. Re-path when a bot lands below its path neo#2185 makes a bot re-plan when it lands below its path, which takes the spot to 0.25 a match on this mesh and 0.1 on master's; this PR needs it for that spot. Marking the walkway PRECISE cut the falls by a fifth to a third, but added as many stuck events on the walkway itself (bots meeting on it no longer side-step), so it is not in this PR.
  • The east train's roof (18 areas, 38 on master) has no way in: a beam over the platform lip leaves too little headroom. Bots land on it about once in 40 matches by a squeeze above the train's ghost spawn, and leave by the roof's own drops within a few seconds. Removing it would strand such a bot off the mesh; linking it would send bots through the beam. It stays as on master.
  • The west train's roof (42 areas) counts as reachable only through links from the track bed that rise 114 u, more than any class can climb. Path costs keep bots off them. Inherited from master.

One file. Against master: 743 -> 518 areas, 289,515 -> 238,249
bytes; areas no spawn can reach 40 -> 18 (the sealed east train
roof); areas blocked at every round start 9 -> 0.

- Regenerated, and sliver areas merged into their neighbors on the
  same floor.
- Links the player hull cannot cross are cut: six walk links ending
  against a wall, a prop or a long drop, links across railings, and
  platform-edge drops outside the barrier rail's opening.
- Areas split or trimmed around six props bots stood against, and
  one spot by the west ladder's top where a player cannot stand cut
  out.
- The 9 areas blocked at round start are removed or split.
- The area through the breakable grate by the south glass pane is
  removed: the grate is intact at round start and bots do not shoot
  it open.
- Areas under the parked pilot car's body are removed, and the track
  bed areas stop half a hull short of its nose. The car is chamfered
  towards the nose; the floor beside it keeps one area on each side
  (master's 625 and 626), linked with the track bed to the north
  only, without master's climbs out of those narrow pockets.
- Ladder records as on master, climbed and descended from both side
  landings.
- Re-analyzed in game after the edits.
Renumbers area ids only, so an id-keyed diff against master reads
sensibly: 514 of the 518 areas carry the id of the master area they
match, including the two pocket floors beside the pilot car (625,
626); the diff shows 4 added / 229 removed areas. Geometry,
connections, attributes and the analyzed visibility data are
unchanged (verified topology-identical).
An outside review of this mesh found walk links that run one way
only and a climb whose drop back was cut. Each one-way pair was
swept with a player hull in both directions by the engine's hull
audit:

- Three one-way links ended in 20 u squares inside ticket machines,
  where no player hull fits: delete the squares. Cut the link
  through the vending machine near (-270, -560), one-way on master.
- The track bed beside the east platform near (120, 1070) was one
  area along both the barrier rails and the opening at their north
  end, so its climb to the platform crossed the rails and the drop
  back had been cut. Split it at the rails' end; the north piece is
  linked both ways with the platform through the opening.

Beyond the review, from the same audit: delete two more 20 u
squares inside a bench and a barrier, and the 20 u top of the bus
stop kiosk near (-110, -790), reached only by 80 u climbs nothing
can make.

Existing areas keep their ids; the track bed's north piece is new.
Re-analyzed in game (same graph, fresh visibility).
@sunzenshen
sunzenshen requested a review from sunmachine October 9, 2026 02:50
@sunzenshen
sunzenshen marked this pull request as ready for review October 9, 2026 04:49
@sunzenshen
sunzenshen merged commit 16ebb18 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