n3Plugins Source Of Truth
Current as of 2026-07-13. This file owns current-state facts. Live source wins; update this file when they diverge.
Runtime Shape
Single-module Java 11 RuneLite external plugin suite under com.n3plugins.*. Native RuneLite plugin registration via runelite-plugin.properties. SDK/utilities packaged under com.n3plugins.sdk.*.
PacketUtilsPlugin is the required shared plugin. It owns revision setup, packet reflection, SDK event-bus init, request-driven account bootstrap, walker ticking, action pacing, active-automation input locking, suite-wide idle-logout prevention, SOCKS proxy routing, and plugin-list branding.
Account bootstrap is opt-in per active owner. Gameplay plugins and script surfaces that need account setup call PacketUtilsPlugin.requireAccountBootstrap(owner) while active and releaseAccountBootstrap(owner) when idle/stopped. PacketUtils then waits for login, ensures fixed view mode, raises HA warning threshold, disables level-up messages, and exposes readiness via PacketUtilsPlugin.isAccountBootstrapReady() and SuiteRuntimeStatus. When no owner has requested bootstrap, isAccountBootstrapReady() is true and no bootstrap UI actions run.
Full automation plugins are also required to integrate with Break Handler using active-only tracking: register on startup, call startPlugin(this) only while an automation loop or command has an actionable active state, pause gameplay actions on planned/active breaks, and stop tracking when idle/disabled/stopped/shutdown. Current required full automation plugins: Market Alcher, Power Skiller, Tree Woodcutter, Woodcutter, Wood Fletcher, GE Buyer, AIO Fighter, Tutorial Island, Guardians of the Rift, Mule Orchestrator, and Bank Stander. Dialogue Helper, Walk Assistant, Questing Assistant, and Combat Awareness are QoL/helper-style exemptions.
Build And Metadata
| Item | Value |
|---|---|
| Group / Version | com.n3plugins / 5.5 |
| RuneLite | 1.12.32 (rev239) |
| Java | 11 |
| Source / Resources | src/main/java / src/main/resources |
| Manifest | runelite-plugin.properties (placed at jar root by processResources) |
| Fat jar tasks | FatJar (excludes hidden/PathingTesting, includes n3DevTools), FatJarWithHidden |
| Brand asset | src/main/resources/com/n3plugins/ui/brand/n3.png — load from jar, never machine-local |
Repo-owned RuneLite mirror constants and widget/gameval IDs are guarded against
RuneLite 1.12.32 by WidgetIdParityTest, LegacyConstantParityTest, and the
raw widget ID allowlist scan. Runtime-only widget IDs without a current gameval
name must stay in that allowlist with an authority note. New or touched packed
widget IDs should be added to WidgetID/WidgetInfoExtended from RuneLite
InterfaceID, ComponentID, or gameval names, then covered by parity tests;
do not keep raw packed literals in production callers merely because the
action-name widget lookup path cannot resolve a component.
Vendored shortest-path data
| Item | Value |
|---|---|
| Upstream | https://github.com/Skretzo/shortest-path |
| Companion tooling reference | https://github.com/osrs-pathfinding/shortest-path-tooling |
| Vendor root | src/main/resources/com/n3plugins/sdk/walker/shortestpath |
| Metadata | vendor.properties pins upstreamSha, commit URL, copied resources, license, and update time |
| Included resources | collision-map.zip, destinations/**, transports/**, UPSTREAM-LICENSE.txt |
| Excluded resources | upstream plugin descriptor and legacy transports.txt bridge |
| Refresh/check | .\gradlew.bat updateShortestPathVendor --console plain; .\gradlew.bat checkShortestPathVendor --console plain |
PacketUtils exposes the pinned upstream Shortest Path config keys for route
settings, POH transports, thresholds, display/debug fields, and hidden
built-transport persistence. ShortestPathRouteService classifies modern TSV
transport rows by source file before requirement filtering rather than
collapsing them into one imported category.
collision-map.zip stores raw per-region flag bitsets inside the zip; the
loader accepts those raw entries plus older gzip/serialized region payloads.
ShortestPathRouteServiceModernResourcesTest.collisionResourceSupportsVarrockWalkingRoute
guards the SplitFlagMap ZipException: Not in GZIP format regression from the
live 3165,3463 -> 3173,3441 failure case.
Runtime dependencies (fat jar)
| Dependency | Version | Used by |
|---|---|---|
Java-WebSocket | 1.5.3 | Code Console |
org.json | 20230227 | ID maps, market client, packets |
RoaringBitmap | 0.9.44 | Walker collision map |
commons-lang3 | 3.14.0 | Shared utils (shaded com.n3plugins.shaded.*) |
jcefmaven | 135.0.20 | Code Console browser |
cfr | 0.152 | Code Console decompiler |
caffeine | 3.1.8 | WikiMarketClient cache |
PureLogViewer | 1.0.1 | Log viewer UI |
rxjava | 3.1.8 | Break Handler event bus |
compileOnly (provided by RuneLite at runtime)
| Dependency | Version | Notes |
|---|---|---|
net.runelite:client | 1.12.32 | Must match exactly |
net.runelite:jshell | 1.12.32 | Code Console JShell |
net.runelite:flatlaf-extras | 3.2.5-rl4 | UI theming |
gson | 2.9.0 | Excluded from fat jar |
okhttp3 | 4.12.0 | WikiMarketClient |
guava | 32.1.3-jre | IdMapRegistry |
lombok | 1.18.20 | Compile-time only |
Registered Plugins
| Plugin | Entrypoint | Config group | Notes |
|---|---|---|---|
| Packet Utils | c.n3p.PacketUtils.PacketUtilsPlugin | n3packetutils | Required; enabled by default; revision-sensitive; owns request-driven bootstrap, shared input lock, idle-logout prevention, SOCKS proxy routing, and branding |
| Mule Orchestrator | c.n3p.muleplugin.MulePlugin | n3muleplugin | Break Handler active while slave workflow commands run; see docs/muleplugin.md |
| Walk Assistant | c.n3p.walkassistant.WalkAssistantPlugin | n3walkassistant | Walk/cancel with InteractionResult status; uses PacketUtils-owned Shortest Path route settings |
| Dialogue Helper | c.n3p.dialoguehelper.DialogueHelperPlugin | n3dialoguehelper | Stateless widget-scan; autoContinue/autoQuestOptions/debugLogging |
| Questing Assistant | c.n3p.questingassistant.QuestingAssistantPlugin | n3questingassistant | Disabled by default; helper-style Quest Helper-driven dialogue/NPC/object/item automation for unambiguous supported steps, walking near Quest Helper step points before out-of-range target actions; no Break Handler registration or PacketUtils account-bootstrap requirement; see docs/questing-assistant.md |
| Profiles | c.n3p.n3Profiles.PureProfilesPlugin | n3profiles | Typed encrypted credential store; strict typed bulk import; Jagex OAuth/manual sessions; see docs/profiles.md |
| Combat Awareness | c.n3p.combatawareness.CombatAwarenessPlugin | n3combatawareness | Randomized re-attack + anti-ban fidgets; see docs/combat-awareness.md |
| Code Console | c.n3p.codeconsole.CodeConsolePlugin | n3codeconsole | Session-only command console |
| Market Alcher | c.n3p.marketalcher.MarketAlcherPlugin | n3marketalcher | MVC alcher with budget-reserved/adaptive supply planner + GE reconciliation, configurable target selection mode, ownership-aware inventory alching, configurable nature restock, and independent GE buy toggles. Config is primarily managed via sidebar Quick Settings and target browser Settings tab; MarketAlcherConfig is still provided through RuneLite ConfigManager. Break Handler active while automation is enabled and the controller is not idle/stopped. See docs/market-alcher.md and docs/market-alcher-dreambot-comparison.md |
| Power Skiller | c.n3p.powerskiller.PowerSkillerPlugin | n3powerskiller | Generic object/NPC skilling helper with hotkey start/stop, required-tool and keep-list policy, optional nearest-bank deposit, one-item-per-tick dropping, forestry-style tree targeting, and Break Handler-gated running state. See docs/power-skiller.md |
| Tree Woodcutter | c.n3p.treewoodcutter.TreeWoodcutterPlugin | n3treewc | Per-tick hybrid + TaskPipeline subflows; Break Handler-gated while the controller is not stopped; see docs/tree-woodcutter.md |
| Woodcutter | c.n3p.woodcutter.WoodcutterPlugin | n3woodcutter | Hotkey-controlled local-radius chopping with immutable session settings, TaskPipeline bank/axe/nest trips, SDK-only query/action runtime, synchronized n3 sidebar, active-time telemetry, PacketUtils bootstrap, and active-only Break Handler tracking; see docs/woodcutter.md |
| Wood Fletcher | c.n3p.woodfletcher.WoodFletcherPlugin | n3woodfletcher | Disabled by default; per-tick chop/fletch loop using ProductionWorkflowBuilder, BankWorkflowBuilder, PacketUtils bootstrap, and active-only Break Handler tracking; see docs/wood-fletcher.md |
| GE Buyer | c.n3p.gebuyer.GeBuyerPlugin | n3gebuyer | Disabled by default; Grand Exchange buy queue that places one TaskPipeline at a time while monitoring multiple submitted buy slots; see docs/ge-buyer.md |
| AIO Fighter | c.n3p.fighter.FighterPlugin | n3fighter | Disabled by default; profile-driven combat with configured targets, loadout reconciliation, bank/combat anchors, ownership-safe loot and targets, food thresholds, and active-only Break Handler tracking; see docs/fighter.md |
| Tutorial Island | c.n3p.tutorialisland.TutorialIslandPlugin | n3tutorialisland | Disabled by default; varp-281 decision tree; Break Handler-gated while auto mode is active; see docs/tutorial-island.md |
| Guardians of the Rift | c.n3p.guardiansrift.GuardiansRiftPlugin | n3guardiansrift | Disabled by default; AutoRifts parity-plus per-tick controller with pouch repair, altar selection, portal/cell/rune handling, and Break Handler active-only tracking; see docs/guardians-rift.md |
| Break Handler | c.n3p.breakhandler.BreakHandlerPlugin | n3breakhandler | Disabled by default; ChinBreakHandler port; RxJava3 bus; see docs/breakhandler.md |
| Agent Server | c.n3p.agentserver.AgentServerPlugin | n3agentserver | Disabled by default; localhost-only HTTP API plus direct non-SSE /mcp Streamable HTTP endpoint for agent/client development; see docs/agent-server.md |
| Developer Tools | c.n3p.n3DevTools.DevToolsPlugin | devtools | Disabled by default; developer inspection panel included in fat jars |
| API Tester | c.n3p.apitester.ApiTesterPlugin | n3apitester | Disabled by default; developer/QoL live-client harness for user-triggered InteractionApi.actions.* probes; no Break Handler registration or account-bootstrap requirement; see docs/api-tester.md |
| Bank Stander | c.n3p.bankstander.BankStanderPlugin | n3bankstander | Bank standing automation; Break Handler active while running |
Entrypoint abbreviation: c.n3p = com.n3plugins. Do not register N3LoaderPlugin, EthanApiPlugin, or PathingTesting.
Package Map
| Package | Role |
|---|---|
PacketUtils | Required shared plugin: revision, packets, bootstrap, pacer, walker tick, active-automation input lock, branding |
Packets | Low-level packet queuing helpers |
InteractionApi | Result-aware action API + legacy compatibility facades |
sdk.client | N3Client, ClientThreadBridge, ClientScreenshots, ClientScreenshot, Delays, GameVars, HintArrows, line-of-sight, tile-threat, world-point utils |
sdk.events | Passive bounded snapshots for XP gained, item-container deltas, NPC spawns/despawns, animation changes, and projectile movement |
sdk.items | Item metadata snapshots and OSRS Wiki price quote parsing/fetching |
sdk.market | Shared Grand Exchange buy-limit tracking and market time-source helpers |
sdk.idmaps | Bundled + revision-cache item/NPC/object ID-map registry |
sdk.input | Canvas input helpers, configured HotkeyEventListener callbacks, and HotkeyCaptureEventListener binding capture |
sdk.menu | Current menu-entry snapshots and action-resolution diagnostics |
sdk.social | Friends chat, clan channel, and recent chat message snapshots |
sdk.widgets | Widget/inventory/bank/equipment/dialogue/shop/GE/rune-pouch/combat/prayer helpers |
sdk.world | Current world, world-list, and world-map read helpers |
sdk.query | Inventory/bank/equipment/NPC/player/tile-object/tile-item/widget/trade/shop queries |
sdk.network | Generic WebSocket pub/sub network layer for inter-client communication (SdkWebSocketServer, SdkWebSocketClient, NetworkMessage, ClientSession) |
sdk.walker | Walker, route planner, collision, route options, transports, progress/stall policies, banked route planner, requirements |
sdk.random | Non-blocking bounded random helpers for pacing, scheduling, and gesture points |
sdk.humanizer | Suite-level opt-in anti-ban profiles, gesture scheduling, and pending gesture model |
sdk.loadouts | Inventory/equipment loadout helpers |
sdk.progress | Read-only quest and achievement diary progress helpers backed by RuneLite quests and stable diary var mappings |
sdk.questhelper | Shared Quest Helper reflection snapshot reader and step metadata |
sdk.workflow | State-machine, CombatWorkflowBuilder, ProductionWorkflowBuilder, AutomationApi, caller-owned AutomationLoop adapters |
walkassistant | Walk helper plugin using shared walker |
dialoguehelper | Stateless per-tick dialogue automation |
questingassistant | Quest Helper-driven quest step automation using shared reflection and InteractionApi.actions.* |
muleplugin | Mule orchestration; ::comehere/::mulebank commands. See docs/muleplugin.md |
n3Profiles | Typed encrypted profile store + Jagex OAuth. See docs/profiles.md |
breakhandler | Break-handling; RxJava3 bus; profile re-login. See docs/breakhandler.md |
combatawareness | Combat reminders/re-attack/anti-ban fidgets |
codeconsole | Session-only command console |
marketalcher | Market-driven alcher with supply planner + GE reconciliation |
powerskiller | Generic object/NPC skilling loop with hotkey control, inventory policy, optional banking, and one-item drop handling. See docs/power-skiller.md |
treewoodcutter | Per-tick woodcutting + TaskPipeline subflows. See docs/tree-woodcutter.md |
woodcutter | Hotkey-controlled woodcutting with session telemetry. See docs/woodcutter.md |
woodfletcher | Per-tick woodcutting plus fletching production loop. See docs/wood-fletcher.md |
gebuyer | Grand Exchange buy-order queue and submitted-slot monitor. See docs/ge-buyer.md |
fighter | Profile-driven AIO fighter controller, runtime adapter, profile store, panel, and overlay. See docs/fighter.md |
tutorialisland | Varp-281 decision tree + TaskPipeline. See docs/tutorial-island.md |
guardiansrift | Guardians of the Rift automation controller/runtime with package-local altar, pouch, and repair rules. See docs/guardians-rift.md |
PathingTesting | Source-only, unregistered, excluded from default fat jar |
n3DevTools | Registered developer tooling, disabled by default, included in fat jars |
agentserver | Localhost-only HTTP API for runtime snapshots, shared InteractionApi.actions.* writes, global loaded-plugin status/control, plugin config/log inspection, packaged agent docs, suite capability catalog, restricted read-only SDK helper reads, and direct /mcp Streamable HTTP MCP tools |
apitester | Registered developer/QoL live-client action test harness, disabled by default, included in fat jars |
tools/agent-mcp | Node MCP stdio bridge over Agent Server REST runtime endpoints for agent tool calling; remains separate from direct /mcp, does not expose direct /mcp SDK docs/search tools, and does not run inside RuneLite |
ui | Shared amber theme (N3Theme #F59E0B), panels, cards, buttons, brand loader |
bankstander | Bank standing automation (Using item, Item on Item, Item on Object, Using Object, Spell on Item) |
Shared UI And Branding
N3Theme defines amber accent #F59E0B and dark panel/card colors. N3PluginPanel.addAction(...) returns N3Button pills (first = primary amber action). HeaderPill draws bundled n3.png before plugin name.
N3PluginListBranding replaces [n3] descriptor markers with the bundled icon at runtime (RuneLite has no descriptor icon field). Started/stopped by PacketUtilsPlugin on the Swing EDT; restores labels on shutdown. Depends on [n3] marker remaining in plugin names. See docs/suite-wiring.md for branding caveats.
Interaction API
InteractionApi.actions.* is the preferred plugin-facing automation surface. New code returns InteractionResult; legacy boolean/void facades stay for compatibility. GameVars exposes raw varbit/varplayer reads. Internal deps point at sdk.*, Packets, PacketUtils. Spatial action lookups resolve nearest reachable scene targets by path; stable work-area logic composes reachability with distance to its anchor, never unordered first() results.
Action Catalog
Action classes (all under InteractionApi.actions):
| Class | Coverage |
|---|---|
BankActions | Reachable-target open, close, count, withdraw, deposit, noted-name helpers |
BankWornEquipmentActions | Stable bank worn-equipment deposit action backed by the bank deposit-equipment button |
BankInventoryActions | Bank inventory slot interactions |
BlockingEventActions | Blocking game-event helpers |
DepositBoxActions | Deposit box interactions |
DialogActions | Continue, Quest Helper option select, object-picker input |
EquipmentActions | Equip/unequip/isEquipped by name and slot |
GrandExchangeActions | GE open/close, offer/buy/sell/cancel flows and state |
GraphicsObjectActions | Graphics object targeting |
InventoryActions | Inventory item interactions, selected-spell item clicks |
InventoryDropActions | Comparator-backed paced inventory drop-next helpers |
LootingBagActions | Looting bag use |
MagicActions | Spell casting through spell widgets |
NavigationActions | Path state, cancel/reuse, reached-distance, and movement helpers |
NPCActions | NPC interactions |
ObjectActions | Tile object interactions |
PlayerActions | Player targeting |
PrayerActions | Idempotent enable/disable/set-only and active-state helpers |
ProjectileActions | Projectile targeting |
QuestActions | getState/isComplete/isStarted wrapping RuneLite Quest |
ReachabilityActions | Reachability checks |
SailingActions | Sailing interactions |
ShopActions | Shop buy/sell |
SkillsActions | Skill level reads |
TileItemActions | Ground item interactions |
TradeActions | Trade accept/decline |
UseItemActions | Item-on-target, item-on-item, drag-and-drop |
UtilityEventActions | Utility event helpers |
WidgetActions | Widget interactions; clickOp fires raw 1-based op for actionless CS2 components |
WorldActions | World/map actions |
Sub-packages: actions.combat (AttackStyle/WeaponStyle/CombatActions), actions.magic (Rune/RunePouch/SpellBook/teleports), actions.minigame, actions.movement (FairyRing/GnomeGlider/CharterShip/SpiritTree/MagicCarpet/Minecart/BirdFlight/BankLocation + action helpers), actions.production, actions.tabs. InventoryDropPattern supplies row-major, reverse row-major, column-major, reverse column-major, and custom comparator drop ordering for InventoryDropActions.
Supporting types (InteractionApi.common): InteractionResult, InteractionStatus, ActionResolver, GameStateGuard, StringMatchers.
Pacing (InteractionApi.pacing): ActionPacer, ActionPacerConfig; jitter uses sdk.random.N3Random.
Planning (InteractionApi.plan): TaskPipeline, TaskStep, InventoryPlan, Cooldowns, TickDelay, StepResult/StepStatus.
Debug (InteractionApi.debug): WidgetDescriptor, WidgetExplorer, PacketTrace, RevisionHealthCheck, SuiteRuntimeStatus.
Legacy facades (under InteractionApi root): InventoryInteraction, BankInventoryInteraction, BankInteraction, GeInventoryInteraction, ShopInventoryInteraction, NPCInteraction, TileObjectInteraction, PlayerInteractionHelper, InteractionHelper. Prefer actions.* for new code.
ID Maps And Query Helpers
IdMapRegistry loads item/NPC/object name↔ID maps from bundled classpath resources. Prefers local cache at RuneLite.RUNELITE_DIR/n3Plugins/id-maps/rev-<clientRevision>/ when revision matches. Maps are Guava ImmutableListMultimap/ImmutableMap, built from JSON at load time, immutable thereafter. Import via IdMapRegistry.importGenerated(...). No runtime Python or wiki scraping.
ID-map-assisted query helpers: ItemQuery.withMappedName, NPCQuery.withMappedName, TileObjectQuery.withMappedName. Existing withName(...) methods are exact runtime-name filters. ItemQuery name filters compare the widget name when RuneLite supplies one, then resolve the item ID through the project item-definition API before comparing names. Mapped item-name ID lookups also include the bundled RuneLite item variation table for the current rev239 release, so base mapped names can match released variant IDs without changing exact visible-name filtering. BankItemWidget and EquipmentItemWidget remain public compatibility wrappers, but they carry a real backing Widget via getWidget() instead of implementing RuneLite Widget.
Query builders keep their legacy result() list return and also expose
results() immutable QueryResults<T> snapshots. QueryResults provides
list(), count(), isEmpty(), first(), firstOrNull(), random(),
sorted(...), ids(), names(), and anchor-distance helpers. The distance
helpers use straight-line tile distance only; path-aware selection remains on
query methods such as nearestByPath().
SDK gap-fill read APIs added under sdk.items, sdk.world, sdk.menu,
sdk.widgets, sdk.social, sdk.client.LineOfSightApi, and
sdk.client.ThreatMapApi are compatibility
surfaces for plugin and agent code. Market Alcher strategy, target selection,
budgeting, cooldowns, and GE behavior remain plugin-local. Bank worn-equipment
per-slot writes are not exposed until stable per-slot widget constants/actions
are live-validated. BankStateApi exposes typed withdraw, requested quantity,
placeholder, rearrange, and supported bank-widget descriptor reads; bank control
clicks stay in result-aware BankActions. ProductionApi exposes Make-X and legacy Smithing product and quantity reads;
selected product and selected quantity are widget-state heuristics until
live-validated on the target RuneLite revision. MinigamesApi exposes grouping
tab state, destination availability, cooldown, last usage, and selected
destination reads; selected destination is live-verification pending.
CameraApi exposes read-only camera orientation, position, zoom, viewport
bounds, and viewport projection helpers; zoom source and projection behavior are
live-verification pending.
QuestProgressApi exposes quest state snapshots and walker QuestRequirement
adapters. DiaryProgressApi exposes only explicitly mapped diary varbit/varplayer
tasks; unmapped diary coverage returns absent instead of guessed completion.
SdkEvents exposes bounded passive event snapshots registered by PacketUtils;
it does not poll, issue actions, or own a tick loop. AutomationLoop standardizes
same-tick dedupe, optional PacketUtils bootstrap gating, break-gate callbacks,
status/error text, and adapters for TaskPipeline and AutomationStateMachine;
plugins still call it from their own onGameTick.
Walker And Bootstrap Ownership
PacketUtilsPlugin.onGameTick advances: ActionPacer.onTick(nowMs) → input-lock refresh → optional idle-logout prevention → request-driven account bootstrap → Walker.tick(). No other plugin should own suite-level walker/pacer ticking.
Walker.planTo(...) and Walker.walkTo(...) default to gated smart routing via WalkerRouteOptions.smartDefaults(): walking, teleports, transports, all route categories, and wilderness avoidance are enabled, but route edges are only added when category options and requirements pass. Spell teleports, item teleports, basic transports, imported transports, source-file shortest-path transport categories, spirit trees, fairy rings, gnome gliders, and minecarts can be toggled under their teleport/transport master switches. Imported shortest-path spell and home-spell rows share the TELEPORTATION_SPELL category. Curated in-repo transport widgets, including fairy rings and gnome gliders, use WidgetInfoExtended constants backed by gameval names rather than raw packed IDs. WalkerRouteOptions.walkingOnly() is the explicit literal-walking mode. withBankedRoutePlanning(true) is an explicit opt-in for BankedRoutePlanner direct-vs-bank-prep comparison; default routing is unchanged. WalkerPath uses progress/stall policies so movement, expected-destination arrival, and progress toward the final target prevent premature retries. PacketUtils maps its pinned Shortest Path settings, POH settings, currency threshold, and transport costs into the static Walker route policy and owns the shared PacketUtilsWalkerOverlay over Walker.getActivePath(). NavigationActions tracks the specific path handle it starts and clears stale state when the shared walker path is foreign or terminal. Walk Assistant calls Walker.walkTo(...) directly for world-map and hotkey requests, may replace its own active path, refuses to overwrite a foreign active path, leaves suite-level overlay rendering to PacketUtils, and explicit cancel stops any current non-terminal shared walker path.
WalkerResourceApi exposes immutable route category, vendored shortest-path
transport resource, agility shortcut, and curated transport network descriptors
without publishing raw upstream rows or package-private planner definitions.
sdk.humanizer.HumanizerService is the suite-level opt-in anti-ban scheduler. It owns randomized, non-blocking pending gesture timing; plugin wrappers execute gestures through local code. Combat Awareness consumes it for existing camera, right-click, and tab-glance fidgets.
Automation plugins that require account setup call requireAccountBootstrap(owner) while their automation is active and gate gameplay actions on the returned readiness. Passive overlays, login/logout flows, helper plugins, and non-action bookkeeping may run without requesting bootstrap.
Full automation plugins must also use Break Handler active-only tracking. Register on startup, start tracking only while the automation loop or command has an actionable active state, check shouldBreak(this) / isBreakActive(this) before issuing actions, call startBreak(this) when a planned break becomes due, and release input locks while paused. The source-level guardrail is AutomationBreakHandlerRegistrationTest; update its required/exempt/support classification intentionally when adding registered plugins.
Agent Server MCP
Agent Server exposes existing /api/v1 REST endpoints and a direct /mcp endpoint on the same 127.0.0.1 Java HttpServer. /mcp implements MCP Streamable HTTP without SSE: POST JSON-RPC requests return application/json, accepted notifications return HTTP 202 with no body, and GET returns HTTP 405. Origin validation allows missing Origin and localhost origins; remote browser origins are rejected.
Direct MCP runtime tools use n3_* names and include existing read/write coverage, player snapshots sourced through Players.search(), menu entries, packet-trace interactions, raw varbit/varplayer reads, recent varbit changes, screenshots, global loaded-plugin status/control, plugin config read/write scoped to each plugin config group, live in-memory plugin log reads, item-on-item/NPC/object/ground-item writes, suite capability reporting, typed read tools for world/world-map/camera/line-of-sight/items/prices/social/progress/events/Quest Helper/production/minigames/loadouts, and typed write tools for GE/shop/trade/equipment/prayer/magic/combat/tabs/production/transport/deposit-box/bank-inventory/bank-worn-equipment/drop-pattern actions. n3_read_sdk is a restricted read-only static SDK helper invoker with an explicit allowlist; mutating/action methods are rejected and gameplay writes must use typed InteractionApi.actions.* tools returning InteractionResult. PacketUtils can be inspected and enabled but cannot be disabled through Agent Server because it owns suite runtime state. Direct MCP also exposes Storm-style SDK documentation tools (search, get_class, get_method, list_packages, list_classes, get_examples) plus compatibility helpers (n3_describe_api, n3_search_api_docs, n3_read_api_doc). n3_describe_api returns runtime tool metadata plus an agent-ingestible SDK/API discovery section with schemaVersion, indexVersion, generatedAt, source-index status, supported docs tools, package/topic entry points, coverage counts, capabilities, recommended flow, and stable ids for classes, overload-safe methods, fields, enum constants, packages, and topics. The SDK/API index is generated at build time from src/main/java/com/n3plugins/sdk and src/main/java/com/n3plugins/InteractionApi with JDK compiler tree/doc APIs and packaged as com/n3plugins/agentserver/mcp/sdk-index.json; runtime loads that JSON first and falls back to packaged source only when the generated index is unavailable. Method ids use method:<fqcn>#<name>(<paramTypes>), while simple compatibility reads return overloads when ambiguous. Resource-backed examples live under src/main/resources/com/n3plugins/agentserver/mcp/examples/ for banking, combat, movement, pathfinding, inventory, and widgets. Packaged markdown docs remain available as fallback guidance. Gameplay/business failures return MCP tool results with isError: true and structured InteractionResult or Agent Server details. JSON-RPC protocol failures return JSON-RPC errors. tools/agent-mcp remains a REST-backed runtime bridge and does not expose the direct /mcp SDK docs/search tools.
ClientScreenshots.capturePng() copies the current RuneLite BufferProvider pixels on the Swing EDT, encodes PNG, caches only the latest in memory, and returns null when the client/buffer is unavailable. ClientScreenshots.lastCapture() returns that in-memory latest capture. No screenshot data is written to disk.
Public API Javadocs
Public declarations under src/main/java/com/n3plugins/InteractionApi and
src/main/java/com/n3plugins/sdk require source Javadocs. ApiJavadocCoverageTest
checks public types, constructors, methods, fields, enum constants, and common
placeholder wording. Keep compatibility facades and SDK test adapter seams
documented when they remain part of the public API.
Documentation Conventions
Docs-site content lives under docs/ and is rendered by Docusaurus. Callouts
must use Docusaurus admonitions, not GitHub callout blockquotes:
:::note, :::tip, :::info, :::warning[Caution], and :::danger.
Use warning[Caution] when the heading should read "Caution"; there is no
separate caution directive. Touched legacy sections should be migrated away
from > [!NOTE]/> [!WARNING] and from italicized Note: labels when those
labels carry behaviorally important guidance. The detailed authoring standard
lives in docs/documentation-style-guide.md.
Validation Commands
The compiler-AST-backed Stage 1 widget and action inventory writes
build/reports/correctness/stage-1-audit.json, including HEAD plus scoped
audited-source/config dirty and content-digest provenance. The task rejects
findings outside its reviewed structural baseline. WidgetInfoExtended local
WidgetID aliases are recursively resolved: authoritative gameval terminals
may be source-compliant, while raw numeric terminals remain source gaps unless
narrowly allowlisted. Live widget evidence remains a separate status.
Successful generation is not a live-client verdict.
.\gradlew.bat auditStageOneCorrectness --console plain
Run focused tests first. Use the aggregate build once when full integration and packaging validation are required; it owns compilation, full tests, normal/fat-jar assembly, and packaging tests:
.\gradlew.bat build --console plain
Run shortest-path vendor maintenance by hand; compile/test/build tasks skip GitHub:
.\gradlew.bat updateShortestPathVendor --console plain
.\gradlew.bat checkShortestPathVendor --console plain
Revision-239 packet mapping analysis requires the exact injected client, not the RuneLite launcher or Jagex bootstrap jar:
.\gradlew.bat analyzeRevision239 -PinjectedClientJar=<injected-client.jar> --console plain
-PvanillaGamepackJar=<decrypted-gamepack.jar> is optional and adds artifact
inventory correlation. The supported packet catalog mapping label is
2026-07-08-rev239-11232-release-artifact-derived against injected artifact
REFERENCE_RESOURCES/injected_clients/rev239/v1.12.32/injected-client-1.12.32.jar. Artifact checks cover
field names, decoded lengths, CFG-bounded write order, byte transforms, and
operand provenance. SET_HEADING remains deliberately unmapped until its field
and byte transform are proven; health reports it as non-blocking UNSUPPORTED
while direct sends remain fail-closed.
Focused suites — run the narrowest relevant suite first:
.\gradlew.bat test --tests com.n3plugins.InteractionApi.* --console plain
.\gradlew.bat test --tests com.n3plugins.PacketUtils.* --console plain
.\gradlew.bat test --tests com.n3plugins.walkassistant.* --console plain
.\gradlew.bat test --tests com.n3plugins.dialoguehelper.* --console plain
.\gradlew.bat test --tests com.n3plugins.muleplugin.* --console plain
.\gradlew.bat test --tests com.n3plugins.codeconsole.* --console plain
.\gradlew.bat test --tests com.n3plugins.marketalcher.* --console plain
.\gradlew.bat test --tests com.n3plugins.combatawareness.* --console plain
.\gradlew.bat test --tests com.n3plugins.treewoodcutter.* --console plain
.\gradlew.bat test --tests com.n3plugins.woodcutter.* --console plain
.\gradlew.bat test --tests com.n3plugins.guardiansrift.* --console plain
.\gradlew.bat test --tests com.n3plugins.breakhandler.* --console plain
.\gradlew.bat test --tests com.n3plugins.agentserver.* --console plain
.\gradlew.bat test --tests com.n3plugins.n3Profiles.* --console plain
.\gradlew.bat test --tests com.n3plugins.sdk.* --console plain
.\gradlew.bat test --tests com.n3plugins.ApiJavadocCoverageTest --console plain
.\gradlew.bat test --tests com.n3plugins.PacketUtils.N3PluginListBrandingTest --tests com.n3plugins.ui.brand.N3BrandingTest --console plain
Manual Verification Still Open
- PacketUtils starts on target revision; bootstrap reaches ready (fixed view, HA warning, level-up disable).
- Revision 239 controlled packet tests: mouse, movement, widget, object, NPC, player, ground-item, dialog, and sailing families.
- Revision 239 vanilla/injected correlation against a decrypted vanilla gamepack; the available five-class bootstrap jar is insufficient.
- Each n3 plugin appears in plugin list without a loader.
- Plugin-list branding: bundled icon replaces
[n3]marker; no icon duplication/loss on refresh/shutdown. N3PluginPanelheaders show bundled icon with amber pill/status layout.- Enabling/disabling one n3 plugin does not affect others.
- Walker: PacketUtils Shortest Path route settings, shared path overlay display, modern Skretzo transport edges, POH/banked route settings, and route execution against live RuneLite.
- Walk Assistant: start/cancel paths, world-map target resolution, and replacement of its own active path.
- Dialogue Helper: auto-continue + Quest Helper
[N]-prefixed option selection. - Questing Assistant: supported Quest Helper dialogue, talk-to NPC, object interact, item-on-object, item-on-NPC, and item-on-item steps.
- Mule: bank/walk/trade.
- Combat Awareness: overlay/reminders/re-attack and humanizer-backed anti-ban gestures.
- Code Console: read-only and action commands.
- Agent Server:
/mcpinitialize/tools/list/tools/call over live HTTP, screenshot image capture, menu entries, varbit-change capture, walking/cancel/state polling fields, and item-on-target actions. - SDK gap-fill helpers: bank worn-equipment panel reads, bank state widget reads, Make-X product/quantity reads, grouping/minigame tab reads, camera reads/projection helpers, world-map state/conversions, menu entry snapshots, social snapshots, client-backed line-of-sight behavior, quest/diary progress reads, passive event snapshots, and runtime loop helpers.
- ThreatMap tile-threat semantics: projectile targets, graphics-object hazards, and NPC line-of-sight checks.
- Market Alcher: full supply→alch→rotate loop; budget-reserved/adaptive GE reconciliation; no duplicate buys. See
docs/market-alcher.mdanddocs/market-alcher-dreambot-comparison.md. - Power Skiller: hotkey toggle, object/NPC target interaction, required-tool detection, keep-list protection, nearest-bank Deposit-All, one-item dropping, and forestry tree targeting. See
docs/power-skiller.md. - Tree Woodcutter: axe/tree/inventory/bank state detection. See
docs/tree-woodcutter.md. - Woodcutter: all tree types, target retention, nest pickup/banking, strict and nearest bank routing, axe recovery, synchronized sidebar controls, session rates, target-level completion, and Break Handler pauses. See
docs/woodcutter.md. - Tutorial Island: full name-entry→magic-teleport run; see
docs/tutorial-island.md. - Guardians of the Rift: barrier entry, portal spawn handling, altar selection, pouch repair, cell placement, and rune deposit/drop. See
docs/guardians-rift.md. - Break Handler: schedule/break/re-login cycle. See
docs/breakhandler.md. - Bank Stander: start/stop hotkey, deposit unwanted inventory, withdraw any configured items regardless of mode, equip loadout string, configurable Make-X product selection, and
BankStanderModelogic. Seedocs/bankstander.md.
Key Implementation Patterns
OSRS dialogue is stateless. If the target widget is visible this tick, deliver it when the shared ActionPacer is ready; otherwise do nothing. No signature tracking, lockout, or retry backoff. Dialogue Helper keeps a local lastFiredTick same-tick duplicate guard, but successful delivery also calls ActionPacer.recordAction(). WidgetApi.search() returns hidden widgets; OSRS destroys dialogue widgets on close rather than hiding them.
Testing constraints (no MockedStatic, ActionPacer.reset() in @Before, Mockito mock-before-when() ordering, WidgetApi adapter injection) — see AGENTS.md § Testing constraints.
Developer Rules
- Read AGENTS.md and this file before significant work.
- Keep changes surgical, Java 11 compatible, and
runelite-plugin.propertiesaligned. - Update docs when interaction layer, SDK packages, or registration changes.
- Run
ApiJavadocCoverageTestafter publicInteractionApiorsdkAPI changes. - RuneLite Javadocs: client · API
Contributor Workflow Docs
- Use this file for current-state facts. Use the docs below for workflows and playbooks.
docs/agent-handbook.mdis the handbook for agent and human contributors working on n3 API, SDK, and plugins.docs/sdk-examples-and-best-practices.mdprovides detailed SDK examples, side-by-side proper/improper comparisons, and code templates.docs/beginner-scripting-guide.mdoutlines essential tick-engine concepts, safety rules, and beginner walkthroughs.docs/agent-plugin-production-loop.mdcovers the idea-to-implementation loop.docs/agent-testing-loop.mdcovers compile, test, live evidence, failure taxonomy, and iteration limits.docs/agent-runtime-tools.mdrecords current inspection tools and the future local-only live evidence harness design.tools/agent-mcpexposes Agent Server REST endpoints as local MCP stdio tools for checking client state and issuing explicit commands. The RuneLite plugin also exposes direct/mcpStreamable HTTP MCP tools.