Register

Metamorph

An Add-on Module for Foundry Virtual Tabletop

Author: Gus77 Project: Source Foundry Versions 13 to 14 (Verified 14) Last Updated 1 week, 3 days ago

This module is free. Wanna do a cool thing?

ko-fi


Foundry v14 Github All Releases GitHub Release

Metamorph

Swap between sheets and tokens: any actor can have multiple forms. This module is a must for boss phases, polymorph spells, lycanthropes, shapeshifters, doppelgangers... System agnostic, check the Tutorial tab.

image

It's not just a change in appearance — it's a complete new character sheet each time, with its own data and abilities. You can share health between forms or keep them fully independent.


What It Does

A HUD button on any configured token opens a form picker. Click a portrait to instantly swap the token to that form. The token's appearance (portrait, size, bars, light, vision) updates from the target actor's prototype token. HP can optionally carry over.

image

There are two ways to populate the picker — use either, or both together.


Two Ways to Set Up Forms

Actor Forms — hand-picked (best for boss phases)

The simplest approach. Select an actor, go to the Actors tab, click Add Set, name it, then drag actors from the left panel (or from the Foundry actor sidebar) onto the drop zone. Each set shows up as its own tile in the HUD picker.

Filter Groups — query-based (best for druids / polymorph spells)

Define a query once, reuse it everywhere. Filters scan the world and compendiums at pick-time, so new actors that match automatically appear without re-configuring anything.

Groups are global — two druids in the party can share one "Wild Shapes" group.


Setup

Open the configuration window: scene controls toolbar → masks icon, or right-click any actor in the sidebar → Metamorph: Configure.

Actor Forms (Actors tab)

image

  1. Click an actor in the left panel → Actors tab.
  2. Set the HP on swap mode.
  3. Under Actor Forms → click Add Set, name it, drag actors from the left panel into the drop zone.
  4. Repeat for additional sets (e.g. Phase 1, Phase 2).

Filters tab

image

Filters are the building blocks for query-based groups. Each filter is a named query that finds actors matching a set of rules.

  1. Click New Filter.
  2. Give it a name (e.g. Druid Beasts CR≤2).
  3. Choose sources (World actors, compendium packs, or both).
  4. Optionally restrict by actor type (e.g. npc).
  5. Add field rules — a path like system.details.cr with a value like <=2. All rules must match.
  6. Save Preset. The count of matching actors appears next to the name.

Groups tab

Groups bundle filters together and appear as sections in the HUD picker.

image

  1. Click New Group and name it.
  2. Expand the group (click the chevron).
  3. Use the Add existing filter dropdown, or click New Filter to create one and auto-add it in one step.

Groups are global — the same group can be assigned to multiple actors.

Morph Groups (Actors tab)

  1. Click any actor in the left panel → Actors tab.
  2. Under Morph Groups, check every group that actor should have access to.

That's it. The HUD button appears on the token once at least one Actor Form set or Morph Group has actors.


Swapping Forms

Select a token on the canvas and open its HUD. Click the masks icon to open the form picker.

Form picker HUD

The picker shows each group as a section. Click a portrait to swap to that form.

The token keeps its position, rotation, and elevation. Everything else (name, image, size, vision, light, bars) is replaced by the target actor's prototype token settings.


HP Transfer Modes

Set per actor in the Actors tab:

Mode Behavior
Independent Each form keeps its own HP. No transfer.
Keep original HP The form swaps but HP stays what it was.
Absolute Current HP carries over as-is (clamped to new max).
Percent Current HP percentage is preserved (e.g. 50% → 50% of new max).

API

For macros, modules, or systems. Exposed on ready:

const mm = game.modules.get("metamorph").api;  // or: globalThis.Metamorph

token accepts a controlled Token, a TokenDocument, an id, or { sceneId, tokenId }. target accepts an Actor, a uuid, an id, or { actorId, packId }.

Call Does
morph(token, target, { hpMode? }) Swap the token to a target form
revert(token) Return to the base form
getForm(token) / getMainActor(token) Read the current / original form
promptForm(token, opts) Open a portrait grid, resolve to the choice (no swap)
polymorph(token, opts) Prompt and morph — the spell entry point
queryFilter(filterOrId) Run a filter, return the matching actors

Filter rules are { path, value }. value may be a comparison (<=2, >=4, <10, >0) or an exact match (beast). All rules must match. hpMode: independent · keep-original · absolute · percent.

Hooks: metamorph.preMorph (return false to cancel), metamorph.morph, metamorph.revert.

Examples

Find your Actor compendium ids (use as filter sources):

game.packs.filter(p => p.metadata.type === "Actor").map(p => p.collection);

D&D 5e — Wild Shape (beasts up to a CR that scales with druid level, HP carried as %):

const token = canvas.tokens.controlled[0];
const druidLvl = token.actor.classes?.druid?.system?.levels ?? 1;
const cr = Math.max(0, Math.floor(druidLvl / 3));   // illustrative — adjust to taste
await Metamorph.polymorph(token, {
  title: `Wild Shape (CR ≤ ${cr})`,
  hpMode: "percent",
  filter: {
    sources: ["dnd5e.monsters"],
    criteria: {
      actorTypes: ["npc"],
      rules: [
        { path: "system.details.type.value", value: "beast" },
        { path: "system.details.cr", value: `<=${cr}` },
      ],
    },
  },
});

Pathfinder 2e — battle form (bestiary creatures at or below your level):

const token = canvas.tokens.controlled[0];
const lvl = token.actor.system.details?.level?.value ?? 1;
await Metamorph.polymorph(token, {
  title: `Polymorph (level ≤ ${lvl})`,
  filter: {
    sources: ["pf2e.pathfinder-bestiary"],
    criteria: {
      actorTypes: ["npc"],
      rules: [{ path: "system.details.level.value", value: `<=${lvl}` }],
    },
  },
});

Shadowdark — transform (world NPCs of level 3 or less; swap sources for your monster pack):

const token = canvas.tokens.controlled[0];
await Metamorph.polymorph(token, {
  title: "Transform",
  filter: {
    sources: ["world"],
    criteria: {
      actorTypes: ["NPC"],
      rules: [{ path: "system.level.value", value: "<=3" }],
    },
  },
});

Direct swap and revert (any system, by uuid):

const token = canvas.tokens.controlled[0];
await Metamorph.morph(token, "Compendium.dnd5e.monsters.Actor.<id>");
await Metamorph.revert(token);   // later

Query without UI (build your own automation):

const beasts = await Metamorph.queryFilter({
  sources: ["dnd5e.monsters"],
  criteria: { actorTypes: ["npc"], rules: [{ path: "system.details.cr", value: "<=1" }] },
});
// → [{ actorId, packId, name, img, type }, ...]

Installation

Search for metamorph in Addon Modules OR paste this manifest URL into Foundry's module installer:

https://github.com/mordachai/metamorph/releases/latest/download/module.json

Categories

Available Versions

  1. Version 1.3.1

    1 week, 3 days ago
    Foundry Version 14 - 14 (Verified 14) Manifest URL Read Notes
  2. Version 1.2.0

    1 week, 3 days ago
    Foundry Version 14+ (Verified 14) Manifest URL Read Notes
  3. Version 1.0.1

    3 weeks, 5 days ago
    Foundry Version 13+ (Verified 14) Manifest URL Read Notes