Skip to main content

Widget And Item SDK APIs

com.n3plugins.sdk.widgets contains lower-level widget and item helpers used by AutomationApi, workflow builders, and plugin runtimes. These helpers are packaged SDK utilities, not RuneLite plugins.

Use the result-aware InteractionApi.actions.* classes when you need detailed failure statuses. Use these SDK APIs when a boolean/query surface is enough or when you are implementing a workflow Services adapter.

Core Widget API

WidgetApi is the raw widget boundary.

Packed widget IDs in production code should come from WidgetInfoExtended, WidgetID, RuneLite ComponentID, or gameval InterfaceID constants. If a component needs direct packed-ID targeting because normal action lookup cannot resolve it, add a named mirror constant and parity coverage instead of keeping a raw integer literal at the call site.

Methods:

  • get(packedId), get(groupId, childId), get(WidgetInfoExtended)
  • search()
  • click()
  • interact(widget, actions...)
  • interact(widget, menu, action)
  • interactOnWidget(source, destination)
  • raw interact(action, widgetId, childId, itemId) overloads
  • resumePause(widgetId, childId)
  • resumeCount(amount), resumeString(value), resumeName(value)

Tests can inject a fake adapter with setAdapterForTesting(...) and restore the live adapter with resetAdapterForTesting().

Inventory And Item Entries

InventoryApi exposes inventory reads and item-widget actions:

  • getItems()
  • find(itemId)
  • count(itemId)
  • contains(itemId)
  • emptySlots()
  • useItem(itemId, actions...)
  • useItem(widget, actions...)

ItemEntry is the value type returned by inventory, bank, shop, and GE helpers. It carries itemId, name, quantity, and the backing Widget. Calling interact(actions...) dispatches to the backing widget.

Production / Make-X / Smithing Reads

ProductionApi is the read-only side of the Make-X and legacy Smithing (Group 312) interfaces. It mirrors the useful read affordances exposed by bot-client production helpers without moving gameplay writes out of InteractionApi.actions.production.ProductionActions.

Use it to inspect the current interface before deciding which result-aware action to queue:

if (ProductionApi.isOpen()) {
Optional<ProductionProduct> shortbow = ProductionApi.findProduct("Shortbow");
Optional<ProductionQuantity> quantity = ProductionApi.selectedQuantity();

shortbow.ifPresent(product -> log.debug(
"Make option {} at child {} exposes actions {}",
product.getName(),
product.getChildIndex(),
product.getActions()));
}

Methods:

  • isOpen()
  • isEnterInputOpen()
  • products()
  • findProduct(itemId) and findProduct(name)
  • selectedProduct()
  • quantityButtons()
  • quantityButton(quantity)
  • selectedQuantity()
  • makeXQuantity()

ProductionProduct carries the one-based visible option index, item ID, product name, packed widget ID, child index, selected-state heuristic, visible action labels, and backing widget. ProductionQuantityButton carries the ProductionQuantity, packed widget ID, child ID, text, visibility, selected-state heuristic, and backing widget.

Product names are the item/widget names displayed by the Make-X interface. Some interfaces show an ingredient or intermediate widget name that is not exactly the item eventually produced. Selected product and selected quantity are widget-state heuristics and remain live-verification pending on the target RuneLite revision.

Writes still belong in ProductionActions:

InteractionResult result = ProductionActions.selectQuantity(ProductionQuantity.ALL);
if (result.succeeded()) {
result = ProductionActions.chooseOption("Shortbow");
}

Minigame / Grouping Reads

MinigamesApi reads the grouping tab/minigame teleport interface. Teleport writes stay in InteractionApi.actions.minigame.MinigameTeleportActions.

MinigamesSnapshot snapshot = MinigamesApi.snapshot();
if (snapshot.canTeleport()) {
MinigamesApi.destination(MinigameTeleport.PEST_CONTROL)
.filter(MinigameTeleportOption::isVisible)
.ifPresent(option -> log.debug("Teleport widget {}", option.getWidgetId()));
}

Methods:

  • snapshot()
  • isOpen()
  • canTeleport()
  • cooldownValue()
  • lastTeleportUsage()
  • destinations()
  • destination(destination)
  • selectedDestination()

MinigamesSnapshot exposes whether the tab is open, whether the cooldown varbit currently permits teleporting, the raw cooldown varbit value, the raw last-teleport varplayer value, and destination button snapshots.

MinigameTeleportOption carries the destination enum, display name, packed widget ID, child ID, visibility, selected-state heuristic, and backing widget. The selected destination marker and destination widget visibility are live-verification pending until observed in-client.

Bank And Equipment

BankApi exposes the boolean bank widget surface used by bank workflows:

  • isOpen()
  • getItems()
  • find(itemId)
  • count(itemId)
  • isWithdrawNoted()
  • setWithdrawMode(noted)
  • depositInventory(), depositEquipment()
  • withdraw(itemId, amount, noted)
  • withdraw(InventoryLoadout) and withdraw(loadout, maxActions)

BankStateApi is the read-only bank state facade. It exposes typed mode reads and stable widget descriptors so SDK callers do not need raw varbits or packed widget IDs:

  • snapshot()
  • withdrawMode() returning BankWithdrawMode
  • requestedQuantity()
  • placeholderMode() returning Optional<BankPlaceholderMode>
  • rearrangeMode() returning Optional<BankRearrangeMode>
  • supportedWidgets() and supportedWidget(name) returning BankWidget

BankWidget wraps the supported bank WidgetInfoExtended constants, including deposit inventory/equipment, equipment/settings buttons, containers, tabs, and scrollbar descriptors. Gameplay-changing clicks still belong in BankActions.click(BankWidget) or the existing result-aware bank actions.

EquipmentApi exposes equipped item reads:

  • getItems()
  • get(slot)
  • isEquipped(itemId)
  • setAdapterForTesting(adapter), resetAdapterForTesting()

EquippedItem carries itemId, name, slot, and an optional backing Widget. Live equipment reads include the backing widget for interactions; snapshot-only test entries may leave it null.

Dialogue

DialogueApi exposes a boolean/query dialogue surface:

  • isPresent()
  • getHeader(), getText(), getOptions()
  • snapshot()
  • continueDialogue()
  • selectOption(optionNumber)
  • selectOptionByIndex(index)
  • selectOption(optionText)
  • resumeNumericInput(amount), resumeStringInput(value), resumeNameInput(value)

DialogueSnapshot reports whether dialogue is present, whether a continue prompt is visible, the header/body text, and parsed options. DialogueOption contains the option index, widget ID, stripped text, and text color.

For dialogue actions and the auto-continue plugin, see dialogue-helper.md.

Shop And Shop Inventory

ShopApi reads and buys from the shop stock container:

  • isOpen()
  • getItems()
  • find(itemId)
  • count(itemId)
  • buy(itemId, ShopBuyQuantity)
  • buyOne, buyFive, buyTen, buyFifty
  • buy(widget, ShopBuyQuantity)

ShopBuyQuantity maps the SDK enum values to shop action strings through getAction().

ShopInventoryApi acts on the player's inventory while the shop interface is open:

  • isOpen()
  • getItems()
  • find(itemId)
  • useItem(itemId, actions...)
  • useItem(widget, actions...)

For the result-aware shop facade, see shop.md.

Grand Exchange Inventory

GrandExchangeInventoryApi acts on the inventory panel while the Grand Exchange interface is open:

  • isOpen()
  • getItems()
  • find(itemId)
  • offerItem(itemId)
  • offerItem(widget)

For GE interface state and standalone GE actions, see grand-exchange.md.

Rune Pouch

RunePouchApi reads rune-pouch contents:

  • contains(itemId)
  • containsAll(itemIds)
  • hasAmount(itemId, amount)
  • quantity(itemId)
  • setAdapterForTesting(adapter), resetAdapterForTesting()

Magic/enchanting flows use it to decide whether inventory runes are still required.

Testing

Most SDK widget APIs support setAdapterForTesting(...) and resetAdapterForTesting(). Use those hooks in tests; do not mock static methods. This matches the suite rule in CLAUDE.md that Mockito static mocking is not available in this project.