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

Examples

Paste one of these into a library entry and set the entry's event to the one in the heading. Fill the empty asset strings with Insert asset or a file path Foundry can reach; no art is included. Save the entry and assign it to a row of the same event.

Projectile with hits and misses (trait)

const PROJECTILE = "";
const IMPACT = "";
const SIZE = 1;
if (!PROJECTILE || !swade.caster) return;

const s = sequence();
for (const t of swade.targets) {
  s.effect().file(PROJECTILE).atLocation(swade.caster)
    .stretchTo(t.hit ? t.token : fx.missPoint(t))
    .waitUntilFinished(-250);
  if (t.hit && IMPACT) s.effect().file(IMPACT).atLocation(t.token)
    .scaleToObject(t.raise ? SIZE * 1.3 : SIZE);
}
await s.play();

Cast on the targets, or on yourself (trait)

const EFFECT = "";
const SIZE = 1.2;
if (!EFFECT || !swade.caster || swade.fizzle) return;

const s = sequence();
const recipients = swade.targets.length ? swade.targets.map(t => t.token) : [swade.caster];
for (const token of recipients) {
  s.effect().file(EFFECT).atLocation(token).scaleToObject(SIZE);
}
await s.play();

This macro mentions swade.fizzle and returns on a failed activation itself. Without that, the Skip failed activations setting would skip it on a failure anyway, because it skips every power macro whose code does not mention fizzle.

Explosion on a blast template (template)

const EXPLOSION = "";
const SIZE = 1;
const { template } = swade;
if (!EXPLOSION || !template || template.shape !== "circle") return;

const s = sequence();
s.effect().file(EXPLOSION).atLocation(template.center)
  .size(fx.templateSize().diameterPx * SIZE);
await s.play();

Assign this to the Template placed row, not to the power's trait row. The preview creates a temporary template; in play, the macro uses the template SWADE places.

Push back wounded targets (damage)

if (!swade.caster) return;
await fx.forEachTarget(async t => {
  if ((t.wounds ?? 0) > 0) {
    await fx.nudge(t.token, { from: swade.caster, distance: 0.25, duration: 300 });
  }
}, { stagger: 100 });

t.wounds is the module's estimate of the damage result, used here for feedback only. Nothing inflicts Wounds, and the token's saved position never changes.

Lunge and recoil with TokenMove (trait)

Needs the TokenMove module. The attacker lunges, and on a hit the target recoils at the moment of impact; both return to their places.

if (!swade.caster || !swade.target || swade.target === swade.caster) return;
const move = TokenMove.between(swade.caster, swade.target).on("source").lunge();
if (swade.hit) move.on("target").at("impact").offset({ direction: "backward", tokens: 0.3, ease: "easeOutBounce" });
await move.play();

Use swade.caster and swade.target, not TokenMove's source and target globals: those are your current selection and targets, which need not be the roll's.

For lasting template fills and auras, start from the Lasting area or Aura starter and keep their preview branch and their tieToDocuments call. See Starter Templates.