Skip to content

fix(world-hop): wait for the world switcher to load before hopping - #1935

Merged
chsami merged 2 commits into
developmentfrom
fix/world-hop-first-attempt
Oct 11, 2026
Merged

chsami merged 2 commits into
developmentfrom
fix/world-hop-first-attempt

Conversation

@chsami

@chsami chsami commented Oct 11, 2026 •

Copy link
Copy Markdown
Owner

Problem

Microbot.hopToWorld called client.openWorldHopper() and client.hopToWorld(world) inside the same client-thread callback. RuneLite only accepts the hop once the world switcher interface is loaded (the stock world hopper plugin waits a game tick for Worldswitcher.BUTTONS before hopping), so whenever the switcher was closed the first call silently did nothing and logged Failed to hop to world N at ERROR. Callers only got there by calling again.

Found by the release E2E harness (#1933): the world-hop check failed on the first Microbot.hopToWorld and succeeded on the retry.

Fix

  • The client-thread lambda now only runs the guards and builds the target World.
  • New hopViaWorldSwitcher: if Worldswitcher.BUTTONS is not loaded, it opens the switcher and waits for it with sleepUntil (5 s timeout, off the client thread). It re-sends openWorldHopper every 600 ms while waiting, like the stock plugin does each tick. Once the switcher has loaded, it calls client.hopToWorld in a separate client-thread call. If the switcher is already open, it hops straight away.
  • If the switcher never loads, it logs a WARN and returns false instead of attempting a hop that cannot work.
  • quickHopTargetWorld is cleared in a finally, so a concurrent call is still rejected while the switcher is loading and the guard can no longer get stuck.
  • Removed the static sleep(600) before the existing sleepUntil for the hop state.

Callers (Rs2Player.hopIfPlayerDetected, Rs2WorldUtil.hopWorld) keep their own retry loops. Those are generic, not workarounds for this bug, so I left them alone.

Tests

  • MicrobotWorldHopTest, 3 cases:
    • the switcher opens, and the hop is issued only after the list loads, in a separate client-thread call
    • the switcher is already open, so it hops with no reopen
    • the switcher never loads, so it never hops
  • ClientThreadGuardrailTest passes and the baseline is unchanged.

Live verification

I merged the release E2E harness (#1933, c247cb4) into a local throwaway branch on top of this fix and ran scripts/run-release-e2e.sh quick boot login world-hop against the shaded jar. Setup: F2P account, start world 383, isolated runtime home. The harness code is not in this PR.

  • With the final fix code, 15 of 16 runs passed. Each passing run hopped 383 to 552 or 553 and back, so 30 hops in all, every one on the first Microbot.hopToWorld call. Each hop took about 6 to 7 s including the full hop.
  • None of the passing runs logged a Failed to hop line or any other ERROR line.
  • The last run also included the logout check, which scans the whole run's client.log: it passed with 0 error lines.
  • Two runs failed: one before the 600 ms re-open was added and one after it. In both, the check started in the same second the welcome screen's play button was clicked, and the world switcher did not load within 10 s, even with the re-open. Both failures logged only the new WARN, with no ERROR line. I added a throwaway probe for the welcome screen and logout tab state, ran 12 more times with it, and could not reproduce it. All 12 started with the welcome screen closed and the logout tab loaded.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LjtEMzQHGuq4M1Mpqk9pPV

@coderabbitai

coderabbitai Bot commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 41b105ba-2d65-4a1e-8e08-0b5abbad474a



📥 Commits

Reviewing files that changed from the base of the PR and between e5863ae and 4e459b4.




📒 Files selected for processing (2)
  • runelite-client/src/main/java/net/runelite/client/plugins/microbot/Microbot.java
  • runelite-client/src/test/java/net/runelite/client/plugins/microbot/MicrobotWorldHopTest.java



Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 0 remain after this review.





Walkthrough

The world-hop flow now prepares the target world before issuing the hop. If the world switcher buttons are not loaded, it opens the hopper and waits up to 5,000 ms for them. The hop is issued on the client thread only when the buttons are available. The flow clears quickHopTargetWorld in a finally block and no longer uses the fixed 600 ms sleep. Tests cover delayed loading, an already-open switcher, and timeout.

Priority: ⬇️ Low

Merge Risk: ⚪ Minimal · up to 4e459

The hop now waits for the world switcher before proceeding. No actionable merge-blocking issue remains after normal checks.

Pre-merge checks | Passed 4 | Failed 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 9 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
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 and concisely summarizes the primary change: waiting for the world switcher to load before hopping.
Description check Passed The description directly explains the world-hop failure, the implemented fix, the tests, and verification results.

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR





  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@chsami
chsami merged commit 802a7b4 into development Oct 11, 2026
3 checks passed
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