Skip to content
3 Death Saves

API and Hooks

Wiki updated as of 0.7.0 (Oct 2026)
const api = game.modules.get('peddler').api;
// or
const api = globalThis.Peddler;

The API is assigned during the Foundry ready hook. Listen for peddler.ready instead of ready to be sure it exists.

MemberSignatureNotes
versiongetterThe installed module version string, or null.
openShopopenShop({ shopUuid, userId, startNodeId } = {})Async. Opens the vignette for a shop actor UUID. userId defaults to the current user. startNodeId enters the tree at that node and skips the opening-hours check. Returns the vignette, or null if entry was refused.
enterShopFromRegionenterShopFromRegion(event, shopUuid)Async. For an Execute Script region behavior. On tokenEnter, asks the token’s owner to confirm, then opens the shop.
openShopSettingsopenShopSettings(shopActor)Opens the shop settings window for a shop actor, reusing an open one. Returns a promise for the window.
setupShopsetupShop(actor, archetypeId = null, { quiet, concurrency } = {})Async, GM only. Converts an actor into a shop, creates its dialogue journal, and returns the journal page. Pass null for a blank tree. quiet suppresses the notifications.
archetypesgetterArray of valid archetype ids for setupShop. See Shop Archetypes.
openTreeEditoropenTreeEditor(page)Opens the Dialogue Tree Editor for a journal entry page, or brings its open editor to front.
notifynotify(message, { type, timeout, permanent, anchor } = {})Shows a Peddler toast and returns { dismiss }. Shorthands: notify.info, notify.success, notify.warn, notify.error.
getShopConfiggetShopConfig(actor)The actor’s validated, normalized shop configuration, or null when the actor is not a shop.
updateShopConfigupdateShopConfig(actor, changes)Async. Merges changes into the shop configuration. Returns { ok: true, config }, or { ok: false, reason: 'validation', errors }.
runRestockrunRestock(shopActor, options = {})Async. Runs a restock cycle. Returns the restock summary with ok: true, or { ok: false, reason }.
setActorModifiersetActorModifier(shopActor, buyerActor, patch)Async. Merge-patches one buyer’s price modifiers on a shop. The patch takes buy, sell, perItem keyed by item id with its own buy and sell, and a source string. Values must be zero or greater.
setGoodwillBasesetGoodwillBase(shopActor, buyerActor, value)Async. Sets a base goodwill value for one buyer at a shop. It adds to the goodwill the buyer earns in play. Returns { ok: true, value }.
setGoodwillRungssetGoodwillRungs(shopActor, rungs)Async. Replaces the shop’s goodwill rung thresholds with an array of numbers. Returns { ok: true, rungs }.
registryobjectregisterPredicate(id, definition), registerEffect(id, definition), and registerFilter(id, definition) add entries to the Dialogue Tree Editor. ids() returns { predicates, effects, filters }.

runRestock, setActorModifier, setGoodwillBase, and setGoodwillRungs run on the primary GM’s client. A player caller needs owner permission on the shop actor. Failures return { ok: false, reason } with validation, permission, no-gm, or rollback.

Registering predicates, effects, and filters

Section titled “Registering predicates, effects, and filters”

Ids must be namespaced as <module-id>.<name>. An unnamespaced or already registered id is refused and returns null.

A predicate takes { label, description, args, evaluate(args, scope) } and returns a boolean. A filter takes { label, args, match(item, args, scope) }.

An effect takes { label, kind, args, apply } and an optional gmOnly. The kind decides where apply runs:

  • remote runs apply(args, scope, { user, sessionId }) on the primary GM’s client and may return an outcome object. A gmOnly remote effect requested by a player is refused.
  • client runs apply(args, scope) on the shopping player’s client.
  • local runs apply(args, scope) immediately, wherever the choice is taken. gmOnly has no effect on it.

Payloads are a single object argument unless noted.

HookFires whenClientPayload
peddler.readyThe API has been assigned.AllThe API object.
peddler.preOpenShopBefore a vignette opens. Return false to cancel.Shopper{ shopActor, userId }
peddler.openShopThe vignette is created, before its first render.Shopper{ shopActor, userId, sessionId }
peddler.sessionStartThe vignette has rendered and the session is live.Shopper{ session }
peddler.nodeEnterThe walker enters a node.Shopper{ session, node }
peddler.nodeExitThe walker leaves a node through a choice.Shopper{ session, node, choice }
peddler.choiceMadeA choice resolves, including free-text matches.Shopper{ session, choice }
peddler.sessionEndThe session ends.Shopper{ session, reason }
peddler.preTradeBefore a trade is priced and committed, after its lines are validated. Return false to cancel.Primary GM{ shopActor, buyerActor, lines, user }
peddler.tradeA trade commits.Primary GM{ shopActor, buyerActor, summary }
peddler.tradeRollbackA trade fails mid-commit and its changes are undone.Primary GM{ shopActor, buyerActor, reason, lines, total, rollbackFailed }
peddler.theftA theft attempt succeeds.Primary GM{ shopActor, buyerActor, item }
peddler.theftCaughtA theft attempt is caught.Primary GM{ shopActor, buyerActor, item }
peddler.discoveryA discovery attempt resolves.Primary GM{ shopActor, buyerActor, found, itemName }
peddler.queueJoinA player joins a queued shop. position is 0 when they go straight in.Primary GM{ shopActor, userId, position }
peddler.queueLeaveA player leaves a queued shop.Primary GM{ shopActor, userId }
peddler.queueAdvanceThe next player in a queue becomes the active shopper.Primary GM{ shopActor, newActiveUserId }
peddler.shopOpenedWorld time passes a scheduled shop’s opening hour.Primary GM{ actor, time }
peddler.restockA restock cycle completes.Primary GM{ actor, restocked, added, refilled, deleted, unresolved }
peddler.tradeRequestedA player-to-player trade is requested.Both tradersThe trade session.
peddler.tradeExecutedBoth sides of a player-to-player trade confirm and the exchange runs.Both tradersThe trade session.
peddler.tradeCancelledA player cancels a player-to-player trade.Cancelling playerThe trade session.

When a GM triggers a primary-GM action, it runs on that GM’s own client instead. The commit queries behind peddler.trade and peddler.tradeRollback are internal. Use these hooks as the trade integration point.

A peddler.preTrade listener may mutate the lines array. Each line carries itemId, quantity, direction, and paymentIndex. Lines are re-validated after the hook, and an empty or malformed cart fails the trade with validation.

The trade summary is { added, sold, total, currency, containerWarnings, purchaseWarnings }. added and sold are arrays of { name, qty, uuid, itemId }, where uuid is the source item and itemId is the item created on the receiving actor, or null.

On peddler.restock, added counts items created on the shop actor. unresolved counts table results that pointed at a missing document or something other than an Item.

The player-to-player trade session is { tradeId, a, b, state }. Each side is { actorUuid, userId, items, coins, stage }.

The Fire hook effect in the Dialogue Tree Editor calls peddler.<name> on the primary GM’s client.

Transaction nodes resolve to one of four outcome strings:

  • success
  • insufficient_funds
  • out_of_stock
  • cancelled

When a Transaction node has no choice for the outcome, the walker falls back to its cancelled choice. A peddler.preTrade listener returning false resolves the transaction as cancelled.

System support ships inside the module, with no adapter registration API. See System Adapters.

Peddler requires 3DS Atlas. Atlas supplies Peddler’s theming, window frames, and console logging, and names the primary GM that runs automation and commits trades. See Themes and Chassis.