Skip to content

Hotfix/webwalker fixes - #1837

Open
dylanreniers wants to merge 15 commits into
chsami:developmentfrom
dylanreniers:hotfix/webwalker-fixes
Open

dylanreniers wants to merge 15 commits into
chsami:developmentfrom
dylanreniers:hotfix/webwalker-fixes

Conversation

@dylanreniers

@dylanreniers dylanreniers commented Aug 12, 2026 •

Copy link
Copy Markdown

Applied fixes:

  1. Persistent Single-Thread Walk Task Execution (ShortestPathScript.java):
  • Eliminates thread restarts and pathfinder cancellations, keeping movement active on a single dedicated background thread.
  1. Fixing False Route Failures in Banked Walking (Rs2Walker.java):
  • Preserves active movement states (MOVING) when walking with banked transports, preventing self-cancellation.
  1. Humanized Run Energy Recovery (Rs2Player.java):
  • Waits for run energy to recover to a randomized threshold (15%–35%) before toggling run back on, eliminating robotic 1% toggles.
  1. Camera Settling for Door Interaction Accuracy (Rs2Walker.java):
  • Waits for camera movement to settle after turning towards off-screen doors before computing 3D canvas clickboxes, ensuring 100% click accuracy.
  1. Fast Miss Recovery & Reduced Door Wait (Rs2WalkerAwaits.java):
  • Detects stationary state after 1200ms (2 game ticks) on missed clicks and releases immediately for a fast retry, eliminating 5-second idle stalls.
  1. Realistic Physical Mouse Click Hold Duration (VirtualMouse.java):
  • Incorporates a 40–90ms hold duration between button press and release.
  1. Short-Distance 3D Scene Clicks (Rs2Walker.java):
  • Clicks directly on the 3D ground canvas when the destination is within 4 tiles (a couple of steps) and visible on screen, while preserving minimap navigation for longer journeys.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

The walking task now loops while logged in and processes target state changes and terminal walker states. Nearby reachable targets can use canvas clicks before minimap fallback. Mouse clicks include randomized press-release timing, and shape movement uses helper-selected points. Run-energy toggling uses randomized activation thresholds. Transport preparation, camera delays, direct-walk state handling, and door-await timings were updated.

Possibly related PRs

  • chsami/Microbot#1765: Overlaps in ShortestPathScript and Rs2Walker walking-loop, route-state, click, and transport behavior.
  • chsami/Microbot#1827: Overlaps in Rs2Walker and Rs2WalkerAwaits route handling and door-wait behavior.
  • chsami/Microbot#1811: Overlaps in Rs2Walker door interaction handling.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Title check ✅ Passed The title clearly identifies the pull request as a WebWalker fixes hotfix and matches the main changes.
Description check ✅ Passed The description directly explains the WebWalker, walking, mouse, run-energy, and door-interaction fixes.

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.

@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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/player/Rs2Player.java (1)

413-442: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

toggleRunEnergy javadoc no longer matches its return contract.

The javadoc states false is returned only "if the run energy toggle widget was not found." The new threshold check at line 433 also returns false when getRunEnergy() < nextRunEnergyThreshold, a case unrelated to the widget. A caller that treats false as "widget missing" per the documented contract cannot distinguish that from "deliberately not enabling run yet."

Update the javadoc to document the new early-return case.

📝 Proposed javadoc fix
     /**
      * Toggles the player's run energy on or off.
      *
      * `@param` toggle {`@code` true} to enable running, {`@code` false} to disable it.
-     * `@return` {`@code` true} if the toggle action was performed successfully or was already in the desired state,
-     *         {`@code` false} if the run energy toggle widget was not found.
+     * `@return` {`@code` true} if the toggle action was performed successfully or was already in the desired state,
+     *         {`@code` false} if the run energy toggle widget was not found, or (when {`@code` toggle} is
+     *         {`@code` true}) if run energy is below the currently randomized activation threshold.
      */
🤖 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/player/Rs2Player.java`
around lines 413 - 442, Update the javadoc for toggleRunEnergy(boolean) to
document that it also returns false when enabling is requested but
getRunEnergy() is below nextRunEnergyThreshold, in addition to the
missing-widget case. Keep the existing behavior and return conditions unchanged.
🤖 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/shortestpath/ShortestPathScript.java`:
- Around line 98-103: Update the banked-transport branch in the
ShortestPathScript walk-state flow to use the configured reached-distance source
instead of the hardcoded 10. Ensure Rs2Walker.walkWithBankedTransportsAndState
receives the same reachedDistanceOrDefault()-based value honored by
Rs2Walker.walkWithState(target), preserving consistent arrival thresholds across
both branches.

In
`@runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/door/Rs2WalkerAwaits.java`:
- Line 18: Update the boundary assertions in Rs2WalkerAwaitsTest for
shouldAcceptIdleDoorAwait to match DOOR_IDLE_ACCEPT_MIN_MS at 600 ms: treat 600
ms as rejected and 601 ms as accepted, preserving the strict elapsedMs >
threshold behavior.

---

Outside diff comments:
In
`@runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/player/Rs2Player.java`:
- Around line 413-442: Update the javadoc for toggleRunEnergy(boolean) to
document that it also returns false when enabling is requested but
getRunEnergy() is below nextRunEnergyThreshold, in addition to the
missing-widget case. Keep the existing behavior and return conditions unchanged.
🪄 Autofix

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 Plus

Run ID: b0d14e91-55b0-448e-9a65-d0c1c4378e5e

📥 Commits

Reviewing files that changed from the base of the PR and between 463c2c7 and 7cd1aaf.

📒 Files selected for processing (5)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/shortestpath/ShortestPathScript.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/mouse/VirtualMouse.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/player/Rs2Player.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/Rs2Walker.java
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/walker/door/Rs2WalkerAwaits.java

Comment on lines +98 to +103
WalkerState state;
if (config.walkWithBankedTransports()) {
state = Rs2Walker.walkWithBankedTransportsAndState(target, 10, false);
} else {
state = Rs2Walker.walkWithState(target);
}

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Banked-transport branch ignores the configured reached distance.

The banked-transport call hardcodes 10 for the distance argument. The non-banked branch instead calls Rs2Walker.walkWithState(target), which resolves to reachedDistanceOrDefault() and honors config.reachedDistance(). As a result, a walk driven through this loop uses a different arrival threshold depending on config.walkWithBankedTransports(), and a user-configured reached distance is silently dropped for every banked-transport walk.

Use the same distance source for both branches.

🔧 Proposed fix to use a consistent distance source
                     WalkerState state;
                     if (config.walkWithBankedTransports()) {
-                        state = Rs2Walker.walkWithBankedTransportsAndState(target, 10, false);
+                        state = Rs2Walker.walkWithBankedTransportsAndState(target, config.reachedDistance(), false);
                     } else {
                         state = Rs2Walker.walkWithState(target);
                     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
WalkerState state;
if (config.walkWithBankedTransports()) {
state = Rs2Walker.walkWithBankedTransportsAndState(target, 10, false);
} else {
state = Rs2Walker.walkWithState(target);
}
WalkerState state;
if (config.walkWithBankedTransports()) {
state = Rs2Walker.walkWithBankedTransportsAndState(target, config.reachedDistance(), false);
} else {
state = Rs2Walker.walkWithState(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/shortestpath/ShortestPathScript.java`
around lines 98 - 103, Update the banked-transport branch in the
ShortestPathScript walk-state flow to use the configured reached-distance source
instead of the hardcoded 10. Ensure Rs2Walker.walkWithBankedTransportsAndState
receives the same reachedDistanceOrDefault()-based value honored by
Rs2Walker.walkWithState(target), preserving consistent arrival thresholds across
both branches.

private static final int DOOR_TRAVERSAL_PROGRESS_WAIT_MS = 1200;
/** Stationary and not animating for longer than this, with the edge unresolved, means the click didn't land. */
private static final long DOOR_IDLE_ACCEPT_MIN_MS = 1_200L;
private static final long DOOR_IDLE_ACCEPT_MIN_MS = 600L;

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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Align the idle-await test boundary with the new threshold.

Line 18 sets DOOR_IDLE_ACCEPT_MIN_MS to 600 ms, but Rs2WalkerAwaitsTest.java still expects 1200 ms and 800 ms to be rejected. Because shouldAcceptIdleDoorAwait uses elapsedMs > DOOR_IDLE_ACCEPT_MIN_MS, those assertions now fail. Update the test to use 600/601 ms, or restore the constant to 1200 ms if that contract is required.

Proposed test boundary update
-assertFalse(Rs2WalkerAwaits.shouldAcceptIdleDoorAwait(false, false, 1200L, false));
-assertTrue(Rs2WalkerAwaits.shouldAcceptIdleDoorAwait(false, false, 1201L, true));
+assertFalse(Rs2WalkerAwaits.shouldAcceptIdleDoorAwait(false, false, 600L, false));
+assertTrue(Rs2WalkerAwaits.shouldAcceptIdleDoorAwait(false, false, 601L, true));

-assertFalse(Rs2WalkerAwaits.shouldAcceptIdleDoorAwait(false, false, 1200L, true));
-assertFalse(Rs2WalkerAwaits.shouldAcceptIdleDoorAwait(false, false, 800L, true));
+assertFalse(Rs2WalkerAwaits.shouldAcceptIdleDoorAwait(false, false, 600L, true));
+assertFalse(Rs2WalkerAwaits.shouldAcceptIdleDoorAwait(false, false, 500L, true));
🤖 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/door/Rs2WalkerAwaits.java`
at line 18, Update the boundary assertions in Rs2WalkerAwaitsTest for
shouldAcceptIdleDoorAwait to match DOOR_IDLE_ACCEPT_MIN_MS at 600 ms: treat 600
ms as rejected and 601 ms as accepted, preserving the strict elapsedMs >
threshold behavior.

chsami commented Aug 14, 2026

Copy link
Copy Markdown
Owner

I’m holding this hotfix from merge. The changes are broad enough (walker task lifecycle, pathfinder fallback, door timing, canvas/mouse input, run-energy behavior, Stronghold answers, and transport data) that they need the normal integration path and runtime evidence.

Please address the following:

  1. Retarget from main to development; the PR currently has no repository Build check.
  2. In ShortestPathScript, replace the hardcoded 10 passed to walkWithBankedTransportsAndState with the same configured/default reached-distance used by the non-banked branch.
  3. Update Rs2Player.toggleRunEnergy’s return contract: it now also returns false when energy is below the randomized activation threshold, not only when the widget is missing.
  4. Remove the trailing whitespace on the three new transports.tsv rows (git diff --check currently fails).
  5. Add or report focused tests/live walks for target replacement/cancellation, unreachable-plane recovery, short canvas clicks, door misses, and the Stronghold/transport additions. The current body also says the idle threshold is 600 ms, while the latest code is back at 1200 ms, so please make the description match the intended behavior.

These are substantial walker/input changes, so I’m leaving them with the author rather than editing and merging them without runtime validation.

@chsami
chsami changed the base branch from main to development August 23, 2026 08:47

@chsami chsami left a comment •

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Re-reviewed head 31b263b6c4771aba44d9af87596c0f8ceb6e93a2 on 2026-09-19. The earlier reached-distance and TSV-whitespace issues are fixed. These material blockers remain:

  1. GitHub reports merge conflicts. The diff still carries RuneLite API, rs2asm, and version updates outside the walker/input feature. Rebuild the feature commits on current development and reconcile VirtualMouse/Rs2Walker with the current input and recovery implementations.
  2. Build fails ClientThreadGuardrailTest: Rs2Walker.handleStrongholdOfSecurityAnswer directly calls TileObject.getWorldLocation() off the client thread; the log also reports 14 shifted lambda-baseline entries. Dispatch the new read on the client thread, then verify any baseline regeneration does not hide new violations.
  3. Rs2Walker sets UNREACHABLE_DOOR_RECOVERY_BACKTRACK_EDGES to 0 and starts raw scans at rawStart. When the nearest raw index is beyond a closed gate, this skips the blocking edge. Preserve the preceding-edge scan or add an automated regression showing off-path closed-gate recovery still works.

Live/manual testing is optional and is not a merge requirement. Validate the reconciled branch with the automated walker/input regressions and green expected CI.

@chsami

chsami commented Oct 9, 2026

Copy link
Copy Markdown
Owner

Thanks for the work on this, @dylanreniers. I re-checked it against current development and it can't be merged as-is:

  1. Merge conflicts in ShortestPathScript, Pathfinder, VirtualMouse, Rs2Player and Rs2Walker. development has moved a long way since August, and the Build check on the current head is red.
  2. Much of it is now superseded:
  3. Behaviour concerns still open:
    • processWalk silently redirects an unwalkable target to the nearest walkable tile up to 48 tiles away. That can report ARRIVED somewhere the caller never asked for. Rejecting with UNREACHABLE was deliberate.
    • Setting door-scan backtrack to 0 can miss a door just behind the player.
    • StrongholdAnswer.findAnswer also matches when cleanEnumQ.contains(cleanQ), so a short or partial dialogue string can return the wrong answer.
    • The Motherlode world-map coordinate conversion is hardcoded.
  4. The earlier review points (toggleRunEnergy contract, the transports.tsv whitespace, and runtime evidence for each behaviour change) are still open.

If you'd like to continue, please start from current development and split it into small focused PRs. Good candidates: Stronghold answer matching (with a unit test), the transport rows, and the plane-aware heuristic (with a test). Each one should come with live-walk evidence. Happy to review those.

This branch has not been deployed

No deployments
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.

4 participants