Restocking
Restocker is a Grand Exchange helper that works with loadout depletion listeners.
Use it when a script should detect missing bank items, buy them, collect them, and then continue preparing its loadout.
Basic Flow
Restocker restocker = Restocker.create()
.defaultAmount(100)
.defaultBuyPrice(GrandExchange.Price.live().plus5())
.defaultSellPrice(GrandExchange.Price.live().minus5())
.defaultCollectionMode(GrandExchange.CollectionMode.BANK);
InventoryLoadout inventory = InventoryLoadout.create()
.add(LoadoutItem.of(ItemId.SHARK).amount(10).build())
.depletionListener(restocker);
When Loadouts.withdraw(inventory) cannot find a required item in the bank, the restocker queues a buy request.
Your script should then enter a restocking branch:
if (!restocker.empty()) {
restocker.tick();
return;
}
Loadouts.withdraw(inventory, equipment);
tick() performs at most one meaningful Grand Exchange step and returns. Call it repeatedly until restocker.empty() is true.
Register Preferred Amounts
Register items up front when depletion should buy a specific amount.
restocker
.item(ItemId.SHARK, 100)
.price(GrandExchange.Price.live().plus5())
.retryAfterTicks(100)
.maxRetries(3);
When sharks deplete, this buys 100 instead of the restocker default amount.
Queue Buys Directly
restocker.request(ItemId.SHARK, 100);
Or use the configured amount:
restocker.request(ItemId.SHARK);
Queue Sells
restocker.sell(ItemId.MAGIC_LOGS, 100, GrandExchange.Price.live().minus5());
Or:
restocker.requestSell(ItemId.MAGIC_LOGS, 100);
For selling, the restocker withdraws the item first if it is not carried. If the item is not stackable and has a noted form, it prefers withdrawing the noted ID for easier selling.
If the requested sell item is not in the bank, the sell request is cleared.
Retry Behavior
Active offers can be cancelled and retried with more aggressive prices.
Restocker restocker = Restocker.create()
.defaultRetryAfterTicks(100)
.defaultMaxRetries(3);
Per item:
restocker.item(ItemId.SHARK, 100)
.retryAfterTicks(80)
.maxRetries(5);
For buy offers, each retry applies another +5% to the configured base price.
For sell offers, each retry applies another -5% to the configured base price.
request.offerPrice();
Collection Mode
Default:
restocker.defaultCollectionMode(GrandExchange.CollectionMode.BANK);
Per request:
restocker.item(ItemId.SHARK, 100)
.collectionMode(GrandExchange.CollectionMode.ITEM);
Available modes:
ITEMNOTEBANK
Restocking State
restocker.empty();
restocker.queued();
restocker.items();
restocker.clear();
clear() removes queued work but keeps configured restock items and defaults.
Complete Script Shape
public class ExampleScript {
private final Restocker restocker = Restocker.create()
.defaultAmount(100)
.defaultBuyPrice(GrandExchange.Price.live().plus5())
.defaultSellPrice(GrandExchange.Price.live().minus5())
.defaultCollectionMode(GrandExchange.CollectionMode.BANK);
private final EquipmentLoadout equipment = EquipmentLoadout.create()
.add(EquipmentSlot.WEAPON, ItemId.ABYSSAL_WHIP);
private final InventoryLoadout inventory = InventoryLoadout.create()
.add(LoadoutItem.of(ItemId.SHARK).amount(10).build())
.add(LoadoutItem.of(ItemId.DEATHRUNE).amount(200).stackable().build())
.depletionListener(restocker);
public void tick() {
if (!restocker.empty()) {
restocker.tick();
return;
}
if (!inventory.fulfilled() || !equipment.worn()) {
Loadouts.withdraw(inventory, equipment);
return;
}
// Normal script logic.
}
}
The important part is the branch order:
- Finish queued restocking.
- Prepare loadouts.
- Run normal script logic.
That keeps Grand Exchange work from fighting the bank/loadout flow.