Skip to content

fix(shortestpath): TransportNode cost double-count + overflow; remove MoA audit temp plugin#1751

Open
runsonmypc wants to merge 4 commits intochsami:developmentfrom
runsonmypc:fix/transportnode-cost-overflow
Open

fix(shortestpath): TransportNode cost double-count + overflow; remove MoA audit temp plugin#1751
runsonmypc wants to merge 4 commits intochsami:developmentfrom
runsonmypc:fix/transportnode-cost-overflow

Conversation

@runsonmypc
Copy link
Copy Markdown
Contributor

@runsonmypc runsonmypc commented Apr 19, 2026

Summary

Three bundled changes on one branch to avoid back-to-back Rs2Walker baseline-regen conflicts:

1. TransportNode cost fix (main)

  • TransportNode was stamping chained-transport costs at 2 * previous.cost + travelTime instead of previous.cost + travelTime, tripling the effective cost of any agility shortcut (or other non-teleport transport) reached via a teleport. Invisible on first-hop TransportNodes (since previous.cost == 0 at the start node), which is why it was latent for a long time.
  • Concrete symptom: getNearestBank() picked Shilo Village (actual cost 55) over Nemus Retreat (reported cost 74, true cost 40 = MoA teleport 34 + east broken-wall climb 3 + 3-tile walk). The shortcut's TransportNode was getting g=71 instead of g=37.
  • Secondary fix: the new path also sidesteps an overflow bug for plane-crossing transports with travelTime=0 (e.g. Slayer Tower chains). Node.cost falls back to WorldPointUtil.distanceBetween, which returns Integer.MAX_VALUE across planes, and previousCost + Integer.MAX_VALUE wraps into Integer.MIN_VALUE-territory, making those transports look free. Passing the absolute cost directly through Node(int packed, Node prev, int cost) never consults distanceBetween.

2. Remove MoA audit temp debug plugin

MoaAuditPlugin + its runMoaAudit / closeMoaWidgetIfOpen helpers in Rs2Walker were supposed to stay on a side branch and got merged by accident via #1750. Pure deletion — plugin was only ever enabled manually and wrote to logs. Supersedes #1752.

3. Leftover /simplify findings from PR #1750 review

  • CollisionMap MoA debug log now reports actual per-edge costs instead of hardcoded + 4.
  • Rs2Walker.findMoaWidget uses token-set membership instead of substring match — avoids false positives like token log hitting a hypothetical logstrum label.
  • Demoted two [MoA] log.info calls to log.debug (entry + destination selection) — noisy in normal operation.
  • Rs2Walker.collectMoaChildren helper inlined into its two callers so the client-thread guardrail scanner sees the runOnClientThreadOptional wrapper.
  • Regenerated client-thread-guardrail-baseline.txt — Rs2Walker edits shifted pre-existing lambda indices; no new offenders introduced.

Diagnosis trail for the TransportNode bug

  1. Instrumented Pathfinder/CollisionMap with per-pop logs → shortcut dest (1389, 3309, 0) was appearing in pending with g=71, not the expected g=37.
  2. Traced TransportNode constructor chain → static cost(previous, travelTime) computes previous.cost + travelTime, passes that as wait to Node(WorldPoint, Node, int), which adds previous.cost again via its instance cost() method.
  3. Initial fix (just super(point, previous, travelTime)) compiled fine but blew up on plane-crossing transports with duration 0 — the log showed g=-2147483615 for the Slayer Tower chain tile, which led to the absolute-cost constructor swap.

Verification (limited — only on a League 6 account)

  • Before: go to nearest bank from Ardougne picks Shilo Village, Nemus bank target shows cost 74 when reachable via MoA east + broken-wall shortcut.
  • After: same click picks Nemus Retreat, pathfinder reaches (1386, 3309, 0) at cost=40, walker actually selects Map of Alacrity: Varlamore - Nemus retreat (east) and teleports.
  • Plane-crossing transports (Slayer Tower chain (3421, 3550, 0)↔(3421, 3550, 1)) no longer produce overflowed Integer.MIN_VALUE-ish costs.

Only manually tested on one League 6 account (all MoA regions unlocked). Haven't confirmed main-game behavior; the TransportNode change is generic enough that other transport->transport chains (boat-after-teleport, shortcut-after-teleport) should now cost correctly too — would appreciate a second set of eyes on that.

Test plan

  • ./gradlew :client:runTest, log in, MoA in inventory, click "go to nearest bank" from mainland → expect Nemus Retreat to be chosen and the walker to fire Map of Alacrity: Varlamore - Nemus retreat (east).
  • Walk to a destination that requires a non-MoA teleport followed by an agility shortcut (any region) → path cost should reflect teleport + shortcut, not teleport + 2x shortcut.
  • Walk across Slayer Tower or similar plane-crossing chain → cost remains positive and sensible (no overflow).
  • Smoke test non-teleport pathfinding (no transports involved) → unchanged, first-hop TransportNodes also unchanged since previous.cost == 0.
  • Confirm MoaAuditPlugin is gone from the plugin list.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 19, 2026

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: e1ee034a-9838-435d-9c2d-827ebc7d226a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

This PR adds support for seasonal League transports, specifically the Map of Alacrity mechanic, to the shortest path pathfinder. Changes span configuration updates, transport type classification, pathfinding logic, and interactive transport handling. The implementation includes marking seasonal transports as teleport-like, tracking Map of Alacrity transports with cost calculations, filtering based on destination availability and configuration, and adding comprehensive widget-based interaction for the Map of Alacrity picker in Rs2Walker with session blacklist management for locked destinations and regions.

Possibly related PRs

  • Feat/mushtree and digsite transport #1672: Adds special-case transport handling for Magic Mushtree to Rs2Walker, following a similar pattern of implementing a dedicated handler for a new transport type.
  • Rs2Walker handleFairyRings improvements #1496: Modifies transport framework and pathfinding infrastructure including fairy-ring improvements, providing foundational transport-handling changes.
  • 2.0.6 #1511: Extends Rs2Walker transport handling by adding PoH transport support and related session state management, paralleling the session blacklist approach used for Map of Alacrity.
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 36.84% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The PR title accurately describes the primary fixes: TransportNode cost double-counting and overflow issues, with a secondary mention of removing an audit plugin component.
Description check ✅ Passed The PR description comprehensively covers the changeset: a critical TransportNode cost calculation fix, removal of accidentally-merged debug code, and related simplifications from prior review.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java (1)

2593-2601: Log-level inconsistency in the MoA path.

Entry logging at Line 2595 and the destination-selection log at Line 2712 are log.info, while the surrounding MoA diagnostics (region resolution, hotkey press, parsing) are log.debug. Since handleSeasonalTransport is called speculatively for every candidate transport during a walk, log.info("[MoA] entry: ...") will fire even for non-MoA seasonal entries (early-returned at Line 2598-2601) and pollute the normal walk log. Demote both to debug to match the rest of this handler.

As per coding guidelines: "Keep logging minimal; avoid PII/session identifiers and respect existing log levels/patterns".

Proposed diff
-        log.info("[MoA] entry: displayInfo='{}'", displayInfo);
+        log.debug("[MoA] entry: displayInfo='{}'", displayInfo);
-        log.info("[MoA] selecting destination '{}' (text='{}')", shortName, destText);
+        log.debug("[MoA] selecting destination '{}' (text='{}')", shortName, destText);

Also applies to: 2710-2714

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java`
around lines 2593 - 2601, The entry and destination-selection log calls in
handleSeasonalTransport are using log.info and should be demoted to log.debug to
match surrounding MoA diagnostics and avoid noisy logs; update the log
invocation that currently logs "[MoA] entry: displayInfo='{}'" and the later
"[MoA] destination selected ..." (the destination-selection log in the same
method) to use log.debug instead of log.info so all MoA-related diagnostics
remain at debug level.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java`:
- Around line 2593-2601: The entry and destination-selection log calls in
handleSeasonalTransport are using log.info and should be demoted to log.debug to
match surrounding MoA diagnostics and avoid noisy logs; update the log
invocation that currently logs "[MoA] entry: displayInfo='{}'" and the later
"[MoA] destination selected ..." (the destination-selection log in the same
method) to use log.debug instead of log.info so all MoA-related diagnostics
remain at debug level.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 1a6b02e9-76a5-431d-b556-024581d6e89b

📥 Commits

Reviewing files that changed from the base of the PR and between a910d88 and 770d57f.

⛔ Files ignored due to path filters (2)
  • runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/agility_shortcuts.tsv is excluded by !**/*.tsv
  • runelite-client/src/main/resources/net/runelite/client/plugins/microbot/shortestpath/seasonal_transports.tsv is excluded by !**/*.tsv
📒 Files selected for processing (6)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/ShortestPathConfig.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/TransportType.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/CollisionMap.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/PathfinderConfig.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/pathfinder/TransportNode.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java

@runsonmypc runsonmypc force-pushed the fix/transportnode-cost-overflow branch 2 times, most recently from 7800f54 to 58b11f5 Compare April 19, 2026 18:44
@runsonmypc runsonmypc changed the title fix(shortestpath): TransportNode cost double-count + overflow fix(shortestpath): TransportNode cost double-count + overflow; remove MoA audit temp plugin Apr 19, 2026
@runsonmypc runsonmypc marked this pull request as draft April 19, 2026 19:11
@runsonmypc runsonmypc marked this pull request as ready for review April 19, 2026 19:37
@chsami
Copy link
Copy Markdown
Owner

chsami commented Apr 19, 2026

@copilot resolve the merge conflicts in this pull request

runsonmypc and others added 4 commits April 19, 2026 15:56
TransportNode's constructor was pre-adding previous.cost to travelTime,
then passing that sum as `wait` to Node(WorldPoint, Node, int) — which
re-adds previous.cost. The upshot: any TransportNode chained off another
TransportNode had its cost double-counted. This only surfaced once a
real transport->transport chain became the only viable path (e.g. Map
of Alacrity -> agility shortcut), which is why it stayed latent.

Concrete impact: "go to nearest bank" from outside Nemus retreat picked
Shilo (cost 55) over Nemus (observed 74, should be 40 = 34 MoA + 3
climb + 3 walk). The shortcut's TransportNode was being stamped at g=71
instead of g=37, tripling the cost of every agility-shortcut edge
downstream of a teleport.

Passing the final absolute cost through Node(int, Node, int cost)
instead of the wait-based constructor also sidesteps a second bug: for
plane-crossing transports with travelTime=0 (e.g. Slayer Tower chains),
the wait<=0 branch of Node.cost falls back to
WorldPointUtil.distanceBetween, which returns Integer.MAX_VALUE across
planes — overflowing previousCost + distance into Integer.MIN_VALUE
territory and making those transports look "free". The absolute-cost
path never consults distanceBetween.

Also in this pass:
  - CollisionMap [MoA] debug log: report actual per-transport costs
    instead of the hardcoded `+ 4` (all MoA durations happened to be
    4, but the log was incidental to the value, not tracking it).
  - Rs2Walker.findMoaWidget: token-set membership instead of
    substring match — avoids false positives like token "log"
    matching a hypothetical "logstrum" widget label.
MoaAuditPlugin and the runMoaAudit()/closeMoaWidgetIfOpen() helpers in
Rs2Walker were intended as a temporary offline landing-coord audit tool
(self-labelled [TEMP] "Delete when done") and were supposed to be held
on a separate debug branch, not merged. They slipped into upstream with
PR chsami#1750 because the amend that removed them locally was never pushed
before the PR was merged.

Scope: delete-only. No functional changes to MoA handling —
handleSeasonalTransport, lockedMoaRegions, and blacklistedMoaDestinations
are untouched.
…d guardrail

- collectMoaChildren called getDynamicChildren/getNestedChildren/getStaticChildren
  directly; the static guardrail scanner can't follow through to the callers'
  runOnClientThreadOptional wrappers, so it flagged a new violation.
- Inlined the three child-array fetches into findMoaWidget and
  computeMoaHotkeyByIndex — they now happen inside the client-thread lambda
  where the scanner can see the wrapper.
- Regenerated client-thread-guardrail-baseline.txt: combined effect of the
  MoA edits and the audit-plugin removal shifted pre-existing Rs2Walker
  lambda indices, plus a few entries the old baseline was missing.
@runsonmypc runsonmypc force-pushed the fix/transportnode-cost-overflow branch from 58b11f5 to 1c6ded0 Compare April 19, 2026 19:57
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