Skip to content

Release Microbot 2.6.15 on RuneLite 1.12.33#1823

Merged
chsami merged 19 commits into
mainfrom
development
Jul 24, 2026
Merged

Release Microbot 2.6.15 on RuneLite 1.12.33#1823
chsami merged 19 commits into
mainfrom
development

Conversation

@chsami

@chsami chsami commented Jul 24, 2026

Copy link
Copy Markdown
Owner

Summary

  • Merge the latest runelite/master through 90eb13760d (17 upstream commits since Microbot's previous RuneLite sync).
  • Bring in RuneLite 1.12.33, including render-thread GPU support, the overlay/snap-corner refactor, cache/GameVal updates, increased profile capacity, and the latest world-map/API fixes.
  • Pin project.build.version and runelite.injected-client.version to the latest released RuneLite version, 1.12.33.
  • Bump microbot.version from 2.6.14 to 2.6.15.

Conflict resolutions and compatibility

  • gradle.properties: retained Microbot repository/injected-client properties and set the release versions above.
  • runelite-client/pmd-ruleset.xml: retained Microbot's intentionally relaxed PMD configuration.
  • ProfilePanel.java: retained Microbot formatting while adopting RuneLite's new 64-profile limit.
  • GpuPlugin.java: adopted RuneLite's render-thread refactor while retaining Microbot's safeguard that pauses scripts after a fatal GPU swap failure.
  • RuneLiteDebug.java: migrated debug-launcher core overlay setup to the new OverlayManager.init() lifecycle.

Validation

  • ./gradlew :client:compileJava — passes (existing warnings only).

Adam- and others added 18 commits July 11, 2026 09:16
screenshot() currently reads the framebuffer as RGBA bytes into a freshly allocated direct ByteBuffer, then reassembles every pixel with four relative ByteBuffer.get() calls in a nested loop. For a w×h capture that's a 4*w*h native allocation plus ~4*w*h bounds-checked byte reads per screenshot, all on the render thread.

This reads the pixels with GL_BGRA / GL_UNSIGNED_INT_8_8_8_8_REV directly into the BufferedImage's backing int[] instead, then flips the rows in place with System.arraycopy. The packed-int format matches TYPE_INT_RGB's layout, and being a packed type its component order is defined relative to the int, so it's endian-independent. GL_BGRA + _REV is also the readback format drivers commonly service without a conversion pass. Both are core since OpenGL 1.2.

One behavioral note: the high byte of each pixel now carries the framebuffer's alpha instead of always being 0. TYPE_INT_RGB's color model has no alpha mask, so it's ignored by rendering, getRGB(), and image encoders alike.

No API change; output images are identical. Mostly motivated by requestNextFrameListener consumers that capture more than a single frame, where this path currently dominates.
# Conflicts:
#	gradle.properties
#	runelite-client/pmd-ruleset.xml
#	runelite-client/src/main/java/net/runelite/client/plugins/config/ProfilePanel.java
#	runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java
@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

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 Plus

Run ID: 9b57953d-f490-4c12-858f-e00a7ab5c364

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

The update bumps project versions and refreshes generated API identifiers and game-data mappings. It adds outdated-plugin runtime configuration and centralizes overlay initialization. GPU rendering gains configurable per-thread resources, deferred VAO allocation, refactored model upload helpers, updated alpha sorting, screenshot handling, and GPU memory reporting. Overlay management now supports widget-aware origins, persisted snap corners, reset and drag hooks, revised widget construction, coordinate conversion, hover selection, and anchor cycle detection.

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.80% 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 clearly states the Microbot release on RuneLite 1.12.33, matching the main changeset.
Description check ✅ Passed The description summarizes the version bump, upstream sync, and compatibility changes accurately.
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.

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: 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/callback/RenderCallbackManager.java`:
- Around line 59-61: Update the callback iteration loops in
RenderCallbackManager at the paths around callbacks.get(i) to use
snapshot-enhanced iteration over the CopyOnWriteArrayList instead of
size()/index-based access. Apply this to all three loops around lines 59, 85,
and 111, preserving the callback-specific try handling and avoiding iterator
removal during concurrent callback unregistering.
🪄 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 Plus

Run ID: 6492a3d9-2940-4d91-ada4-5489ac152835

📥 Commits

Reviewing files that changed from the base of the PR and between 20e953a and 352987d.

📒 Files selected for processing (37)
  • gradle.properties
  • runelite-api/src/main/java/net/runelite/api/Client.java
  • runelite-api/src/main/java/net/runelite/api/ItemID.java
  • runelite-api/src/main/java/net/runelite/api/NullItemID.java
  • runelite-api/src/main/java/net/runelite/api/ObjectID.java
  • runelite-api/src/main/java/net/runelite/api/gameval/DBTableID.java
  • runelite-api/src/main/java/net/runelite/api/gameval/InterfaceID.java
  • runelite-api/src/main/java/net/runelite/api/gameval/ItemID.java
  • runelite-api/src/main/java/net/runelite/api/gameval/ObjectID.java
  • runelite-api/src/main/java/net/runelite/api/gameval/VarPlayerID.java
  • runelite-api/src/main/java/net/runelite/api/gameval/VarbitID.java
  • runelite-client/src/main/java/net/runelite/client/RuneLite.java
  • runelite-client/src/main/java/net/runelite/client/RuneLiteDebug.java
  • runelite-client/src/main/java/net/runelite/client/RuntimeConfig.java
  • runelite-client/src/main/java/net/runelite/client/callback/Hooks.java
  • runelite-client/src/main/java/net/runelite/client/callback/RenderCallbackManager.java
  • runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CoordinateClue.java
  • runelite-client/src/main/java/net/runelite/client/plugins/config/ProfilePanel.java
  • runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java
  • runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPluginConfig.java
  • runelite-client/src/main/java/net/runelite/client/plugins/gpu/ModelUploader.java
  • runelite-client/src/main/java/net/runelite/client/plugins/gpu/SceneUploader.java
  • runelite-client/src/main/java/net/runelite/client/plugins/gpu/VAO.java
  • runelite-client/src/main/java/net/runelite/client/plugins/gpu/Zone.java
  • runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java
  • runelite-client/src/main/java/net/runelite/client/plugins/worldmap/FishingSpotLocation.java
  • runelite-client/src/main/java/net/runelite/client/plugins/worldmap/HunterAreaLocation.java
  • runelite-client/src/main/java/net/runelite/client/plugins/worldmap/MiningSiteLocation.java
  • runelite-client/src/main/java/net/runelite/client/ui/overlay/Overlay.java
  • runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayManager.java
  • runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayOriginX.java
  • runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayOriginY.java
  • runelite-client/src/main/java/net/runelite/client/ui/overlay/OverlayRenderer.java
  • runelite-client/src/main/java/net/runelite/client/ui/overlay/SnapCorner.java
  • runelite-client/src/main/java/net/runelite/client/ui/overlay/SnapCorners.java
  • runelite-client/src/main/java/net/runelite/client/ui/overlay/WidgetOverlay.java
  • runelite-client/src/main/resources/item_variations.json
💤 Files with no reviewable changes (1)
  • runelite-api/src/main/java/net/runelite/api/gameval/InterfaceID.java

Comment on lines +59 to +61
for (int i = 0; i < callbacks.size(); ++i)
{
var cb = callbacks.get(i);

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.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Locate file =="
git ls-files | rg 'RenderCallbackManager\.java$' || true

echo "== File outline/size =="
wc -l runelite-client/src/main/java/net/runelite/client/callback/RenderCallbackManager.java
ast-grep outline runelite-client/src/main/java/net/runelite/client/callback/RenderCallbackManager.java --view compact || true

echo "== Relevant sections =="
cat -n runelite-client/src/main/java/net/runelite/client/callback/RenderCallbackManager.java | sed -n '1,150p'

echo "== Search render callback usage =="
rg -n "RenderCallbackManager|removeRenderCallback|addRenderCallback|render.*callback|callbacks" runelite-client/src/main/java -S

Repository: chsami/Microbot

Length of output: 8286


🌐 Web query:

Java CopyOnWriteArrayList iterator removed from list get index bounds

💡 Result:

In Java, the iterator returned by CopyOnWriteArrayList does not support the remove method [1][2]. If you attempt to call iterator.remove, it will throw an UnsupportedOperationException [3][4]. The reason for this behavior is that CopyOnWriteArrayList iterators are designed as "snapshot" iterators [1][5]. When an iterator is created, it maintains a reference to the state of the underlying array at that specific moment [1][2]. This snapshot never changes, which is why these iterators are guaranteed not to throw a ConcurrentModificationException [1][6]. Because the iterator's view of the data is fixed to the point of its creation, it cannot modify the original list [1][4]. If you need to remove elements from a CopyOnWriteArrayList while traversing it, you should avoid using the iterator's remove method and instead use the list's own methods, such as the removeIf(Predicate) method, which is the recommended and efficient way to perform this operation [3]. Regarding "index bounds," while the iterator itself does not support removal, the CopyOnWriteArrayList class does provide a listIterator(int index) method that accepts an index [4]. If the index provided to this method is out of bounds (less than 0 or greater than the current size of the list), it will throw an IndexOutOfBoundsException [4]. Once the iterator is successfully created, however, its own internal operations (like next or previous) are constrained by the snapshot's bounds, and as noted, any attempt to call remove on that iterator will immediately throw an UnsupportedOperationException rather than an IndexOutOfBoundsException [1][4].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

cat -n runelite-client/src/main/java/net/runelite/client/callback/RenderCallback.java
echo
rg -n "register\(.*RenderCallback|unregister\(.*RenderCallback|addEntity\(.*Renderable|drawTile\(Scene|drawObject\(Scene" runelite-client/src/main/java -S

Repository: chsami/Microbot

Length of output: 4999


🏁 Script executed:

#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from collections.abc import Iterator
import copy

class CopyOnWriteArrayList:
    def __init__(self):
        self._inner = []
    def add(self, item):
        inner = list(self._inner)
        inner.append(item)
        self._inner = inner
    def remove(self, item):
        self._inner = list(self._inner)
        self._inner.remove(item)
    def size(self):
        return len(self._inner)
    def get(self, i):
        return self._inner[i]
    def __iter__(self):
        return iter(list(self._inner))

calls = []
items = CopyOnWriteArrayList()
items.add("A"); items.add("B"); items.add("C")
for i in range(items.size()):
    value = items.get(i)
    if value == "B":
        items.remove("B")
    calls.append(f"get({i})={value}")

print(calls)
print("enhanced =", list(CopyOnWriteArrayList()))

Repository: chsami/Microbot

Length of output: 384


🌐 Web query:

Java source CopyOnWriteArrayList Iterator remove UnsupportedOperationException

💡 Result:

The UnsupportedOperationException is thrown when calling remove, add, or set on an iterator obtained from a CopyOnWriteArrayList because these operations are explicitly unsupported by design [1][2]. The Iterator for CopyOnWriteArrayList provides a "snapshot" of the list's state at the moment the iterator was created [1][3]. Because this snapshot is immutable—referencing the fixed state of the array at that specific point in time—it cannot reflect or perform modifications to the underlying list [1][4]. Consequently, the iterator's remove method is implemented to always throw an UnsupportedOperationException [2]. To remove elements while traversing a CopyOnWriteArrayList, you should use the list's own mutation methods (e.g., list.remove(element)) or the collection's removeIf(predicate) method, rather than attempting to use the iterator's remove method [5][6]. Note that while the iterator itself is guaranteed not to throw ConcurrentModificationException because it operates on a static snapshot, modifying the list while iterating over it will not be reflected in that existing iterator [1][6].

Citations:


Preserve snapshot iteration for concurrent callback changes.

These loops read size() and get(i) from a CopyOnWriteArrayList; if a callback unregisters while iteration is in progress, get(i) can throw instead of being handled by the callback-specific try block. Use the snapshot-enhanced iteration instead, and keep concurrent removals off the iterator when appropriate. Applies to the loops at 59-61, 85-87, and 111-113.

🤖 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/callback/RenderCallbackManager.java`
around lines 59 - 61, Update the callback iteration loops in
RenderCallbackManager at the paths around callbacks.get(i) to use
snapshot-enhanced iteration over the CopyOnWriteArrayList instead of
size()/index-based access. Apply this to all three loops around lines 59, 85,
and 111, preserving the callback-specific try handling and avoiding iterator
removal during concurrent callback unregistering.

@chsami
chsami merged commit 4136e9e into main Jul 24, 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.

7 participants