Skip to content
3 Death Saves
Wiki updated as of 0.3.0 (Aug 2026)

API and Hooks

Peddler exposes a small API for macros and other modules, and fires namespaced hooks at every significant point in a shopping session.

The same object is available two ways once the module is ready:

const api = game.modules.get('peddler').api;
// or
const api = globalThis.Peddler;

The API is assigned during the Foundry ready hook. To be sure the API exists before you touch it, use peddler.ready instead of ready.

MemberSignatureNotes
versiongetterReturns the installed module version string, or null.
openShopopenShop({ shopUuid, userId } = {})Async. Opens the vignette for the given shop actor UUID. userId defaults to the current user. Returns the vignette application, or null if entry was refused.
openShopSettingsopenShopSettings(shopActor)Async. Opens the shop settings window for a shop actor, reusing the window already open for that actor. Returns the settings application.
setupShopsetupShop(actor, archetypeId = null)Async, GM only. Converts an actor into a shop, creates its dialogue journal, and returns the created journal page. Pass null for a blank tree.
archetypesgetterReturns the array of valid archetype id strings for setupShop. See Shop Archetypes.
openTreeEditoropenTreeEditor(page)Opens the Dialogue Tree Editor for a journal entry page. Brings an existing editor for that page to front.
notifynotify(message, { type, timeout, permanent, anchor } = {})Shows a Peddler-styled toast and returns { dismiss }. Shorthands: notify.info, notify.success, notify.warn, notify.error.
getTrustgetTrust(shopActor)Returns { key, value, steps } for the shop archetype’s trust counter, or null when the actor is not a shop. steps is the archetype’s ladder of rung values.
setTrustsetTrust(shopActor, value)Async. Sets the shop’s trust counter to an absolute value, routed to the primary GM. Returns { ok: true, value } when the value is already set, or { ok: false, reason: 'validation' } for a non-shop actor or a non-numeric value.
runRestockrunRestock(shopActor, options = {})Async. Runs a restock cycle for a shop actor. Routes to the primary GM, so a player caller needs ownership of the actor. Returns the restock result, or { ok: false, reason }.
getShopConfiggetShopConfig(actor)Returns the actor’s validated and normalized shop configuration, or null when the actor is not a shop.
updateShopConfigupdateShopConfig(actor, changes)Async. Merges changes into the shop configuration and writes it to the actor. Returns { ok: true, config }, or { ok: false, reason: 'validation', errors } when the merged result fails validation.
setActorModifiersetActorModifier(shopActor, buyerActor, patch)Async. Merge-patches one buyer’s entry in a shop’s per-actor price modifiers. 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. Runs on the primary GM’s client; a player caller needs owner permission on the shop actor. Returns { ok: true }, or { ok: false, reason } with validation, permission, no-gm, or rollback.
registrygetterRegistration surface for other modules. registry.registerPredicate(id, definition), registry.registerEffect(id, definition), and registry.registerFilter(id, definition) add entries usable in the Dialogue Tree Editor. Ids must be namespaced as <module-id>.<name>. An unnamespaced id or one that is already registered is refused and returns null. registry.ids() returns { predicates, effects, filters }.

A registered effect definition takes { label, kind, args, apply } and an optional gmOnly. A remote effect runs its apply(args, scope, { user }) on the primary GM’s client and may return an outcome object. A client effect runs apply(args, scope) on the shopping player’s client. A local effect runs apply(args, scope) immediately, wherever the choice is taken, with no round trip to the GM; gmOnly has no effect on it. A gmOnly remote effect asked for by a player is refused.

All hook names are prefixed with peddler.. Payloads are a single object argument unless noted.

HookFires whenPayload
peddler.readyThe module API has been assigned.The API object itself.
peddler.preOpenShopBefore a vignette opens. Return false from a listener to cancel the open.{ shopActor, userId }
peddler.openShopThe vignette is created, before its first render.{ shopActor, userId, sessionId }
peddler.sessionStartThe vignette has rendered and the session is live.{ session }
peddler.nodeEnterThe walker enters a node.{ session, node }
peddler.nodeExitThe walker leaves a node through a choice.{ session, node, choice }
peddler.choiceMadeThe player picks a choice, including free-text matches.{ session, choice }
peddler.preTradeBefore a trade is priced and committed, after its lines are validated. Return false from a listener to cancel the trade.{ shopActor, buyerActor, lines, user }
peddler.tradeA trade commits successfully.{ shopActor, buyerActor, summary }
peddler.tradeRollbackA trade fails mid-commit and its document changes are undone.{ shopActor, buyerActor, reason, lines, total }
peddler.sessionEndThe session ends.{ session, reason }
peddler.shopOpenedWorld time advances past a scheduled shop’s opening hour. Primary GM client only.{ actor, time }
peddler.restockA shop restock cycle completes. Primary GM client only.{ actor, restocked, added, refilled, deleted, unresolved }

A peddler.preTrade listener may mutate the lines array. A line whose price is set to { abbr, amount } uses that value in place of the item’s base value, and still passes through the shop’s price modifiers. Lines are re-validated after the hook, so a listener that empties or corrupts the cart fails the trade with validation.

Session hooks fire on the shopping player’s client. Trades commit on the primary GM’s client over Foundry’s query system, so peddler.trade and peddler.tradeRollback fire there. Treat these two hooks as the trade integration point; the underlying queries are internal and not public API. A macro that reacts to a trade should account for running on that one client.

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

On peddler.restock, added counts the items actually created on the shop actor and unresolved counts table results that pointed at a missing document or something other than an Item. The rollback lines are the priced trade lines and total is the priced trade total.

A choice in the Dialogue Tree Editor can also fire a custom hook under the peddler. prefix through its effect list, with an author-defined payload.

Transaction nodes resolve to one of four outcome strings:

  • success
  • insufficient_funds
  • out_of_stock
  • cancelled

The tree routes on the outcome. When a Transaction node has no dedicated choice for insufficient_funds or out_of_stock, the walker falls back to its cancelled choice. A peddler.preTrade listener returning false also resolves the transaction as cancelled.

System support ships inside the module; there is no adapter registration API. See System Adapters for what each system integration covers.

Peddler requires 3DS Atlas. It registers itself with Atlas for shared theming under the .peddler scope, routes its console output through the Atlas logger, and reads the primary GM from Atlas to decide which client runs automation and commits trades. Atlas owns the window frames and the base palette of every Peddler application. See Themes and Chassis.