Conversation
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughThis PR performs a comprehensive system refactoring that removes all scheduler documentation files, eliminates the Rs2 Cache Debugger plugin entirely, replaces the legacy RS2 cache system with Rs2PlayerStateCache, introduces new entity query APIs (IEntity, IEntityQueryable, AbstractEntityQueryable), adds cache-based queryables for NPCs, players, tile items, and tile objects, removes SchedulableExamplePlugin and related schedulable example classes, deletes SchedulerConfig and SchedulerInfoOverlay, updates MicrobotPluginManager error handling, and bumps the microbot version from 2.0.41 to 2.1.0. Possibly related PRs
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 17
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerScript.java (1)
897-903: Update the JavaDoc to match the implementation.The JavaDoc comment states this method checks "both the manual lock state and any locked conditions from schedulable plugins", but the implementation only returns
lockState.get(). The comment should be updated to reflect that it now only checks the manual lock state.Apply this diff to correct the JavaDoc:
/** - * Checks if the break handler is currently in a locked state. - * This includes both the manual lock state and any locked conditions from schedulable plugins. + * Checks if the break handler is currently in a manually locked state. + * When locked, breaks are prevented from starting. */ public static boolean isLockState() { return lockState.get(); }runelite-client/src/main/java/net/runelite/client/plugins/microbot/externalplugins/MicrobotPluginManager.java (2)
497-545: Plugins with injection failures are still treated as successfully loadedIn
instantiate, if Guice throwsExecutionError(e.g., due toNoClassDefFoundError) or any otherExceptionduring injector creation, you:
- Log the error and delete the JAR, but
- Still fall through, log
"Loaded plugin {}"and return the plugin instance.That leaves a plugin with a null/invalid injector registered as “loaded”, which contradicts the intent of marking such plugins incompatible and cleaning them up.
Consider rethrowing
PluginInstantiationExceptionafter deleting the JAR so callers can skip adding the plugin:try { Injector parent = Microbot.getInjector(); ... Injector pluginInjector = parent.createChildInjector(pluginModule); System.out.println(pluginInjector.getClass().getSimpleName()); plugin.setInjector(pluginInjector); - } catch (com.google.common.util.concurrent.ExecutionError e) { + } catch (com.google.common.util.concurrent.ExecutionError e) { // Guice/Guava wraps NoClassDefFoundError here Throwable cause = e.getCause(); if (cause instanceof NoClassDefFoundError) { log.error("Missing class while loading plugin {}: {}", clazz.getSimpleName(), cause.toString()); } else { log.error("Error while loading plugin {}: {}", clazz.getSimpleName(), e.toString(), e); } File jar = getPluginJarFile(plugin.getClass().getSimpleName()); if (jar != null) { jar.delete(); } - } catch (Exception ex) { - log.error("Incompatible plugin found: " + clazz.getSimpleName()); - File jar = getPluginJarFile(plugin.getClass().getSimpleName()); - jar.delete(); - } - - log.debug("Loaded plugin {}", clazz.getSimpleName()); - return plugin; + throw new PluginInstantiationException(e); + } catch (Exception ex) { + log.error("Incompatible plugin found: " + clazz.getSimpleName()); + File jar = getPluginJarFile(plugin.getClass().getSimpleName()); + jar.delete(); + throw new PluginInstantiationException(ex); + } + + log.debug("Loaded plugin {}", clazz.getSimpleName()); + return plugin;This keeps the “incompatible/missing class” paths consistent with upstream error-handling semantics.
1001-1053: Removal log message says “Added plugin”In
remove(MicrobotPluginManifest manifest), after successfully removing and deleting the plugin, the log still says:log.info("Added plugin {} to installed list", manifest.getDisplayName());which contradicts the operation being performed.
Consider updating it to reflect removal:
- log.info("Added plugin {} to installed list", manifest.getDisplayName()); + log.info("Removed plugin {} from installed list", manifest.getDisplayName());
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (79)
docs/scheduler/README.md(0 hunks)docs/scheduler/api/schedulable-plugin.md(0 hunks)docs/scheduler/combat-lock-examples.md(0 hunks)docs/scheduler/condition-manager.md(0 hunks)docs/scheduler/conditions/location-conditions.md(0 hunks)docs/scheduler/conditions/logical-conditions.md(0 hunks)docs/scheduler/conditions/npc-conditions.md(0 hunks)docs/scheduler/conditions/resource-conditions.md(0 hunks)docs/scheduler/conditions/skill-conditions.md(0 hunks)docs/scheduler/conditions/time-conditions.md(0 hunks)docs/scheduler/defining-conditions.md(0 hunks)docs/scheduler/event/plugin-schedule-entry-finished-event.md(0 hunks)docs/scheduler/event/plugin-schedule-entry-soft-stop-event.md(0 hunks)docs/scheduler/plugin-schedule-entry-merged.md(0 hunks)docs/scheduler/plugin-writers-guide.md(0 hunks)docs/scheduler/predicate-condition-examples.md(0 hunks)docs/scheduler/roadmap.md(0 hunks)docs/scheduler/schedulable-example-plugin.md(0 hunks)docs/scheduler/scheduler-plugin.md(0 hunks)docs/scheduler/tasks/README.md(0 hunks)docs/scheduler/tasks/enhanced-schedulable-plugin-api.md(0 hunks)docs/scheduler/tasks/plugin-writers-guide.md(0 hunks)docs/scheduler/tasks/requirements-integration.md(0 hunks)docs/scheduler/tasks/requirements-system.md(0 hunks)docs/scheduler/tasks/task-management-system.md(0 hunks)docs/scheduler/user-guide.md(0 hunks)runelite-client/pom.xml(1 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/Microbot.java(3 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/MicrobotConfig.java(0 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/MicrobotOverlay.java(0 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/MicrobotPlugin.java(2 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/Script.java(0 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/rs2cachedebugger/GroundItemFilterPreset.java(0 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/rs2cachedebugger/NpcFilterPreset.java(0 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/rs2cachedebugger/ObjectFilterPreset.java(0 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/rs2cachedebugger/RenderStyle.java(0 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/rs2cachedebugger/Rs2CacheDebuggerConfig.java(0 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/rs2cachedebugger/Rs2CacheDebuggerGroundItemOverlay.java(0 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/rs2cachedebugger/Rs2CacheDebuggerInfoPanel.java(0 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/rs2cachedebugger/Rs2CacheDebuggerNpcOverlay.java(0 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/rs2cachedebugger/Rs2CacheDebuggerObjectOverlay.java(0 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/rs2cachedebugger/Rs2CacheDebuggerPlugin.java(0 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/schedulable/example/LocationStartNotificationOverlay.java(0 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/schedulable/example/README.md(0 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/schedulable/example/SchedulableExampleConfig.java(0 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/schedulable/example/SchedulableExampleOverlay.java(0 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/schedulable/example/SchedulableExamplePlugin.java(0 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/schedulable/example/SchedulableExamplePrePostScheduleRequirements.java(0 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/schedulable/example/SchedulableExamplePrePostScheduleTasks.java(0 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/schedulable/example/SchedulableExampleScript.java(0 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/schedulable/example/enums/SpellbookOption.java(0 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/schedulable/example/enums/UnifiedLocation.java(0 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/AbstractEntityQueryable.java(1 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/IEntity.java(1 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/IEntityQueryable.java(1 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/actor/Rs2ActorModel.java(1 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/NpcApiExample.java(1 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/Rs2NpcCache.java(1 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/Rs2NpcQueryable.java(1 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/models/Rs2NpcModel.java(1 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/PlayerApiExample.java(1 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/Rs2PlayerCache.java(1 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/Rs2PlayerQueryable.java(1 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/models/Rs2PlayerModel.java(1 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/playerstate/Rs2PlayerStateCache.java(1 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileitem/Rs2TileItemCache.java(1 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileitem/Rs2TileItemQueryable.java(1 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileitem/TileItemApiExample.java(1 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileitem/models/Rs2TileItemModel.java(1 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileobject/Rs2TileObjectCache.java(1 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileobject/Rs2TileObjectQueryable.java(1 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileobject/models/Rs2TileObjectModel.java(1 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileobject/models/TileObjectType.java(1 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerOverlay.java(1 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerScript.java(1 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExampleScript.java(2 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/externalplugins/MicrobotPluginManager.java(3 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/pluginscheduler/SchedulerConfig.java(0 hunks)runelite-client/src/main/java/net/runelite/client/plugins/microbot/pluginscheduler/SchedulerInfoOverlay.java(0 hunks)
💤 Files with no reviewable changes (51)
- docs/scheduler/user-guide.md
- docs/scheduler/conditions/logical-conditions.md
- runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/schedulable/example/SchedulableExampleOverlay.java
- runelite-client/src/main/java/net/runelite/client/plugins/microbot/MicrobotConfig.java
- docs/scheduler/conditions/resource-conditions.md
- docs/scheduler/conditions/time-conditions.md
- docs/scheduler/scheduler-plugin.md
- docs/scheduler/README.md
- docs/scheduler/defining-conditions.md
- docs/scheduler/event/plugin-schedule-entry-soft-stop-event.md
- docs/scheduler/schedulable-example-plugin.md
- docs/scheduler/plugin-writers-guide.md
- runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/schedulable/example/enums/UnifiedLocation.java
- runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/schedulable/example/SchedulableExamplePrePostScheduleTasks.java
- runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/rs2cachedebugger/Rs2CacheDebuggerInfoPanel.java
- docs/scheduler/tasks/requirements-system.md
- docs/scheduler/event/plugin-schedule-entry-finished-event.md
- docs/scheduler/conditions/location-conditions.md
- runelite-client/src/main/java/net/runelite/client/plugins/microbot/pluginscheduler/SchedulerConfig.java
- runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/rs2cachedebugger/Rs2CacheDebuggerGroundItemOverlay.java
- runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/schedulable/example/SchedulableExamplePlugin.java
- runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/schedulable/example/LocationStartNotificationOverlay.java
- docs/scheduler/tasks/enhanced-schedulable-plugin-api.md
- runelite-client/src/main/java/net/runelite/client/plugins/microbot/pluginscheduler/SchedulerInfoOverlay.java
- runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/schedulable/example/README.md
- runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/rs2cachedebugger/RenderStyle.java
- runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/schedulable/example/SchedulableExamplePrePostScheduleRequirements.java
- docs/scheduler/api/schedulable-plugin.md
- runelite-client/src/main/java/net/runelite/client/plugins/microbot/MicrobotOverlay.java
- docs/scheduler/tasks/README.md
- runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/rs2cachedebugger/Rs2CacheDebuggerObjectOverlay.java
- runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/rs2cachedebugger/Rs2CacheDebuggerConfig.java
- docs/scheduler/tasks/task-management-system.md
- docs/scheduler/combat-lock-examples.md
- runelite-client/src/main/java/net/runelite/client/plugins/microbot/Script.java
- docs/scheduler/roadmap.md
- docs/scheduler/tasks/plugin-writers-guide.md
- docs/scheduler/tasks/requirements-integration.md
- runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/rs2cachedebugger/Rs2CacheDebuggerPlugin.java
- runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/rs2cachedebugger/GroundItemFilterPreset.java
- docs/scheduler/conditions/skill-conditions.md
- docs/scheduler/plugin-schedule-entry-merged.md
- runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/rs2cachedebugger/Rs2CacheDebuggerNpcOverlay.java
- runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/rs2cachedebugger/NpcFilterPreset.java
- docs/scheduler/predicate-condition-examples.md
- runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/rs2cachedebugger/ObjectFilterPreset.java
- docs/scheduler/conditions/npc-conditions.md
- docs/scheduler/condition-manager.md
- runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/schedulable/example/SchedulableExampleConfig.java
- runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/schedulable/example/enums/SpellbookOption.java
- runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/schedulable/example/SchedulableExampleScript.java
🧰 Additional context used
📓 Path-based instructions (6)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/**/*.java
📄 CodeRabbit inference engine (AGENTS.md)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/**/*.java: Place all gameplay automation code under runelite-client/src/main/java/net/runelite/client/plugins/microbot
Prefix configuration interfaces with the plugin name (e.g., ExampleConfig) within microbot plugins
Files:
runelite-client/src/main/java/net/runelite/client/plugins/microbot/externalplugins/MicrobotPluginManager.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileobject/Rs2TileObjectQueryable.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/Rs2NpcCache.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerOverlay.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileobject/models/TileObjectType.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileitem/Rs2TileItemQueryable.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileitem/Rs2TileItemCache.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/Rs2NpcQueryable.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/AbstractEntityQueryable.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/PlayerApiExample.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerScript.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileobject/models/Rs2TileObjectModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileobject/Rs2TileObjectCache.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/models/Rs2PlayerModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/IEntity.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/playerstate/Rs2PlayerStateCache.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileitem/models/Rs2TileItemModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/Rs2PlayerQueryable.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/NpcApiExample.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/IEntityQueryable.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/actor/Rs2ActorModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileitem/TileItemApiExample.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/MicrobotPlugin.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/models/Rs2NpcModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/Rs2PlayerCache.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExampleScript.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/Microbot.java
**/*.java
📄 CodeRabbit inference engine (AGENTS.md)
**/*.java: Use tabs for indentation, follow the brace placement style exemplified in MicrobotPlugin.java, and keep lines under 120 characters
Use UpperCamelCase for types and lowerCamelCase for members
Files:
runelite-client/src/main/java/net/runelite/client/plugins/microbot/externalplugins/MicrobotPluginManager.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileobject/Rs2TileObjectQueryable.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/Rs2NpcCache.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerOverlay.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileobject/models/TileObjectType.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileitem/Rs2TileItemQueryable.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileitem/Rs2TileItemCache.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/Rs2NpcQueryable.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/AbstractEntityQueryable.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/PlayerApiExample.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerScript.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileobject/models/Rs2TileObjectModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileobject/Rs2TileObjectCache.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/models/Rs2PlayerModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/IEntity.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/playerstate/Rs2PlayerStateCache.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileitem/models/Rs2TileItemModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/Rs2PlayerQueryable.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/NpcApiExample.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/IEntityQueryable.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/actor/Rs2ActorModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileitem/TileItemApiExample.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/MicrobotPlugin.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/models/Rs2NpcModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/Rs2PlayerCache.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExampleScript.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/Microbot.java
runelite-client/src/main/java/net/runelite/client/plugins/microbot/@(!(util|example))/**/*.java
📄 CodeRabbit inference engine (AGENTS.md)
For new automation scripts, reuse the scheduler pattern demonstrated in ExampleScript
Files:
runelite-client/src/main/java/net/runelite/client/plugins/microbot/externalplugins/MicrobotPluginManager.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileobject/Rs2TileObjectQueryable.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/Rs2NpcCache.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerOverlay.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileobject/models/TileObjectType.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileitem/Rs2TileItemQueryable.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileitem/Rs2TileItemCache.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/Rs2NpcQueryable.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/AbstractEntityQueryable.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/PlayerApiExample.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerScript.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileobject/models/Rs2TileObjectModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileobject/Rs2TileObjectCache.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/models/Rs2PlayerModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/IEntity.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/playerstate/Rs2PlayerStateCache.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileitem/models/Rs2TileItemModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/Rs2PlayerQueryable.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/NpcApiExample.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/IEntityQueryable.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/actor/Rs2ActorModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileitem/TileItemApiExample.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/models/Rs2NpcModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/Rs2PlayerCache.java
**/pom.xml
📄 CodeRabbit inference engine (AGENTS.md)
Target Java 11 via maven-compiler-plugin using 11 in all module POMs
Files:
runelite-client/pom.xml
runelite-client/src/main/java/net/runelite/client/plugins/microbot/MicrobotPlugin.java
📄 CodeRabbit inference engine (AGENTS.md)
When adding panel controls or overlays, update the Microbot navigation panel setup in MicrobotPlugin and provide default config values
Files:
runelite-client/src/main/java/net/runelite/client/plugins/microbot/MicrobotPlugin.java
runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/**/*.java
📄 CodeRabbit inference engine (AGENTS.md)
Keep runnable examples under .../microbot/example
Files:
runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExampleScript.java
🧠 Learnings (17)
📚 Learning: 2025-10-16T17:14:29.778Z
Learnt from: CR
Repo: chsami/Microbot PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-16T17:14:29.778Z
Learning: Applies to runelite-client/src/main/java/net/runelite/client/plugins/microbot/**/*.java : Place all gameplay automation code under runelite-client/src/main/java/net/runelite/client/plugins/microbot
Applied to files:
runelite-client/src/main/java/net/runelite/client/plugins/microbot/externalplugins/MicrobotPluginManager.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/Rs2NpcCache.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerOverlay.javarunelite-client/pom.xmlrunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/PlayerApiExample.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerScript.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileobject/models/Rs2TileObjectModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileobject/Rs2TileObjectCache.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/models/Rs2PlayerModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/IEntity.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/playerstate/Rs2PlayerStateCache.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileitem/models/Rs2TileItemModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/NpcApiExample.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/actor/Rs2ActorModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileitem/TileItemApiExample.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/MicrobotPlugin.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/models/Rs2NpcModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/Rs2PlayerCache.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExampleScript.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/Microbot.java
📚 Learning: 2025-10-16T17:14:29.778Z
Learnt from: CR
Repo: chsami/Microbot PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-16T17:14:29.778Z
Learning: Applies to runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/**/*.java : Put shared helpers under .../microbot/util
Applied to files:
runelite-client/src/main/java/net/runelite/client/plugins/microbot/externalplugins/MicrobotPluginManager.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/Rs2NpcCache.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerOverlay.javarunelite-client/pom.xmlrunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/AbstractEntityQueryable.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/PlayerApiExample.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerScript.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileobject/models/Rs2TileObjectModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileobject/Rs2TileObjectCache.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/models/Rs2PlayerModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/IEntity.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/playerstate/Rs2PlayerStateCache.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileitem/models/Rs2TileItemModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/NpcApiExample.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/IEntityQueryable.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/actor/Rs2ActorModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileitem/TileItemApiExample.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/MicrobotPlugin.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/models/Rs2NpcModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExampleScript.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/Microbot.java
📚 Learning: 2025-10-16T17:14:29.778Z
Learnt from: CR
Repo: chsami/Microbot PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-16T17:14:29.778Z
Learning: Applies to runelite-client/src/main/java/net/runelite/client/plugins/microbot/**/*.java : Prefix configuration interfaces with the plugin name (e.g., ExampleConfig) within microbot plugins
Applied to files:
runelite-client/src/main/java/net/runelite/client/plugins/microbot/externalplugins/MicrobotPluginManager.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerOverlay.javarunelite-client/pom.xmlrunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/PlayerApiExample.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerScript.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileobject/models/Rs2TileObjectModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/models/Rs2PlayerModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/IEntity.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/NpcApiExample.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/IEntityQueryable.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/actor/Rs2ActorModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileitem/TileItemApiExample.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/MicrobotPlugin.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/models/Rs2NpcModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExampleScript.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/Microbot.java
📚 Learning: 2025-10-16T17:14:29.778Z
Learnt from: CR
Repo: chsami/Microbot PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-16T17:14:29.778Z
Learning: Applies to runelite-client/src/main/java/net/runelite/client/plugins/microbot/MicrobotPlugin.java : When adding panel controls or overlays, update the Microbot navigation panel setup in MicrobotPlugin and provide default config values
Applied to files:
runelite-client/src/main/java/net/runelite/client/plugins/microbot/externalplugins/MicrobotPluginManager.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerOverlay.javarunelite-client/pom.xmlrunelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerScript.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/MicrobotPlugin.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExampleScript.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/Microbot.java
📚 Learning: 2025-10-16T17:14:29.778Z
Learnt from: CR
Repo: chsami/Microbot PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-16T17:14:29.778Z
Learning: Applies to runelite-client/src/main/java/net/runelite/client/plugins/microbot/@(!(util|example))/**/*.java : For new automation scripts, reuse the scheduler pattern demonstrated in ExampleScript
Applied to files:
runelite-client/src/main/java/net/runelite/client/plugins/microbot/externalplugins/MicrobotPluginManager.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerOverlay.javarunelite-client/pom.xmlrunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/PlayerApiExample.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerScript.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/NpcApiExample.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/actor/Rs2ActorModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileitem/TileItemApiExample.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/MicrobotPlugin.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExampleScript.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/Microbot.java
📚 Learning: 2025-10-16T17:14:29.778Z
Learnt from: CR
Repo: chsami/Microbot PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-16T17:14:29.778Z
Learning: Applies to runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/**/*.java : Keep runnable examples under .../microbot/example
Applied to files:
runelite-client/src/main/java/net/runelite/client/plugins/microbot/externalplugins/MicrobotPluginManager.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerOverlay.javarunelite-client/pom.xmlrunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/PlayerApiExample.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerScript.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/models/Rs2PlayerModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/NpcApiExample.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/actor/Rs2ActorModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileitem/TileItemApiExample.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/MicrobotPlugin.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExampleScript.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/Microbot.java
📚 Learning: 2025-08-23T16:17:37.615Z
Learnt from: g-mason0
Repo: chsami/Microbot PR: 1423
File: runelite-client/src/main/java/net/runelite/client/plugins/microbot/externalplugins/MicrobotPluginManager.java:366-389
Timestamp: 2025-08-23T16:17:37.615Z
Learning: The ScheduledExecutorService injected into MicrobotPluginManager (and other RuneLite classes) is configured as a single-threaded executor via Executors.newSingleThreadScheduledExecutor() at RuneLiteModule.java line 130, wrapped in ExecutorServiceExceptionLogger. This ensures all async tasks execute sequentially, preventing race conditions.
Applied to files:
runelite-client/src/main/java/net/runelite/client/plugins/microbot/externalplugins/MicrobotPluginManager.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerOverlay.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerScript.java
📚 Learning: 2025-09-03T03:59:10.180Z
Learnt from: g-mason0
Repo: chsami/Microbot PR: 1462
File: runelite-client/src/main/java/net/runelite/client/plugins/microbot/ui/MicrobotPluginHubPanel.java:343-344
Timestamp: 2025-09-03T03:59:10.180Z
Learning: In MicrobotPluginManager, the public methods installPlugin(), removePlugin(), and update() already use executor.submit() internally to perform their operations asynchronously, making them non-blocking on the EDT. These are wrapper methods that delegate to the actual implementation methods (install(), remove(), refresh()) via the executor.
Applied to files:
runelite-client/src/main/java/net/runelite/client/plugins/microbot/externalplugins/MicrobotPluginManager.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerOverlay.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerScript.java
📚 Learning: 2025-08-23T06:16:24.647Z
Learnt from: Voxsylvae
Repo: chsami/Microbot PR: 1415
File: runelite-client/src/main/java/net/runelite/client/plugins/microbot/VoxPlugins/schedulable/example/SchedulableExamplePlugin.java:275-281
Timestamp: 2025-08-23T06:16:24.647Z
Learning: In the Microbot plugin scheduler framework, when using AbstractPrePostScheduleTasks, error handling and reporting for pre-schedule and post-schedule tasks is already managed by the handlePreTaskCompletion and handlePostTaskCompletion methods. These methods automatically handle exceptions and report failures via ExecutionResult. Additional error reporting in catch blocks when calling runPreScheduleTasks() or runPostScheduleTasks() is redundant and should be avoided.
Applied to files:
runelite-client/src/main/java/net/runelite/client/plugins/microbot/externalplugins/MicrobotPluginManager.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerScript.java
📚 Learning: 2025-09-03T04:18:27.289Z
Learnt from: g-mason0
Repo: chsami/Microbot PR: 1462
File: runelite-client/src/main/java/net/runelite/client/plugins/microbot/externalplugins/MicrobotPluginManager.java:985-1010
Timestamp: 2025-09-03T04:18:27.289Z
Learning: In MicrobotPluginManager, hash verification is performed during refresh() rather than download to avoid false positives. JAR files built on GitHub runners with different OS/JDK versions can produce different hashes than local builds, so comparing downloaded bytes against manifest hash would cause legitimate files to fail verification. Instead, the system saves MicrobotPluginManifest copies in installedPlugins profile key and uses verifyHash() method to compare saved local manifest hash against current authoritative manifest hash.
Applied to files:
runelite-client/src/main/java/net/runelite/client/plugins/microbot/externalplugins/MicrobotPluginManager.java
📚 Learning: 2025-09-10T01:10:09.440Z
Learnt from: T-edit
Repo: chsami/Microbot PR: 1500
File: runelite-client/src/main/java/net/runelite/client/plugins/microbot/tempoross/TemporossScript.java:674-679
Timestamp: 2025-09-10T01:10:09.440Z
Learning: Rs2NpcModel implements the NPC interface (extends ActorModel implements NPC), so instanceof NPC returns true for Rs2NpcModel instances. When Rs2Player.getInteracting() returns Rs2NpcModel objects, they can be safely cast to NPC.
Applied to files:
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/Rs2NpcCache.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/Rs2NpcQueryable.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/models/Rs2PlayerModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileitem/models/Rs2TileItemModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/NpcApiExample.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/actor/Rs2ActorModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/models/Rs2NpcModel.java
📚 Learning: 2025-09-10T01:10:09.440Z
Learnt from: T-edit
Repo: chsami/Microbot PR: 1500
File: runelite-client/src/main/java/net/runelite/client/plugins/microbot/tempoross/TemporossScript.java:674-679
Timestamp: 2025-09-10T01:10:09.440Z
Learning: Rs2NpcModel is an NPC class, so `instanceof NPC` returns true for Rs2NpcModel instances. When reviewing code that checks `instanceof NPC` on objects that might be Rs2NpcModel, the check will work correctly.
Applied to files:
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/Rs2NpcCache.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/Rs2NpcQueryable.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/models/Rs2PlayerModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileitem/models/Rs2TileItemModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/NpcApiExample.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/actor/Rs2ActorModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/models/Rs2NpcModel.java
📚 Learning: 2025-08-25T07:26:53.623Z
Learnt from: Voxsylvae
Repo: chsami/Microbot PR: 1415
File: runelite-client/src/main/java/net/runelite/client/plugins/microbot/pluginscheduler/SchedulerPlugin.java:2341-2366
Timestamp: 2025-08-25T07:26:53.623Z
Learning: In SchedulerPlugin.startLoginMonitoringThread(), do not gate startup on isBreakHandlerEnabled(); rely on isOnBreak() to suppress the monitor only when a break is actually active. This avoids blocking login monitoring whenever BreakHandler is merely enabled.
Applied to files:
runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerOverlay.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerScript.java
📚 Learning: 2025-08-26T14:31:41.066Z
Learnt from: Voxsylvae
Repo: chsami/Microbot PR: 1415
File: runelite-client/src/main/java/net/runelite/client/plugins/microbot/TaF/GiantSeaweedFarmer/GiantSeaweedFarmerPlugin.java:84-103
Timestamp: 2025-08-26T14:31:41.066Z
Learning: In GiantSeaweedFarmerPlugin's post-schedule task event handler, when lockCondition is active, the event should be ignored rather than unlocking and stopping. The lock should only be released by the code that originally acquired it to maintain thread safety during critical operations.
Applied to files:
runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerOverlay.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerScript.java
📚 Learning: 2025-08-31T19:19:07.691Z
Learnt from: chsami
Repo: chsami/Microbot PR: 1455
File: runelite-client/src/main/java/net/runelite/client/plugins/microbot/MicrobotVersionChecker.java:112-132
Timestamp: 2025-08-31T19:19:07.691Z
Learning: The Microbot project uses only numeric versioning (e.g., "1.2.3") without any alphanumeric suffixes like "-beta" or "-alpha", so simple integer parsing of version segments is safe.
Applied to files:
runelite-client/pom.xml
📚 Learning: 2025-08-25T15:51:39.272Z
Learnt from: runsonmypc
Repo: chsami/Microbot PR: 1417
File: runelite-client/src/main/java/net/runelite/client/plugins/microbot/agility/AgilityScript.java:13-13
Timestamp: 2025-08-25T15:51:39.272Z
Learning: Both net.runelite.api.ItemID and net.runelite.api.gameval.ItemID are valid import paths in the RuneLite codebase. The microbot plugins consistently use net.runelite.api.ItemID as their established pattern.
Applied to files:
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileitem/models/Rs2TileItemModel.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileitem/TileItemApiExample.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/MicrobotPlugin.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExampleScript.javarunelite-client/src/main/java/net/runelite/client/plugins/microbot/Microbot.java
📚 Learning: 2025-10-16T17:14:29.778Z
Learnt from: CR
Repo: chsami/Microbot PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-16T17:14:29.778Z
Learning: Use RuneLite’s dependency injection to share logic via util classes rather than duplicating inside scripts
Applied to files:
runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExampleScript.java
🧬 Code graph analysis (14)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileobject/Rs2TileObjectQueryable.java (3)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/AbstractEntityQueryable.java (1)
AbstractEntityQueryable(19-170)runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileobject/models/Rs2TileObjectModel.java (1)
Rs2TileObjectModel(23-269)runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileobject/Rs2TileObjectCache.java (1)
Rs2TileObjectCache(13-67)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileobject/models/TileObjectType.java (1)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/TileObjectType.java (1)
TileObjectType(3-9)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileitem/Rs2TileItemQueryable.java (1)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/AbstractEntityQueryable.java (1)
AbstractEntityQueryable(19-170)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/Rs2NpcQueryable.java (2)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/AbstractEntityQueryable.java (1)
AbstractEntityQueryable(19-170)runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/Rs2NpcCache.java (1)
Rs2NpcCache(11-41)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/PlayerApiExample.java (1)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/Rs2PlayerCache.java (1)
Rs2PlayerCache(12-42)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileobject/models/Rs2TileObjectModel.java (2)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/equipment/Rs2Equipment.java (1)
Rs2Equipment(25-392)runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/menu/NewMenuEntry.java (1)
NewMenuEntry(11-317)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileobject/Rs2TileObjectCache.java (1)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileobject/models/Rs2TileObjectModel.java (1)
Rs2TileObjectModel(23-269)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/models/Rs2PlayerModel.java (3)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/actor/Rs2ActorModel.java (1)
Getter(16-435)runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/models/Rs2NpcModel.java (1)
Getter(19-206)runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/player/Rs2PlayerModel.java (1)
Getter(12-88)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileitem/models/Rs2TileItemModel.java (3)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/menu/NewMenuEntry.java (1)
NewMenuEntry(11-317)runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/reflection/Rs2Reflection.java (1)
Rs2Reflection(22-131)runelite-api/src/main/java/net/runelite/api/Perspective.java (1)
Perspective(62-1159)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/Rs2PlayerQueryable.java (2)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/AbstractEntityQueryable.java (1)
AbstractEntityQueryable(19-170)runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/Rs2PlayerCache.java (1)
Rs2PlayerCache(12-42)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/NpcApiExample.java (1)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/Rs2NpcCache.java (1)
Rs2NpcCache(11-41)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/actor/Rs2ActorModel.java (2)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/models/Rs2NpcModel.java (1)
Getter(19-206)runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/models/Rs2PlayerModel.java (1)
Getter(12-98)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/models/Rs2NpcModel.java (3)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/actor/Rs2ActorModel.java (1)
Getter(16-435)runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/models/Rs2PlayerModel.java (1)
Getter(12-98)runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/npc/Rs2NpcModel.java (1)
Getter(19-196)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExampleScript.java (5)
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/Rs2NpcCache.java (1)
Rs2NpcCache(11-41)runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileobject/Rs2TileObjectCache.java (1)
Rs2TileObjectCache(13-67)runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/player/Rs2PlayerCache.java (1)
Rs2PlayerCache(12-42)runelite-client/src/main/java/net/runelite/client/plugins/microbot/Microbot.java (1)
Slf4j(78-784)runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileitem/models/Rs2TileItemModel.java (1)
Slf4j(17-260)
🪛 GitHub Actions: CI
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/NpcApiExample.java
[error] 21-21: incompatible types: net.runelite.client.plugins.microbot.api.npc.models.Rs2NpcModel cannot be converted to net.runelite.client.plugins.microbot.util.npc.Rs2NpcModel
[error] 24-24: incompatible types: net.runelite.client.plugins.microbot.api.npc.models.Rs2NpcModel cannot be converted to net.runelite.client.plugins.microbot.util.npc.Rs2NpcModel
[error] 27-27: incompatible types: net.runelite.client.plugins.microbot.api.npc.models.Rs2NpcModel cannot be converted to net.runelite.client.plugins.microbot.util.npc.Rs2NpcModel
[error] 30-30: incompatible types: net.runelite.client.plugins.microbot.api.npc.models.Rs2NpcModel cannot be converted to net.runelite.client.plugins.microbot.util.npc.Rs2NpcModel
[error] 33-33: incompatible types: net.runelite.client.plugins.microbot.api.npc.models.Rs2NpcModel cannot be converted to net.runelite.client.plugins.microbot.util.npc.Rs2NpcModel
[error] 36-36: incompatible types: net.runelite.client.plugins.microbot.api.npc.models.Rs2NpcModel cannot be converted to net.runelite.client.plugins.microbot.util.npc.Rs2NpcModel
[error] 41-41: incompatible types: java.util.List<net.runelite.client.plugins.microbot.api.npc.models.Rs2NpcModel> cannot be converted to java.util.List<net.runelite.client.plugins.microbot.util.npc.Rs2NpcModel>
[error] 47-47: incompatible types: net.runelite.client.plugins.microbot.api.npc.models.Rs2NpcModel cannot be converted to net.runelite.client.plugins.microbot.util.npc.Rs2NpcModel
[error] 52-52: incompatible types: net.runelite.client.plugins.microbot.api.npc.models.Rs2NpcModel cannot be converted to net.runelite.client.plugins.microbot.util.npc.Rs2NpcModel
[error] 58-58: incompatible types: net.runelite.client.plugins.microbot.api.npc.models.Rs2NpcModel cannot be converted to net.runelite.client.plugins.microbot.util.npc.Rs2NpcModel
[error] 62-62: incompatible types: net.runelite.client.plugins.microbot.api.npc.models.Rs2NpcModel cannot be converted to net.runelite.client.plugins.microbot.util.npc.Rs2NpcModel
[error] 69-69: invalid method reference: isMoving in class net.runelite.client.plugins.microbot.util.npc.Rs2NpcModel cannot be applied to given types; expected no arguments, found Rs2NpcModel
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Build
| public Q within(int distance) { | ||
| WorldPoint playerLoc = getPlayerLocation(); | ||
| if (playerLoc == null) { | ||
| return null; | ||
| } | ||
|
|
||
| this.source = this.source | ||
| .filter(o -> o.getWorldLocation().distanceTo(playerLoc) <= distance); | ||
|
|
||
| return (Q) this; | ||
| } | ||
|
|
||
| @SuppressWarnings("unchecked") | ||
| @Override | ||
| public Q within(WorldPoint anchor, int distance) { | ||
| if (anchor == null) { | ||
| return null; | ||
| } | ||
|
|
||
| this.source = this.source | ||
| .filter(o -> o.getWorldLocation().distanceTo(anchor) <= distance); | ||
|
|
||
| return (Q) this; | ||
| } |
There was a problem hiding this comment.
Make within* always return the queryable and consistently guard null player location
There are a couple of logic inconsistencies in the query API:
-
within(...)sometimes returnsnullinstead of the queryable.within(int distance)andwithin(WorldPoint anchor, int distance)returnnullwhen the player location or anchor is null, whilewhere(...)and other filters always return(Q) this.- That makes chains like
query().within(10).withName("Tree")blow up with an NPE ifgetPlayerLocation()happens to be null.
-
Name/ID helpers assume a non‑null player location, unlike
nearest/within.withName,withNames,withId, andwithIdsall callRs2Player.getWorldLocation()inside a distance comparator with no null check.nearest()/nearest(int)explicitly bail out if the player location is null, so behavior here is inconsistent and can NPE when not logged in.
A safer, more consistent approach would be:
- Make
within(...)always returnthis, and if the player location/anchor is null, either:- leave
sourceunchanged (no filtering), or - set
source = Stream.empty()so downstream ops just see no results.
- leave
- For the name/ID methods, reuse
getPlayerLocation()and handle a null anchor similarly tonearest(); if there’s no location, either:- return the first matching entity without distance ordering, or
- return
nullearly without touching the stream.
For example:
@SuppressWarnings("unchecked")
@Override
public Q within(int distance) {
WorldPoint playerLoc = getPlayerLocation();
- if (playerLoc == null) {
- return null;
- }
-
- this.source = this.source
- .filter(o -> o.getWorldLocation().distanceTo(playerLoc) <= distance);
-
- return (Q) this;
+ if (playerLoc != null) {
+ this.source = this.source
+ .filter(o -> o.getWorldLocation().distanceTo(playerLoc) <= distance);
+ }
+ return (Q) this;
}
@Override
public E withName(String name) {
if (name == null) return null;
- return Microbot.getClientThread().invoke(() -> {
- return source.filter(x -> {
+ WorldPoint playerLoc = getPlayerLocation();
+ if (playerLoc == null) return null;
+
+ return Microbot.getClientThread().invoke(() -> {
+ return source.filter(x -> {
String n = x.getName();
return n != null && n.equalsIgnoreCase(name);
})
- .min(java.util.Comparator.comparingInt(o -> o.getWorldLocation().distanceTo(Rs2Player.getWorldLocation())))
+ .min(java.util.Comparator.comparingInt(o -> o.getWorldLocation().distanceTo(playerLoc)))
.orElse(null);
});
}and apply the same pattern to within(WorldPoint, int), withNames, withId, and withIds.
Also applies to: 124-164
| public void setActionFrame(int frame) | ||
| { | ||
| actor.setAnimationFrame(frame); | ||
| } |
There was a problem hiding this comment.
setActionFrame delegates to the wrong underlying method
setActionFrame(int frame) currently calls actor.setAnimationFrame(frame), so any caller intending to change the action frame will instead modify the animation frame:
@Override
public void setActionFrame(int frame)
{
actor.setAnimationFrame(frame);
}This is inconsistent with the Actor API and with setAnimationFrame, which already delegates to actor.setAnimationFrame.
Suggested fix:
- public void setActionFrame(int frame)
- {
- actor.setAnimationFrame(frame);
- }
+ public void setActionFrame(int frame)
+ {
+ actor.setActionFrame(frame);
+ }🤖 Prompt for AI Agents
In
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/actor/Rs2ActorModel.java
around lines 233 to 236, setActionFrame(int frame) incorrectly delegates to
actor.setAnimationFrame(frame); change the delegation to call
actor.setActionFrame(frame) so the action frame is updated (or, if the
underlying actor API uses a different method name, call the correct actor method
for setting the action frame and ensure the method signature matches).
| public static Predicate<Rs2NpcModel> matches(boolean exact, String... names) { | ||
| return npc -> { | ||
| String npcName = npc.getName(); | ||
| if (npcName == null) return false; | ||
| if (exact) npcName = npcName.toLowerCase(); | ||
| final String name = npcName; | ||
| return exact ? Arrays.stream(names).anyMatch(name::equalsIgnoreCase) : | ||
| Arrays.stream(names).anyMatch(s -> name.contains(s.toLowerCase())); | ||
| }; |
There was a problem hiding this comment.
Partial name matching is effectively case‑sensitive on the NPC name
In matches(boolean exact, String... names):
if (exact) npcName = npcName.toLowerCase();
final String name = npcName;
return exact ? Arrays.stream(names).anyMatch(name::equalsIgnoreCase) :
Arrays.stream(names).anyMatch(s -> name.contains(s.toLowerCase()));For exact == false, only s is lower‑cased; name remains in its original case. This makes the substring check unintentionally case‑sensitive on the NPC name.
To make behavior consistent (case‑insensitive in both modes), consider:
- return npc -> {
- String npcName = npc.getName();
- if (npcName == null) return false;
- if (exact) npcName = npcName.toLowerCase();
- final String name = npcName;
- return exact ? Arrays.stream(names).anyMatch(name::equalsIgnoreCase) :
- Arrays.stream(names).anyMatch(s -> name.contains(s.toLowerCase()));
- };
+ return npc -> {
+ String npcName = npc.getName();
+ if (npcName == null) {
+ return false;
+ }
+ String nameLower = npcName.toLowerCase();
+ if (exact) {
+ return Arrays.stream(names)
+ .anyMatch(s -> nameLower.equals(s.toLowerCase()));
+ }
+ return Arrays.stream(names)
+ .map(String::toLowerCase)
+ .anyMatch(nameLower::contains);
+ };This keeps exact semantics but avoids surprising case behavior in the partial‑match branch.
🤖 Prompt for AI Agents
In
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/models/Rs2NpcModel.java
around lines 159 to 167, the partial-match branch currently uses the NPC's
original case while only lower-casing the supplied names, causing unintended
case-sensitive substring checks; fix this by normalizing the NPC name to
lower-case once (after null check) into a local variable and then perform both
exact and partial comparisons against the supplied names after lower-casing them
(e.g., exact: compare name.equals(lowercasedCandidate); partial:
name.contains(lowercasedCandidate)), ensuring case-insensitive behavior in both
modes.
| @@ -0,0 +1,71 @@ | |||
| package net.runelite.client.plugins.microbot.api.npc; | |||
|
|
|||
| import net.runelite.client.plugins.microbot.util.npc.Rs2NpcModel; | |||
There was a problem hiding this comment.
Wrong import causes type mismatch throughout the file.
Line 3 imports net.runelite.client.plugins.microbot.util.npc.Rs2NpcModel, but the Rs2NpcCache returns net.runelite.client.plugins.microbot.api.npc.models.Rs2NpcModel instances. This mismatch causes all 12 compilation errors reported by the pipeline.
Apply this diff to fix the import:
-import net.runelite.client.plugins.microbot.util.npc.Rs2NpcModel;
+import net.runelite.client.plugins.microbot.api.npc.models.Rs2NpcModel;📝 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.
| import net.runelite.client.plugins.microbot.util.npc.Rs2NpcModel; | |
| import net.runelite.client.plugins.microbot.api.npc.models.Rs2NpcModel; |
🤖 Prompt for AI Agents
In
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/NpcApiExample.java
around line 3, the file imports
net.runelite.client.plugins.microbot.util.npc.Rs2NpcModel which mismatches the
Rs2NpcCache return type; change the import to
net.runelite.client.plugins.microbot.api.npc.models.Rs2NpcModel so the types
align, update any import statement accordingly, then rebuild to confirm the 12
compilation errors are resolved.
| private static int lastUpdateNpcs = 0; | ||
| private static List<Rs2NpcModel> npcs = new ArrayList<>(); | ||
|
|
||
| public Rs2NpcQueryable query() { | ||
| return new Rs2NpcQueryable(); | ||
| } | ||
|
|
||
| /** | ||
| * Get all NPCs in the current scene | ||
| * | ||
| * @return Stream of Rs2NpcModel | ||
| */ | ||
| public static Stream<Rs2NpcModel> getNpcsStream() { | ||
|
|
||
| if (lastUpdateNpcs >= Microbot.getClient().getTickCount()) { | ||
| return npcs.stream(); | ||
| } | ||
|
|
||
| List<Rs2NpcModel> result = Microbot.getClientThread().invoke(() -> Microbot | ||
| .getClient() | ||
| .getTopLevelWorldView() | ||
| .npcs().stream().map(Rs2NpcModel::new) | ||
| .collect(Collectors.toList())); | ||
|
|
||
| npcs = result; | ||
| lastUpdateNpcs = Microbot.getClient().getTickCount(); | ||
| return result.stream(); |
There was a problem hiding this comment.
Cache may never populate on first tick due to lastUpdateNpcs initialization
With lastUpdateNpcs starting at 0 and the check lastUpdateNpcs >= Microbot.getClient().getTickCount(), a first call when getTickCount() is 0 will treat the empty cache as “fresh” and skip population, returning an empty stream even though NPCs exist.
Consider using a sentinel value or adjusting the comparison, e.g.:
- private static int lastUpdateNpcs = 0;
+ private static int lastUpdateNpcs = -1;This ensures the first call actually populates the cache.
🤖 Prompt for AI Agents
In
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/npc/Rs2NpcCache.java
around lines 13-39, the cache check uses lastUpdateNpcs initialized to 0 with
the condition lastUpdateNpcs >= Microbot.getClient().getTickCount(), which
causes the cache to be treated as fresh when tickCount is 0 and prevents initial
population; fix by initializing lastUpdateNpcs to a sentinel like -1 (so the
first call will populate) or change the comparison to strictly greater-than
(lastUpdateNpcs > Microbot.getClient().getTickCount()) so the first tick (0)
will not skip population.
| int index = 0; | ||
| String objName = ""; | ||
| if (action != null) { | ||
| //performance improvement to only get compoisiton if action has been specified | ||
| var objComp = getObjectComposition(); | ||
| String[] actions; | ||
| if (objComp.getImpostorIds() != null && objComp.getImpostor() != null) { | ||
| actions = objComp.getImpostor().getActions(); | ||
| } else { | ||
| actions = objComp.getActions(); | ||
| } | ||
|
|
||
| for (int i = 0; i < actions.length; i++) { | ||
| if (actions[i] == null) continue; | ||
| if (action.equalsIgnoreCase(Rs2UiHelper.stripColTags(actions[i]))) { | ||
| index = i; | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| if (index == actions.length) | ||
| index = 0; | ||
|
|
||
| objName = objComp.getName(); | ||
|
|
||
| // both hands must be free before using MINECART | ||
| if (objComp.getName().toLowerCase().contains("train cart")) { | ||
| Rs2Equipment.unEquip(EquipmentInventorySlot.WEAPON); | ||
| Rs2Equipment.unEquip(EquipmentInventorySlot.SHIELD); | ||
| sleepUntil(() -> Rs2Equipment.get(EquipmentInventorySlot.WEAPON) == null && Rs2Equipment.get(EquipmentInventorySlot.SHIELD) == null); | ||
| } | ||
| } | ||
|
|
||
| if (index == -1) { | ||
| Microbot.log("Failed to interact with object " + getId() + " " + action); | ||
| } |
There was a problem hiding this comment.
Action index sentinel logic is inconsistent and never reports “action not found”
index is initialised to 0 and only ever assigned from the loop variable i (0..actions.length - 1). That makes both:
if (index == actions.length) index = 0;if (index == -1) { Microbot.log(...); }
effectively dead code. As a result, when action doesn’t match any of the object’s actions, index stays 0 and click("MissingAction") silently falls back to the first menu option rather than signalling failure.
If you want to detect “no matching action” explicitly, consider using a real sentinel and handling it before building the menu entry, e.g.:
- int index = 0;
+ int index = 0;
String objName = "";
- if (action != null) {
+ if (action != null) {
//performance improvement to only get compoisiton if action has been specified
var objComp = getObjectComposition();
String[] actions;
if (objComp.getImpostorIds() != null && objComp.getImpostor() != null) {
actions = objComp.getImpostor().getActions();
} else {
actions = objComp.getActions();
}
-
- for (int i = 0; i < actions.length; i++) {
+ int matchedIndex = -1;
+ for (int i = 0; i < actions.length; i++) {
if (actions[i] == null) continue;
if (action.equalsIgnoreCase(Rs2UiHelper.stripColTags(actions[i]))) {
- index = i;
- break;
+ matchedIndex = i;
+ break;
}
}
-
- if (index == actions.length)
- index = 0;
+ if (matchedIndex == -1) {
+ Microbot.log("Failed to interact with object " + getId() + " " + action);
+ return false;
+ }
+ index = matchedIndex;
objName = objComp.getName();
@@
- if (index == -1) {
- Microbot.log("Failed to interact with object " + getId() + " " + action);
- }
+ // at this point index is guaranteed to be a valid option indexAdjust the exact fallback behaviour if you do want unknown actions to default to the first option, but as written the current checks are inconsistent and never fire.
🤖 Prompt for AI Agents
In
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileobject/models/Rs2TileObjectModel.java
around lines 201-236, the action index uses 0 as the initial value so “no match”
is indistinguishable from matching the first action; initialize index to -1, set
index = i when a match is found in the loop (leave loop logic), remove or adjust
the meaningless check that compares index to actions.length, and after the loop
explicitly check if index == -1 to log the failure and abort/return before
building the menu entry (or, if you intentionally want to fall back to the first
option, explicitly set index = 0 in that branch so the fallback is obvious).
Ensure null/empty actions are handled and that the rest of the method uses the
updated index sentinel consistently.
| public enum TileObjectType { | ||
| GAME, | ||
| WALL, | ||
| DECORATIVE, | ||
| GROUND, | ||
| GENERIC | ||
| } |
There was a problem hiding this comment.
Duplicate enum definition.
This enum is duplicated at runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/TileObjectType.java with identical constants. Having two identical enums in different packages will cause type incompatibility issues when code expects one type but receives the other.
🤖 Prompt for AI Agents
In
runelite-client/src/main/java/net/runelite/client/plugins/microbot/api/tileobject/models/TileObjectType.java
lines 3-9 there is a duplicate enum definition identical to
runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/TileObjectType.java;
remove this duplicate file (or replace its usages) and consolidate to a single
enum to avoid type incompatibility: delete this enum, update all imports/usages
to reference the canonical TileObjectType (choose the util package or move the
enum to a common shared package), then run a project-wide import/refactor to fix
compile errors and ensure only one enum definition remains.
| public static Stream<Rs2TileObjectModel> getObjectsStream() { | ||
|
|
||
| if (lastUpdateObjects >= Microbot.getClient().getTickCount()) { | ||
| return tileObjects.stream(); | ||
| } | ||
|
|
||
| Player player = Microbot.getClient().getLocalPlayer(); | ||
| if (player == null) return Stream.empty(); | ||
|
|
||
| List<Rs2TileObjectModel> result = new ArrayList<>(); | ||
|
|
||
| var tileValues = Microbot.getClient().getTopLevelWorldView().getScene().getTiles()[Microbot.getClient().getTopLevelWorldView().getPlane()]; | ||
|
|
||
| for (Tile[] tileValue : tileValues) { | ||
| for (Tile tile : tileValue) { | ||
| if (tile == null) continue; | ||
|
|
||
| if (tile.getGameObjects() != null) { | ||
| for (GameObject gameObject : tile.getGameObjects()) { | ||
| if (gameObject == null) continue; | ||
| if (gameObject.getSceneMinLocation().equals(tile.getSceneLocation())) { | ||
| result.add(new Rs2TileObjectModel(gameObject)); | ||
| } | ||
| } | ||
| } | ||
| if (tile.getGroundObject() != null) { | ||
| result.add(new Rs2TileObjectModel(tile.getGroundObject())); | ||
| } | ||
| if (tile.getWallObject() != null) { | ||
| result.add(new Rs2TileObjectModel(tile.getWallObject())); | ||
| } | ||
| if (tile.getDecorativeObject() != null) { | ||
| result.add(new Rs2TileObjectModel(tile.getDecorativeObject())); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| tileObjects = result; | ||
| lastUpdateObjects = Microbot.getClient().getTickCount(); | ||
| return result.stream(); | ||
| } |
There was a problem hiding this comment.
Run scene tile traversal on the client thread to avoid race conditions
getObjectsStream reads getTopLevelWorldView().getScene().getTiles() directly from whatever thread calls it (e.g., ExampleScript’s scheduler), while other caches (like Rs2NpcCache) do this work via Microbot.getClientThread().invoke(...). That inconsistency can violate RuneLite’s client‑thread rules and cause flaky crashes or corrupted reads.
Consider moving the scene iteration into a client‑thread invocation and using its result as the cache, e.g.:
public static Stream<Rs2TileObjectModel> getObjectsStream() {
if (lastUpdateObjects >= Microbot.getClient().getTickCount()) {
return tileObjects.stream();
}
- Player player = Microbot.getClient().getLocalPlayer();
- if (player == null) return Stream.empty();
-
- List<Rs2TileObjectModel> result = new ArrayList<>();
-
- var tileValues = Microbot.getClient().getTopLevelWorldView().getScene().getTiles()[Microbot.getClient().getTopLevelWorldView().getPlane()];
-
- for (Tile[] tileValue : tileValues) {
- for (Tile tile : tileValue) {
- if (tile == null) continue;
-
- if (tile.getGameObjects() != null) {
- for (GameObject gameObject : tile.getGameObjects()) {
- if (gameObject == null) continue;
- if (gameObject.getSceneMinLocation().equals(tile.getSceneLocation())) {
- result.add(new Rs2TileObjectModel(gameObject));
- }
- }
- }
- if (tile.getGroundObject() != null) {
- result.add(new Rs2TileObjectModel(tile.getGroundObject()));
- }
- if (tile.getWallObject() != null) {
- result.add(new Rs2TileObjectModel(tile.getWallObject()));
- }
- if (tile.getDecorativeObject() != null) {
- result.add(new Rs2TileObjectModel(tile.getDecorativeObject()));
- }
- }
- }
-
- tileObjects = result;
+ List<Rs2TileObjectModel> result = Microbot.getClientThread().invoke(() -> {
+ Player player = Microbot.getClient().getLocalPlayer();
+ if (player == null) {
+ return null;
+ }
+
+ List<Rs2TileObjectModel> tmp = new ArrayList<>();
+ var worldView = Microbot.getClient().getTopLevelWorldView();
+ var tileValues = worldView.getScene().getTiles()[worldView.getPlane()];
+
+ for (Tile[] tileRow : tileValues) {
+ for (Tile tile : tileRow) {
+ if (tile == null) {
+ continue;
+ }
+
+ if (tile.getGameObjects() != null) {
+ for (GameObject gameObject : tile.getGameObjects()) {
+ if (gameObject == null) {
+ continue;
+ }
+ if (gameObject.getSceneMinLocation().equals(tile.getSceneLocation())) {
+ tmp.add(new Rs2TileObjectModel(gameObject));
+ }
+ }
+ }
+ if (tile.getGroundObject() != null) {
+ tmp.add(new Rs2TileObjectModel(tile.getGroundObject()));
+ }
+ if (tile.getWallObject() != null) {
+ tmp.add(new Rs2TileObjectModel(tile.getWallObject()));
+ }
+ if (tile.getDecorativeObject() != null) {
+ tmp.add(new Rs2TileObjectModel(tile.getDecorativeObject()));
+ }
+ }
+ }
+
+ return tmp;
+ });
+
+ if (result == null) {
+ return Stream.empty();
+ }
+
+ tileObjects = result;
lastUpdateObjects = Microbot.getClient().getTickCount();
return result.stream();
}| panelComponent.getChildren().add(LineComponent.builder() | ||
| .left("Reason: Plugin Lock Condition Active") | ||
| .leftColor(Color.ORANGE) | ||
| .build()); |
There was a problem hiding this comment.
🧩 Analysis chain
Verify that manual locks are no longer supported.
The hardcoded message "Plugin Lock Condition Active" assumes only plugin-based locks exist. If BreakHandlerScript still supports manual locks, this message would be misleading when a manual lock is active.
Run the following script to check if manual lock functionality still exists in BreakHandlerScript:
🏁 Script executed:
#!/bin/bash
# Description: Search for manual lock methods and fields in BreakHandlerScript
# Search for manual lock related methods and fields
rg -nP --type=java -C5 'manual.*[Ll]ock|setLock|lockManual' runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerScript.javaLength of output: 968
Verify that manual locks are no longer supported, or fix the hardcoded message.
The javadoc at line 899 of BreakHandlerScript states the lock includes "both the manual lock state and any locked conditions from schedulable plugins." However, the overlay always displays "Plugin Lock Condition Active" regardless of lock type, which would be misleading when a manual lock is active.
🤖 Prompt for AI Agents
In
runelite-client/src/main/java/net/runelite/client/plugins/microbot/breakhandler/BreakHandlerOverlay.java
around lines 64-67, the overlay hardcodes "Reason: Plugin Lock Condition Active"
which mislabels manual locks; change the logic to determine the actual lock type
from the BreakHandler/BreakHandlerScript (e.g., check a provided isManualLock()
or getLockType()/getLockReason() method) and set the displayed text accordingly
— e.g., "Reason: Manual Lock Active" when a manual lock is present, otherwise
keep "Reason: Plugin Lock Condition Active"; update the leftColor if desired to
keep visual distinction.
| /** | ||
| * Performance test script for measuring GameObject composition retrieval speed. | ||
| * | ||
| * <p> | ||
| * This script runs every 5 seconds and performs the following: | ||
| * - Gets all GameObjects in the scene | ||
| * - Retrieves the ObjectComposition for each GameObject | ||
| * - Measures and logs the total time taken | ||
| * - Reports average time per object | ||
| * | ||
| * <p> | ||
| * Useful for performance profiling and optimization testing. | ||
| */ |
There was a problem hiding this comment.
Update Javadoc to match the new cache‑based behavior
The class comment still describes a GameObject/ObjectComposition performance test, but the implementation now benchmarks fetching players, NPCs, tile objects, and ground items via the new caches and only logs counts + total time. It’d be less confusing to rewrite the Javadoc to reflect what the script actually does now.
🤖 Prompt for AI Agents
In
runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExampleScript.java
around lines 15 to 25, the class Javadoc still describes a
GameObject/ObjectComposition performance test but the implementation now
benchmarks cache-based retrieval of players, NPCs, tile objects, and ground
items and logs counts plus total time; update the Javadoc to accurately describe
the current behavior: state that it runs every 5 seconds, fetches players, NPCs,
tile objects and ground items from their caches, measures total elapsed time for
the fetches, and logs the counts and total time (and remove any mention of
GameObject/ObjectComposition composition retrieval). Ensure the description is
concise, mentions it’s for performance benchmarking/profiling, and reflects the
current outputs (counts + total time).
# Conflicts: # runelite-client/pom.xml
…orkTree1 # Conflicts: # runelite-client/pom.xml # runelite-client/src/main/java/net/runelite/client/plugins/microbot/Microbot.java # runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExampleScript.java
# Conflicts: # runelite-client/pom.xml # runelite-client/src/main/java/net/runelite/client/plugins/microbot/Microbot.java # runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExampleScript.java
# Conflicts: # runelite-client/pom.xml # runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/tileobject/Rs2TileObjectModel.java
# Conflicts: # runelite-client/pom.xml # runelite-client/src/main/java/net/runelite/client/plugins/microbot/MicrobotPlugin.java # runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/security/LoginManager.java
# Conflicts: # runelite-client/pom.xml
# Conflicts: # runelite-client/pom.xml # runelite-client/src/main/java/net/runelite/client/plugins/microbot/example/ExampleScript.java # runelite-client/src/main/java/net/runelite/client/plugins/microbot/pluginscheduler/tasks/requirements/registry/RequirementRegistry.java
2.1.0