Manual › Scripting API › Items
Inventory, equipment and bank
Inventory & Equipment #
Inventory.items(): InvItem[]
Inventory.first(name: string): InvItem | null
Inventory.contains(name: string): boolean
Inventory.count(name: string): number // total qty across stacks/slots
Inventory.countById(id: number): number // exact object ID across stacks/slots
Inventory.used(): number // occupied slots
Inventory.free(): number // unoccupied slots (0 if normal pack UI is unavailable)
Inventory.isFull(): boolean
Equipment.items(): InvItem[]
Equipment.contains(name: string): boolean
Equipment.equip(name: string): Promise<boolean> // Wield/Wear/Equip from pack
Equipment.unequip(name: string): Promise<boolean> // Remove into pack
InvItem #
class InvItem {
name; id; slot; count;
actions(): string[];
interact(action: string): boolean | Promise<boolean>; // held op, e.g. 'Bury', 'Eat'
useOn(target: InvItem | Loc | Npc): boolean | Promise<boolean>;
}
While the bank is open, these queries read the bank's side-backpack component.
Once populated, its counts and capacity remain authoritative even though the
normal inventory tab is hidden. The side snapshot can populate one tick after
the main bank component;
Bank.withdrawX* waits for that handoff before recording its baseline. Side-view
InvItem actions are the visible Deposit-* component buttons, and useOn
returns false until the bank is closed.
useOn is "use X with Y" behind every processing skill, knife→logs,
raw fish→range, ess→altar. Returns false if a loc target is off-scene.
const raw = Inventory.first('Raw shrimps');
const range = Locs.query().name('Range').within(3).nearest();
if (raw && range) await raw.useOn(range);
Bank #
Low-level bank UI. Prefer Banking.open to walk to and open a bank;
use Bank.* once the interface is open.
Bank.isOpen(): boolean
Bank.ready(): boolean // the bank has said what it holds, empty included
Bank.waitReady(timeoutMs?, log?): Promise<boolean>
Bank.snapshotGeneration(): number // take before a deposit
Bank.snapshotReady(): boolean // the bank-side view has been captured
Bank.waitSnapshotAfter(gen, timeoutMs?): Promise<boolean> // wait for the list that follows
Bank.loaded(): boolean // item list is non-empty; false for an empty bank
Bank.setNoteMode(on: boolean): Promise<void>
Bank.items(): BankItemSnapshot[] // { slot, id, name, count, ops, comId }
Bank.count(name: string): number // exact name, case-insensitive
Bank.countById(id: number): number // when two objects share a display name
Bank.withdraw(name: string, op?: string): boolean | Promise<boolean>
Bank.withdrawById(id: number, op?: string): boolean | Promise<boolean>
Bank.withdrawX(name: string, count: number): Promise<boolean> // Withdraw-X + dialog
Bank.withdrawXById(id: number, count: number): Promise<boolean>
Bank.withdrawLoad(name: string): Promise<boolean> // All, else X for free slots
Bank.deposit(name: string, op?: string): boolean | Promise<boolean>
Bank.depositInventory(): Promise<void>
Bank.depositAllMatching(match: (name, id) => boolean, log?): Promise<void>
Bank.close(timeoutMs?: number): Promise<boolean> // waits for main + side modal halves
Bank.openBooth(stand, boothName, op, log?): Promise<boolean>
Bank.openNearest(boothName, op, log?): Promise<boolean>
Bank.openNearestAccess(access, log?): Promise<boolean>
// Pick a real withdraw label from item.ops ("Withdraw-All" vs "Withdraw All")
withdrawOp(ops, amount: 'all' | '10' | '5' | '1' | 'x' | 'any'): string | null
Gotchas
Bank.open*already waits for the item list, socount()/items()are good on the next line.- After a deposit
ready()is already true and will not block. TakesnapshotGeneration()before the deposit and wait onwaitSnapshotAfter(gen). - Test emptiness with
ready(), neverloaded().loaded()is "the list is non-empty", so an empty bank never satisfies it and a still-loading bank is indistinguishable from a drained one. withdraw/deposit/countmatch names in full (case-insensitive).opis the context-menu label; usewithdrawOp(item.ops, 'all')rather than hard-coding'Withdraw-All'.- Prefer
countById/withdrawById/withdrawXByIdwhen two objects share a display name. - Do not hand-roll walk + booth click in new scripts, use
Banking.open.
if (!(await Banking.open({ stand: bankTile }))) return;
await Bank.depositAllMatching(depositAllExcept(['Harpoon', 'Fishing bait']));
await Bank.withdrawLoad('Fishing bait');
await Bank.withdrawX('Feather', 100);
// or by id when names collide:
// await Bank.withdrawById(someId, op);