3 Macro Reference
Flaig edited this page 2026-10-05 15:24:52 +02:00

Macro Reference

A macro is the body of an async function. It gets four names: swade holds everything that comes from the SWADE action, and fx, sequence() and preview are this module's helpers. No wrapper, import or args lookup is needed. Create a sequence with sequence() and finish with await s.play(). Check values that can be null when a macro is meant for several events, or for actors without a token on the scene.

If you prefer short names, unpack them at the top: const { caster, targets, hit } = swade;.

The editor's Variables and helpers panel lists all of this: search it, click a row to insert it, see which rows your code uses and, after Play, the value each swade.* and t.* field had.

Changed in 0.2.0: the action's data moved into swade. Macros written for 0.1 that use bare names such as caster, targets or hit stop with an error until you add swade. in front. Two bare names don't fail but read something else: target (TokenMove's global, when TokenMove is active) and event (the browser's).

Event and document variables

Variable Meaning
swade.event trait, damage, template, effect or consume
swade.caster The acting token on the scene, preferring a selected token of the actor; or null
swade.targets Array of target entries (see below), not raw tokens
swade.target The first target's token, or null
swade.item, swade.actor The item and its actor, or null
swade.action { key, kind, name } or null. The key is formula for the main trait roll, damage for the main damage roll, the action's ID for additional actions, or the row name (template, effect, consume)
swade.roll, swade.message The SWADE roll and its chat message; null in previews and for events without a roll
swade.template Template information on a template event, otherwise null
swade.effect The created active effect on an effect event, otherwise null
preview True when played from the editor or the assignment window

Trait results

swade.hit, swade.raise, swade.miss, swade.outcome and swade.margin describe the first target. swade.critfail describes the trait roll itself, with or without targets, and swade.fizzle a failed power activation. Without a trait result, hit, raise and miss are false and outcome and margin are null; this includes powers rolled without a target, so check swade.fizzle for those.

Every entry t in swade.targets has:

Field Meaning
token The target's token
outcome hit, raise, miss, critfail, or null
hit, raise, miss, critfail Results for this target; a raise is also a hit, a Critical Failure also a miss
tn, margin, raises Target number, roll total minus target number, number of raises
adjacent The target's and caster's token bounds touch or overlap
distance Center-to-center distance in grid units, or null
damage On damage events: { toughness, margin, shaken, wounds }, or null
shaken, wounds Shortcuts to the damage result on damage events

Target numbers are the target's Parry for melee attacks and for ranged or thrown attacks against an adjacent target, otherwise 4; Bolt against an adjacent target uses the higher of 4 and Parry. With SWADE Clarity active (and its setting on), Clarity's per-target target numbers take precedence, and targets captured in its roll dialog replace your current targets. See Troubleshooting and Limits before you use these values as rules automation.

swade.attack is { mode, skill, rof }. mode is melee, ranged, thrown, power or null; skill is the SWADE ID of the rolled skill when known. rof is informational: the module does not split a Rate of Fire roll into dice per target.

swade.power, for powers, is { trapping, element, activated, raise }, and null for other items (use swade.power?.element). element is read from English or German words in the trapping, then the item name, or null. swade.power.raise is a raise on the activation roll, which is not the same as a raise against a target (t.raise).

swade.damage, on damage events, is { total, raise }. raise means SWADE's bonus damage die was rolled (in previews: a stand-in). The per-target damage fields are estimates for the animation; nothing is applied.

Template information

swade.template is { document, preset, shape, size, center, origin, end, direction }. document is the RegionDocument. preset is sbt, mbt, lbt, cone, smallCone, stream or custom. size is the circle radius, cone length or line length in grid squares. Points are canvas pixels; direction is in degrees for cones and lines.

The presets are circles of radius 1, 2 and 3 squares, cones 9 and 4 squares long, and a stream 12 squares long and 1 wide. Circles, cones and lines of other sizes keep their full geometry: a custom cone still has its tip (origin), end and direction. Other shapes get the center of their bounds, with origin and end at that center. fx.templateSize() returns { squares, px, diameterPx, widthPx }; use widthPx for a stream's width.

Helpers

Call What it does
fx.missPoint(t, { style = "auto" }) Canvas point a miss flies to; styles auto (by margin), past, short, wide. With auto, a near miss lands just outside the target's edge and a clear or wild miss a little further out; a Critical Failure drops short or goes a bit wider. The same within one run
fx.edgePoint(t, { inset = 0.15 }) Point on the target's edge facing the caster, moved inward by inset of its radius
fx.shake(token, { strength = 8, duration = 400, smoothness = 0.37 }) Shakes the token's picture on every screen; it moves at most strength / 2 pixels, duration in ms, lower smoothness moves more often; nothing to await
fx.nudge(token, { from = caster, distance = 0.25, duration = 300 }) Pushes the picture away from from and back on every screen; distance in grid squares; returns a Promise
fx.shakeScreen({ strength = 6, duration = 400 }) Sequencer camera shake; returns the playback Promise
fx.forEachTarget(fn, { stagger = 0 }) Awaits fn(t) for each target in turn; with stagger, starts them stagger ms apart and awaits them all
fx.templateSize(tpl = swade.template) Template sizes, or null
fx.has(key) Whether the key exists in the Sequencer database; does not check file paths
fx.wait(ms) Promise that resolves after ms
fx.element(item = swade.item) Element named by the trapping or item name, or null
fx.random() Seeded random number in [0, 1)

Helpers that take a target accept either t or t.token. from in fx.nudge can also be a canvas point { x, y }. The random seed is the chat message's ID, so replaying a roll gives the same results; previews use a fresh seed.

sequence() returns a Sequencer Sequence with Sequencer's full API, for example .filter("ColorMatrix", { hue: 180 }), .scaleToObject(1.2) or .waitUntilFinished(-250). await s.play() does not necessarily wait until every effect has finished; use section waits when the timing matters.

API for Foundry script macros

const trappings = game.modules.get("swade-trappings").api;
await trappings.openLibrary();
await trappings.openAssignments(item);

Also available:

  • openLibrary(entryId): opens the library at an entry; returns a Promise for the window.
  • library(): the current library data, for reading.
  • assign(item, actionKey, macroId): assigns a macro to an item action; you need permission to update the item.
  • pickAsset(options): opens the asset picker; resolves to the chosen key, or null when closed.
  • runEntry(id, partialContext): plays a saved entry with the context you pass. Provide whatever its code needs, at least the caster and targets; targets here is an array of tokens, not target entries, and defaults to empty. The macro reads these fields under swade (swade.caster, swade.targets …). This only plays the animation; it rolls nothing and triggers no SWADE action.
await trappings.runEntry("YOUR_ENTRY_ID", {
  caster: canvas.tokens.controlled[0],
  targets: [...game.user.targets],
  item
});