Skip to content

Look along the ledge for a drop-down's clear column - #2164

Closed
sunzenshen wants to merge 1 commit into
NeotokyoRebuild:masterfrom
sunzenshen:bot-drop-search-along-ledge
Closed

sunzenshen wants to merge 1 commit into
NeotokyoRebuild:masterfrom
sunzenshen:bot-drop-search-along-ledge

Conversation

@sunzenshen

@sunzenshen sunzenshen commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Description

Look along the ledge for a drop-down's clear column

Background

This came out of the navmesh work on ntre_sentinel_jgr. Bots whose path dropped through a roof hatch walked past the hatch onto solid floor, pressed into what lay beyond until the stuck monitor fired, and then got the same path again: 44.9 stuck events a match at the hatch. The same happens wherever a drop's opening is off to one side of where a path crosses the ledge, such as a gap in a railing, so it is fixed in the path code rather than in one mesh.

Path::PostProcess turns a walk link onto a lower area into a DROP_DOWN. It does this by pushing the crossing point forward (10 u steps, up to two hull widths) until a hull traced straight down is clear.

It only looks straight ahead of where the path crosses the edge. When the opening below is off to one side of that line (a hatch in a floor, a gap in a railing), no column is clear. The loop still sets the drop point at the last, unchecked position: two hull widths out, on solid floor. The bot walks there, stands on the floor it was meant to fall through, and presses into whatever is beyond until the stuck monitor fires; the next path puts it back.

When the straight search finds nothing, the same search is now tried at offsets along the portal: either side of the crossing, nearest first, staying inside the portal. The path crosses at the first clear column. Paths whose straight search succeeds are unchanged. One file, NextBotPath.cpp, +42 inside #ifdef NEO.

Dependencies and status

Needs (code PRs this one depends on):

  • None.

Helped by:

  • None.

Pending before review:

  • A match comparison on upstream master with and without this PR alone at the roof hatch, on master's ntre_sentinel_jgr mesh (so far measured as a research patch).
  • A cold review read (none recorded yet).

Navmesh PRs that rely on this

None of the open navmesh PRs needs this: its case, the roof hatch, is on ntre_sentinel_jgr, whose navmesh PR NeotokyoRebuild/neoAssets#165 fixes the hatch in the mesh itself. It is still worth merging on its own: the defect can happen at any drop on any map, and the 10-map check below shows no harm.

Evidence

  • The hatch case: ntre_sentinel_jgr roof hatch, on a mesh whose drop link spans the whole edge. Stuck events at the hatch went from 44.9 to 2.1 a match, and bot stuck events overall x0.55 [0.42, 0.71] over 36 paired matches.
  • Do-no-harm, 10 maps on current meshes, 258 paired matches:
    • stuck events x0.87 [0.78, 0.98], mostly unrelated heavy tails
    • kills x1.01 [0.99, 1.04]
    • stuck events at the changed drops about 0 in both arms

Risk

Low. Only paths whose straight-ahead drop search already failed are affected. If no column along the portal is clear either, behavior is as before.

Toolchain

  • Linux GCC Distro Native (Linux Mint 22.3, GCC 13.3.0)

Linked Issues

@sunzenshen
sunzenshen force-pushed the bot-drop-search-along-ledge branch 2 times, most recently from 4d32adc to 30985fc Compare September 26, 2026 12:04
sunzenshen added a commit to sunzenshen/neo that referenced this pull request Oct 1, 2026
Path::PostProcess turns a walk link onto a lower area into a DROP_DOWN by
pushing the crossing point forward, 10 u at a time up to two hull widths,
until a hull traced straight down is clear. It only looks straight ahead
of where the path crosses the edge. When the opening below is off to one
side of that line - a hatch in a floor, a gap in a railing - no column is
clear, and the loop still sets the drop point at the last, unchecked
position: two hull widths out, on solid floor. The bot walks there, stands
on the floor it was meant to fall through, and presses into whatever is
beyond until the stuck monitor fires; the next path puts it back.

When the straight search finds nothing, try the same search at offsets
along the portal (either side of the crossing, nearest first, staying
inside the portal) and cross at the first clear column. Paths whose
straight search succeeds are unchanged, and if no column is clear
anywhere along the portal the old behavior stands.

Found on ntre_sentinel_jgr: each freight elevator's roof has a 51 x 55 u
hatch, and the roof's drop link into the shaft runs the whole 100 u edge.
Measured there (the shipped mesh at the time, bot matches, paired per
spawn pin, 36 pairs): stuck events at the hatches 44.9 -> 2.1 a match,
OnStuck x0.55 [0.42, 0.71], 26 down / 10 up.

Across ten maps on the current meshes (apparatus, dusk, ghost, oilstain,
sentinel_ctg, skyline, terminal, transit, yard, and sentinel_jgr with its
hatches since fixed in the mesh; 258 pairs over two batches) the search
fires where drops cross off-axis openings and nothing gets worse: OnStuck
x0.87 [0.78, 0.98], kills x1.01 [0.99, 1.04], every match clean. Stuck
events at the drops it changed stay near zero in both arms, so that
cross-map figure is mostly noise from unrelated heavy tails; the fix's
measured effect is the hatch case above.
@sunzenshen

Copy link
Copy Markdown
Contributor Author

Can be solved with a navmesh edit.

@sunzenshen sunzenshen closed this Oct 9, 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.

1 participant