Skip to content

ntre_isolation_ctg: navmesh rework - #144

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

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

Conversation

@sunzenshen

@sunzenshen sunzenshen commented Sep 27, 2026 •

Copy link
Copy Markdown
Contributor

ntre_isolation_ctg: navmesh rework

One file, neo/maps/nav/ntre_isolation_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 map has no nav ladders and no NAV_MESH_PRECISE, NAV_MESH_CLIFF or NAV_MESH_AVOID marks, and the mesh beats master on upstream bot code (see below).

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

Pending before review:

  • Nothing: ready for review.

At a glance

master this PR
nav areas 6347 5667
file size 51,021,013 bytes 39,983,495 bytes (-22 %)
areas no spawn or objective can reach 169 (16 pockets) 9 (3 pockets), drop-only tops (see "Review fixes")
areas no spawn reaches by links a Recon bot plans (68 u) 183 9
one-way walk links between level floor 1 0
areas the engine blocks at every round start 86 0
bot stuck events a match (see below) 46.8 12.9

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 lost drop back, climb-only tops, and areas inside walls and clips (see below).

1. What changed

  • Areas the engine blocks at round start. CNavArea::UpdateBlocked finds a solid at the center of 86 of master's areas on every restart. The path cost then refuses them for the whole round, so bots plan routes they cannot take. They are cut around the obstacle or dropped.
  • Hand edits where test bots got stuck:
    • the hut eave, where the crouch area now starts on the approach
    • a drop across a displacement cut
  • Unreachable floor is removed. A roof region of 67 areas and several raised tops are linked out only by drops of 74-175 u, above every class's crouch jump (Recon 72 u), and the map has no climbable brush. Two small tops a Recon can climb onto (+58 u, +61 u) get a one-way climb link instead.
  • 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

5682 of the 5685 areas carry the id of the master area they match. Kept ids that sit more than 64 u from their master location drop from 38 to 16, and an id-keyed diff shows 3 added / 665 removed areas. Geometry, connections, attributes and the analysis data are unchanged by this step.

3. Review fixes

An outside review of the mesh listed walk links that run one way only and floor the body called reachable that only climbs no bot plans lead to. 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 (34, and one from master). Five pairs blocked both ways are cut both ways (walls, a bamboo clump). The missing direction of twenty pairs a hull can cross is restored; most are hut doorways 32-40 u wide, where one to four of the audit's six lanes are clear. Five half cuts ended in 25 u areas inside clip brushes and walls, where every stand sample is blocked; they are removed. One of them, by a fence near (-1160, 812), had 14 stuck events in 32 earlier matches on this mesh, bots pressed against the fence's clip.
  • The step onto the roof near (290, 2875) from the slope below, the roof's only way in, was one-way: it is made two-way (the audit reads the way down blocked on the displacement slope, its known false read there; the terrain meets the roof's height). The reverse of a 16 u step down a slope near (1036, -1600), one-way on master, is restored.
  • A climb whose drop back was cut, onto a wall-top strip near (-3345, -888): the drop back is restored.
  • Floor reached only by climbs no bot plans (12 areas in 4 pockets). A flood fill of the map's collision from each, with jumps of up to 40 and 62 u:
    • nothing gets on: the pocket near (-3333, -729) (3 areas, 3 hiding spots, 80-84 u up) is removed
    • a player gets on only with a full-height (62 u) jump: the climbs into them (85-124 u) are cut, and they stay as floor bots can drop off but plan no path onto: near (-625, -938) (2 areas), (-2427, -1631) (6 areas) and (-1338, -1450) (1 area)

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

  • Ten more areas no player hull fits in, each with 92-100 % of the audit's stand samples blocked: in clip brushes and walls, a sloped wall and a bamboo clump. One, a 12 u square near (-2080, -256), had 6 stuck events in those matches, bots pressed against it.
  • Six pairs blocked both ways, by walls and clips, are cut; bots crossed them at most twice.
  • Kept: a link near (562, 2450) with every lane read blocked that bots cross (7 times in 32 matches); 92 links on displacement slopes, stairs and gaps the audit cannot judge.

Every kept area keeps its id. Re-analyzed in game.

How it was tested

  • Reachability:
    • every spawn can reach every other spawn
    • every objective is reachable from a spawn
    • every area is reachable from a spawn or an objective except the three drop-only pockets above (9 areas)
    • 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 9; Assault and Support do not reach 127, raised floor behind climbs of 48-66 u
    • no area a class can enter and not leave; no one-way link between level floor
    • the mesh is one connected piece apart from those pockets
  • Engine hull audit of the final mesh: no linked area a player hull cannot stand in. BLOCKED_LINKS map=ntre_isolation_ctg level_pairs=14532 oneway=0 keep=0 cut=1 area=0 check=92 entity=0: the cut is the link bots cross (above), the checks the slope, stair and gap links
  • Master against this mesh, same bot code. Byte-identical copies of the map, one carrying each .nav, run interleaved. CTG with the ghost pinned at the map's one ghost spawn, 16 matches, 30 bots, default weapon damage. The count excludes stuck events in the spawn crush at round start and the weapon-scavenging behavior.
    • stuck events 46.8 -> 12.9 a match (paired x0.26, 95 % interval [0.16, 0.41], 15 of 16 pairs down)
    • FAIL_NO_PATH_EXISTS move failures 10.2 -> 7.8 a match
    • kills 48.9 -> 48.8 a match
    • no fall deaths in either
  • The review fixes against commit 2, the same design (the ghost at the map's one spawn, 24 pairs), on upstream master plus #2176 and #2186: stuck events 17.8 -> 10.5 a match (paired x0.63, 95 % interval [0.48, 0.83], 18 down / 6 up); at the edited spots 67 -> 14 (the 12 u clip square near (-2080, -256) and the area beside it: 66 -> 0); kills 48.4 -> 50.3; ghost captures 7 -> 6 of 48 rounds; no fall deaths; 99 % of kills between bots in different areas on both. Every match reached match end with 0 asserts and no crash.
  • Bots still see and shoot across the mesh. 99 % of kills are between bots in different nav areas and 97 % in non-adjacent ones, against 99 % / 98 % on master (kill distance median 882 u against 817 u).

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.

  • The ghost is placed on the area 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". It 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.
  • A pickup at the spot means bots can reach the area. Bots run their normal CTG errand to the ghost. A pickup is the clear signal; a bot coming within 160 u is a weaker one. The position of the first pickup is checked, because a ghost on a low raised top can be taken from the floor below, and a ghost on a narrow ledge can fall off it.
  • A miss only counts with a control. One run is a screen. A spot bots miss is re-run 6 times beside a control spot on the same map that bots are known to reach, in the same batch. Without the control, "not reachable" and "the probe did not work" look the same.
  • Weapon damage is turned down for these probes, so bots move instead of dying in fights on the way.
  • Master's mesh can run beside this one. The game loads a .nav by map name, so the harness copies the .bsp byte for byte under a second name (for example ntre_oilstainb_ctg) that loads its own .nav. The same pin then runs on both meshes in one batch. The copy only carries the second mesh; the ghost comes from the cvar.

On this map. On an older revision, the largest floor region removed from master's mesh was probed on both meshes, 12 runs each: 4/12 pickups (10/12 reached) on the reworked mesh against 3/12 (7/12) on master's. A first 4-run screen had shown the opposite (1/4 against 3/4); it did not hold at 12 runs.

One file. Against master: 6347 -> 5685 areas, 51,021,013 -> 40,250,206
bytes; 169 areas no spawn or objective reaches (16 pockets) -> 0; 86
areas the engine blocks at every round start -> 0.

- Areas CNavArea::UpdateBlocked finds solid at their center at round
  start are cut around the obstacle or dropped.
- Hand edits where test bots got stuck: the hut eave (a crouch strip on
  its approach) and a drop across a displacement cut.
- Unreachable floor is removed: a roof region and raised tops linked
  out only by drops of 74-175 u; two small tops get a Recon climb.
- Re-analyzed in game after the edits.
Renumbers area ids only, so an id-keyed diff against master reads
sensibly: 5682 of the 5685 areas carry the id of the master area they
match, kept ids that moved more than 64 u from their master location
drop from 38 to 16, and the diff shows 3 added / 665 removed areas.
Geometry, connections, attributes and the analyzed visibility data are
unchanged (verified topology-identical).

@sunzenshen sunzenshen left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image

Deleted the roof that bots would be unlikely to climb:

Image

(Along with yet more railing deletions)

@sunzenshen
sunzenshen marked this pull request as ready for review September 28, 2026 08:07
An outside review of this mesh found walk links that run one way
only, a climb 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 five pairs blocked both ways; restore the
  missing direction of the twenty pairs a hull can cross, most of
  them hut doorways 32-40 u wide. Delete five 25 u areas the half
  cuts ended in that sit inside clip brushes and walls, among them
  one by a fence near (-1160, 812) bots pressed against.
- Make the step onto the roof near (290, 2875), its only way in,
  two-way, and restore the reverse of a 16 u step on a slope near
  (1036, -1600), one-way on master.
- Restore the drop from a wall-top strip near (-3345, -888) whose
  climb was kept.
- Climb-only tops: delete the pocket nothing can get onto near
  (-3333, -729); cut the climbs of 80 u or more into three pockets
  a player reaches only with a full-height jump, and keep them as
  drop-only floor.

Beyond the review, from the same audit: delete ten more areas no
player hull fits in (clip brushes, walls, a sloped wall, bamboo),
and cut six pairs blocked both ways that bots never or seldom cross.

Existing areas keep their ids. Re-analyzed in game (same graph,
fresh visibility).

@sunmachine sunmachine left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Straight-forward, no issues.

@sunmachine
sunmachine requested a review from a team October 14, 2026 02:24
@sunzenshen
sunzenshen merged commit 4425a81 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