Exchange System

The exchange system handles two modes of item transfer between inventories: loot (free taking) and trade (buying/selling with currency).


Two Modes

ModeDescriptionUse Case
lootFree item transfer, no currency involvedTreasure chests, corpse looting, storage
tradeItems have prices, currency is exchangedShops, merchants, trading NPCs

Opening an Exchange

Use actions to open exchanges:

ActionDescription
{loot: "inventory_id"}Open loot UI with inventory
{trade: "inventory_id"}Open trade UI with inventory

Both actions are event delayed - they wait for the current scene to finish before opening.

The exchange UI shows two inventories side by side:

  • Left: Party inventory (_party_inventory)
  • Right: Exchange inventory (the one you specified)

Clicking items moves them between inventories. In trade mode, currency is automatically exchanged.


Currencies

Currencies are regular items with is_currency: true set in their template.

FieldDescription
is_currencyMark item as currency (appears in currency bar)
priceBase price in various currencies

Example currency item:

FieldValue
idgold
is_currencytrue
traits.name"Gold"
traits.image(coin icon)
max_stack-1 (unlimited stacking)

Setting item prices:

FieldValue
price.gold100
price.gems5

Items can have prices in multiple currencies. The buyer must have all required currencies.


Modifying Trade Prices

The trade_init event fires for each item when a trade opens. Use it to set custom buy/sell prices.

PropertyWhat it controls
item.priceBase price (from template, read-only)
item.tradePrice.playerWhat trader pays when buying from player
item.tradePrice.traderWhat trader charges when selling to player

Example - Merchants buy at 50% price:

game.on("trade_init", (traderInventory, item) => {
  for (const currency in item.price) {
    item.tradePrice.player[currency] = Math.round(item.price[currency] * 0.5);
  }
});

Example - Mage trader only accepts arcane items:

game.on("trade_init", (traderInventory, item) => {
  if (traderInventory.tags.includes("mage_trader") && !item.tags.includes("arcane")) {
    item.tradePrice.player = {};  // Can't sell to this merchant
    item.tradePrice.trader = {};  // Can't buy from this merchant
  }
});

Currency Methods

MethodDescription
inventory.getCurrencyAmount(currencyId)Get total of a specific currency
inventory.getCurrencies()Get all currencies as { id: amount }
inventory.canAffordPrice(price)Check if can afford { gold: 100, gems: 5 }
inventory.deductCurrency(price)Pay with currency (returns false if can't afford)

Currency only counts unequipped items - equipped currency items are not spendable.


Exchange Events

EventWhen it firesParameters
inventory_openExchange UI opens(inventory)
inventory_closeExchange UI closes(inventory)
inventory_transferItem moves between inventories(source, target, item, quantity, isTrade)
trade_initTrade opens, for each item(traderInventory, item)

Canceling transfers:

Return false from inventory_transfer to prevent the transfer:

EventCheckResult
inventory_transferitem.traits.is_quest_itemreturn false (can't sell quest items)

Trade Flow Example

StepActionResult
1Player clicks item in merchant inventoryCheck if party can afford price
2Party can affordDeduct currency from party inventory
3Currency deductedAdd currency to merchant inventory
4Currency transferredMove item from merchant to party

If any step fails (can't afford, inventory full), the whole transaction is cancelled.


Creating a Shop

StepWhat to do
1Create inventory template with shop items
2Set prices on each item template
3Create a currency item (gold, coins, etc.)
4Give player starting currency
5Use {trade: "shop_id"} action to open

Quick Reference

I want to...Do this
Open a shop{trade: "shop_id"}
Open a loot container{loot: "chest_id"}
Check player goldinventory.getCurrencyAmount('gold')
Check if can buyinventory.canAffordPrice({ gold: 100 })
Modify trade pricesListen to trade_init event
Prevent item transferReturn false from inventory_transfer
Create a currencySet is_currency: true on item template

Next Steps

  • Overview - Item basics and templates
  • Apply - Crafting and custom apply logic