Automation API
revision-sensitive RuneLite UI, packet, or in-game outcomes; treat those as live-client verification pending unless the page records direct evidence.
Automation code uses exactly two surfaces:
com.n3plugins.Api.actions.*— result-aware writes that returnInteractionResult(e.g.BankActions.withdraw,DialogActions.chooseOption,MagicActions.cast).com.n3plugins.sdk.query.*— read-only state access with fluent filters (e.g.Bank.search(),Inventory.getItems(),Dialogue.getOptions()).
There is no unified facade layer. Earlier sdk/widgets *Api classes (e.g. BankActions, Dialogue, Widgets, PrayerActions) were redundant delegation layers and have been removed; call the query or actions class directly.
Plugins that need ordered once-per-tick choices can compose these surfaces with sdk.combat.TickDecisionList. The list controls evaluation order and blocking; action APIs continue to own pacing and dispatch. See tick-decisions.md for the contract and combat examples.
if (Bank.isOpen() && Inventory.contains(ItemID.NATURE_RUNE)) {
BankActions.withdrawNoted(ItemID.NATURE_RUNE, 100);
}
Dialogue.DialogueOption option = Dialogue.getOptions().stream()
.filter(o -> o.getText().contains("Yes"))
.findFirst().orElse(null);
Spell names and packed widget IDs
MagicActions.resolveSpellInfo(name) resolves a non-blank friendly spell name to its packed widget ID. It derives its authoritative inventory from Api.actions.Spell. Each enum value contributes its normalized enum name and its InterfaceID-backed getWidgetId() value.
Optional<Integer> highAlchemy = MagicActions.resolveSpellInfo("High Level Alchemy");
if (!highAlchemy.isPresent()) {
// Unsupported, misspelled, or unavailable name: do not dispatch a widget action.
return;
}
int packedWidgetId = highAlchemy.get();
// Equals InterfaceID.MagicSpellbook.HIGH_ALCHEMY for this spell.
The resolver normalizes friendly punctuation, case, and the spell_ prefix before lookup. When an exact normalized match fails, the resolver retains its suffix matching for compatible friendly names. Treat an empty result as a configuration or input error. Do not replace it with a raw packed ID or a custom widget lookup.
Bank withdrawal with loadouts
BankActions.withdraw(InventoryLoadout, maxActions) withdraws missing loadout items with a depletion listener and an action cap:
loadout.setItemDepletionListener(item -> replan(item.getItemId()));
InteractionResult result = BankActions.withdraw(loadout, 10);
Ground-item action aliases
TileItemActions.resolveGroundActionIndex(actions...) maps friendly ground-item action aliases ("Take", "Pick up", "Op1".."Op5", ordinals) to menu action indices.
When to use which surface
Api.actions.*— writes that needInteractionResultstatus (e.g. distinguishingPACED/TARGET_NOT_FOUNDfrom a real failure, or bridging into aTaskPipelineviaStepResult.fromInteraction).sdk.query.*— read-only scene, inventory, bank, equipment, dialogue, minigame, or production state with fluent filters (seequery-helpers.md`).
All write paths route through the same ActionPacer gate, maintaining consistent pacing across all surfaces (see sdk-pipeline-guide.md §2).