n3Plugins AI Agent Handbook
Use this handbook when you build or review n3 API, SDK, or plugin work. It applies to human contributors and coding agents. Live source is the authority. Use this page to keep changes aligned with the repo.
Authority Order
- Live source under
src/main/javaandsrc/test/java. N3PLUGINS_SOURCE_OF_TRUTH.mdfor current registration, packages, action catalog, dependencies, validation, and runtime ownership.AGENTS.mdand local agent prompts.- Plugin docs under
docs/. - RuneLite client and API Javadocs when a callback, widget, or API contract matters.
Passing tests do not prove live RuneLite behavior. Mark live behavior pending until you observe it in the client.
Operating Rules
- Inspect
git status --short --branchand relevant diffs before editing. - Read
AGENTS.md,N3PLUGINS_SOURCE_OF_TRUTH.md, and the docs for the area you touch. - Use CodeGraph for structural discovery. Use
rgfor literal text, configuration, and documentation searches, then read only the focused files. - Keep changes scoped to the request. Avoid hidden refactors and tool-generated artifacts.
- Import Java types and use simple names in source. Keep fully qualified names inline only when two required types have the same simple name.
- State file-writing side effects before creating workflow files, screenshots, local harness output, or generated reports.
- Use
InteractionApi.actions.*for new game interactions. Return and inspectInteractionResult. - Use
sdk.*helpers before adding plugin-local equivalents. - Add source Javadocs for public declarations under
InteractionApiandsdk.ApiJavadocCoverageTestchecks coverage and rejects placeholder wording. - Do not add suite-level walker or pacer tick owners.
PacketUtilsPlugin.onGameTickownsActionPacer.onTick(...), bootstrap, andWalker.tick(). - Logged-in automation that requires account setup calls
PacketUtilsPlugin.requireAccountBootstrap(owner)while active, gates gameplay actions on the returned readiness, and releases the owner when idle or stopped. Passive overlays and bookkeeping may run outside that gate.
Repo Orientation
| Area | Source | Use it for |
|---|---|---|
| Shared plugin | com.n3plugins.PacketUtils | Revision setup, packet reflection, SDK init, bootstrap, pacer tick, walker tick, plugin-list branding |
| Action API | com.n3plugins.InteractionApi.actions | Result-aware interaction calls |
| Results | com.n3plugins.InteractionApi.common | InteractionResult, InteractionStatus, guards, matchers |
| Planning | com.n3plugins.InteractionApi.plan | TaskPipeline, TaskStep, StepResult, InventoryPlan, cooldown helpers |
| Pacing | com.n3plugins.InteractionApi.pacing | Suite-wide action pacing and diagnostics |
| Debug | com.n3plugins.InteractionApi.debug | SuiteRuntimeStatus, WidgetExplorer, PacketTrace, revision health checks |
| Widgets and items | com.n3plugins.sdk.widgets | Widget, inventory, bank, equipment, dialogue, shop, GE, rune-pouch helpers |
| Queries | com.n3plugins.sdk.query | Inventory, bank, equipment, NPC, player, object, item, widget, trade, and shop filters |
| ID maps | com.n3plugins.sdk.idmaps | Bundled and revision-cache ID map lookup |
| Walker | com.n3plugins.sdk.walker | Path planning, route handles, collision, transports, requirements |
| Loadouts | com.n3plugins.sdk.loadouts | Inventory and equipment targets |
| Workflow | com.n3plugins.sdk.workflow | AutomationApi, AutomationStateMachine, domain workflow builders |
| UI | com.n3plugins.ui | N3Theme, N3PluginPanel, cards, buttons, bundled brand asset |
For the full action catalog, use the SOT action table first, then open the matching class under InteractionApi.actions.
API Mapping Flow
- Write the workflow state or user action in plain terms.
- Search
InteractionApi.actions.*for a result-aware action class. - Search
sdk.*for a shared widget, query, walker, loadout, or workflow helper. - Use
GameVarsfor raw varbit or varplayer reads when no action class owns the state. - Use RuneLite API directly only when no n3 layer covers the operation.
- If more than one plugin would need a missing helper, add it to the shared SDK. If only one plugin needs it, keep it local.
ID-map queries use ItemQuery.withMappedName, NPCQuery.withMappedName, and TileObjectQuery.withMappedName. withName(...) means exact runtime-name filtering.
Spatial selection must state its distance reference and reachability rule. Use
nearestByPath() for player-relative actions or compose walkable() with
nearestToPoint(anchor) for stable work areas. Never use first() to implement
a documented nearest object, NPC, player, or ground-item action.
Plugin Creation Flow
- Domain review: verify OSRS mechanics, account requirements, combat risk, supplies, travel, banking, and live UI assumptions.
- Workflow design: pick the smallest driver that fits the behavior.
- SDK map: cite real classes and methods for each interaction.
- Implementation plan: name files, state, thread boundaries, registration, tests, docs, and live verification.
- Implementation: write the minimum code. Register in
runelite-plugin.propertiesonly when adding a plugin. - Tests: start with controller, workflow, parser, config, and state-machine tests that can run without a live client.
- Review: check correctness, timing, shared API usage, bootstrap gating, docs, and source consistency.
- Docs and SOT: update public behavior, new surfaces, registration, validation notes, and manual live gaps.
Driver Decision Matrix
| Shape | Use | Do not use |
|---|---|---|
| Plain per-tick handler | The game state drives the next action and you re-evaluate each tick, such as dialogue, gathering, or simple banking checks | Long fixed subflows where manual counters would creep in |
| MVC controller/runtime plugin | The plugin has many states, async data, persistent UI, or a testable runtime boundary, as Market Alcher does | Small loops with no panel or background work |
TaskPipeline | A fixed-order multi-tick sequence where success advances one step, such as open bank, withdraw, equip | Observation loops where the live game state should decide the next branch |
AutomationStateMachine | Branching, looping work with named states, recovery, and terminal success/error | Linear click chains that TaskPipeline can express |
| Domain workflow builders | Combat, production, banking, enchanting, or loadout work that matches an existing builder | New domain abstractions with one caller |
| Shared SDK helper | Two or more plugins need the same missing primitive | A plugin-specific workaround with no reuse path |
Testing Flow
- Run the narrowest meaningful Gradle suite first.
- For public API or Javadoc changes, run
.\gradlew.bat test --tests com.n3plugins.ApiJavadocCoverageTest --console plain. - Use JUnit 4 and Mockito 4.11. Do not use
mockStatic,MockedStatic, ormockito-inline. - Reset
ActionPacerin tests that touch pacing. - For
WidgetApi, set the testing adapter in@Beforeand reset it in@After. - Prefer runtime interfaces and pure state tests over live-client integration tests.
- Record live-only gaps in docs or final notes instead of pretending a unit test covers them.
See agent-testing-loop.md for the full compile, test, and live-evidence loop.
Review Flow
Review diffs in this order:
- User request and approved plan.
- Source/SOT consistency.
InteractionApi.actions.*,InteractionResult, and SDK reuse.- Bootstrap, pacer, walker, and client-thread ownership.
- Timing and anti-detection shape.
- Tests, docs, SOT, and manual live verification notes.
Use stop-slop on docs. Cut filler, cite real files, and avoid claims that source or live client evidence does not support.
Docs And SOT Sync
Update docs when public behavior, SDK surfaces, action contracts, plugin workflows, registration, validation, or live risks change. Update N3PLUGINS_SOURCE_OF_TRUTH.md when the canonical package map, registered plugin table, dependency list, action catalog, validation commands, or durable workflow conventions change.
Use Docusaurus-native admonitions for callouts: :::note, :::tip,
:::info, :::warning[Caution], and :::danger. Do not use GitHub callout
blockquotes such as > [!WARNING] in repo docs. When you touch a legacy
section that uses those formats or relies on italicized Note: labels for
important behavior, convert that touched section to the standard form. See
documentation-style-guide.md for the full authoring standard.
Keep the SOT short. Put detailed playbooks in docs and register them in
docs-site/sidebars.js so the Docusaurus site can find them.