Skip to content

fix(webwalker): traverse far gates/doors and recover from smoothed-path dead-ends#1792

Open
oversized93 wants to merge 1 commit into
chsami:developmentfrom
oversized93:fix/webwalker-gate-traversal
Open

fix(webwalker): traverse far gates/doors and recover from smoothed-path dead-ends#1792
oversized93 wants to merge 1 commit into
chsami:developmentfrom
oversized93:fix/webwalker-gate-traversal

Conversation

@oversized93

Copy link
Copy Markdown
Contributor

Summary

Two related robustness fixes for the web walker (Rs2Walker), both reproduced and verified live in-game on a fenced gate route, plus unit tests. Both bugs share one root: the walker trusted a geometric shortcut over the actual route.

Bug 1 — stuck behind a far gate/door

Clicking a gate/door several tiles away makes the OSRS server walk the player all the way there and open it in one action. The walker was (a) firing recovery/minimap clicks that cancelled that walk-to-open, and (b) calling markStationaryDoorOpened(...) on a non-traversal, suppressing re-interaction for STATIONARY_DOOR_SUPPRESS_MS (10s) — so the player parked against a still-closed gate and never retried.

Fix: a distance-scaled walking-to-door state. While active it keeps that door interactable (overrides the stationary-opened suppression for it) and yields recovery clicks until the player arrives or a deadline / no-progress timeout elapses. The door is only suppressed on actual traversal; the state self-clears on traversal, timeout, or route change.

Bug 2 — "player just doesn't move" → idle logout

The smoothed walkable path can dead-end against a barrier that must be crossed from the far side (e.g. a closed gate). The unreachable-tile recovery only scanned 5 tiles for a tile Euclidean-closer to the target, which can't follow the winding route to the crossing — so the walker livelocked (tile-unreachable-near-player + stall_recalc indefinitely) until the character idle-logged-out.

Fix: raw-path recovery. When the smoothed next tile is unreachable and there's no openable obstacle nearby, fall back to the raw path (findFurthestReachableRawPathPoint) and walk to the furthest reachable raw-path tile — advancing the player to the actual crossing tile, where existing door handling opens it.

Verification

  • Live on a closed fenced gate: the walk now logs unreachable-raw-path-recovery ×2 → gate opens → arrives, with tile-unreachable-near-player = 0 and stall_recalc = 0 (previously ~16s of thrash / livelock to logout).
  • Unit: 65 walker tests pass, including new tests for the pure helpers walkToDoorDeadlineMs, walkToDoorWindowOpen, doorTileNearSegment, doorApproachDistance.

Scope note

This does not add a generic "give up → UNREACHABLE" loop-breaker, so a genuinely unreachable destination (no valid route at all) could still livelock — a separate, narrower follow-up.

🤖 Generated with Claude Code

…th dead-ends

Two related Rs2Walker navigation-robustness fixes:

1. Walking-to-door state. Clicking a gate/door several tiles away makes the
   OSRS server walk the player there and open it in one action. The walker was
   cancelling that approach with recovery/minimap clicks and then falsely
   marking the door "opened" (10s suppression via markStationaryDoorOpened on a
   non-traversal), stranding the player against a closed gate with no retry. A
   distance-scaled "walking to door" state now keeps the door interactable and
   yields recovery clicks until the player arrives (or a deadline/no-progress
   timeout elapses); the door is only suppressed on actual traversal.

2. Raw-path recovery for unreachable tiles. The smoothed walkable path can
   dead-end against a barrier that must be crossed from the far side (e.g. a
   closed gate). The unreachable-tile recovery only scanned 5 tiles for a
   Euclidean-closer-to-target tile, which cannot follow the winding route to the
   crossing, so the walker livelocked (tile-unreachable-near-player +
   stall_recalc indefinitely) until the character idle-logged-out. It now falls
   back to the raw path (findFurthestReachableRawPathPoint) to advance to the
   actual crossing tile, where existing door handling opens it.

Adds unit tests for the new pure helpers (walkToDoorDeadlineMs,
walkToDoorWindowOpen, doorTileNearSegment, doorApproachDistance).

Verified live in-game on a fenced gate route; 65 walker unit tests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Rs2Walker now implements a "walking-to-door" state that activates when the player clicks a gate or door multiple tiles away. While in this state, the walker suppresses recovery and minimap clicks that would cancel walk-to-open, instead yielding until the door edge resolves or movement stops. The walker detects eligible doors by computing approach distance and entering the state via markWalkingToDoor(). Door-suppression helpers are updated to avoid hiding the currently-walked target. Unreachable-path recovery yields if the state is active and adds a raw-path fallback. The state clears on traversal, timeout, or route teardown. Comprehensive unit tests verify deadline scaling, window predicates, door-nearness matching, and approach distance calculations.

Possibly related PRs

  • chsami/Microbot#1419: Adjusts imposter-object filtering in Rs2Walker's handleDoors logic alongside main PR's walk-to-door state and door suppression.
  • chsami/Microbot#1775: Modifies Rs2Walker's door probing resolution to skip catalog-backed transport segments, overlapping with main PR's door probing and suppression changes.
  • chsami/Microbot#1763: Refactors door detection and interaction helpers and near-segment probing, affecting the same code paths modified for walk-to-door state machine integration.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 31.03% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes both main changes: fixing far gate/door traversal and recovery from smoothed-path dead-ends, matching the changeset's core objectives.
Description check ✅ Passed The description comprehensively covers both bugs, their fixes, and verification approach—directly aligned with the Rs2Walker changes and unit tests in the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ast-grep (0.43.0)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java`:
- Around line 5668-5671: The code only calls clearWalkingToDoor() when target ==
null, leaving stale walkingToDoor* state after reroutes; update the reroute code
paths (e.g. inside recalculatePath() and applyWalkerDestination(...) or wherever
the route/target is rebuilt) to call clearWalkingToDoor() whenever the active
target/route is replaced (including non-null reroutes) so processWalk() cannot
act on an old door; ensure the call happens immediately after the new
route/target is set (or before switching) so walkingToDoor* state is always
cleared on any route change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: ecd445ca-af5f-4cdc-b26a-13859a3ff345

📥 Commits

Reviewing files that changed from the base of the PR and between 9df144c and affb6b2.

📒 Files selected for processing (2)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java
  • runelite-client/src/test/java/net/runelite/client/plugins/microbot/util/walker/Rs2WalkerUnitTest.java

Comment on lines 5668 to 5671
if (target == null) {
logRouteClear(clearReasonWhenNull);
clearWalkingToDoor();
synchronized (ShortestPathPlugin.getPathfinderMutex()) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Clear walkingToDoor* on reroutes, not only on full teardown.

clearWalkingToDoor() only runs when target == null, but recalculatePath() / applyWalkerDestination(...) rebuild the route with a non-null target. That leaves the previous door state alive on the new route, so processWalk() can keep taking the "walking-to-door-yield" branch against a door that's no longer part of the active path.

Suggested fix
 private static void applyWalkerDestination(WorldPoint target) {
+    clearWalkingToDoor();
     Rs2WalkerLifecycleRuntime.applyWalkerDestination(target);
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java`
around lines 5668 - 5671, The code only calls clearWalkingToDoor() when target
== null, leaving stale walkingToDoor* state after reroutes; update the reroute
code paths (e.g. inside recalculatePath() and applyWalkerDestination(...) or
wherever the route/target is rebuilt) to call clearWalkingToDoor() whenever the
active target/route is replaced (including non-null reroutes) so processWalk()
cannot act on an old door; ensure the call happens immediately after the new
route/target is set (or before switching) so walkingToDoor* state is always
cleared on any route change.

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