Useful Foundry Resources for PF2e

For useful Pathfinder 2e resources unrelated to Foundry, click here.

📃Contents



💡Quick Tips


⌨️Keyboard Shortcuts

The full list can be found in the ⚙️ Configure Settings menu in Foundry.

Default ControlPurpose
cToggle character sheet.
pToggle party sheet.
tTarget token under mouse cursor.
Ctrl + gGM Vision (GM only).

When clicking buttons that cause a roll, hold these keys while clicking. They can be combined.

ModifierPurpose
ShiftRoll without the pop-up. Defaults are used.
CtrlBlind GM roll.


🎲Inline Rolls

Inline rolls are bits of text that turn into clickable buttons. These can be in in chat, in documents, and in various other places.

Examples below.

Roll TypeExample
Basic Roll 🎲1d12 + 8
[[/r 1d12 + 8 # This Text Appears Above Result]]
Basic Roll, Pre-rolled 🎲13
[[1d12 + 8]]
Check 🎲Deception
@Check[type:deception|dc:20]
Check, Show DC 🎲DC 20 Deception
@Check[type:diplomacy|dc:20|showDC:all]
Check, Secret 🎲Society
@Check[type:society|dc:20|traits:secret]
Flat Check 🎲DC 15 Flat Check
@Check[type:flat|dc:15|showDC:all]
Save 💗Fortitude
@Check[type:fortitude|dc:20]
Basic Reflex 🏃🏼Basic Reflex
@Check[type:reflex|dc:20|basic:true]
Simple Damage 🎲1d8 + 4 slashing
@Damage[(1d8+4)[slashing]]
Damage with Bleed 🎲(1d8 + 4) slashing + 1d4 bleed
@Damage[(1d8+4)[slashing],(1d4)[bleed]]
Damage with Other Persistent 🎲8d6 fire + 1d6 persistent fire
@Damage[(8d6)[fire],(1d6)[persistent,fire]]
Healing 🎲4d8 + 32 vitality
@Damage[(4d8+32)[vitality]]
Emanation ⭕30-foot emanation
@Template[type:emanation|distance:30]
Burst 🔴20-foot burst
@Template[type:burst|distance:20]
Cone 📐60-foot cone
@Template[type:cone|distance:60]
Line 📏120-foot line
@Template[type:line|distance:120]
Wide Line (or Rectangle) 📏30-foot line
@Template[type:line|distance:30|width:30]


🧮Rules Elements

Rules elements are little bits of JSON text that drive the automation in Foundry. You can achieve very powerful effects with these. Read more here.

Note: by default players cannot interact with Rules Elements. The GM can allow them to do so in the system settings.

In the future, this section may contain example Rules Elements.



🧩My Favourite Modules

Learn about modules here. Browse a library of modules here.

😍Important Modules

These are ones that are important to my PF2e Foundry experience.

😊Nice-to-have Modules

These are ones I've found useful, but could probably live without.



📂Importable JSON Files

Foundry allows you to import JSON files as scenes, actors, items, journals, and more. To do this:

  1. Create a blank object of the desired type. For instance, if you are creating an actor, create a new actor.
  2. Right-click the item in the sidebar.
  3. From the pop-up menu that appears, select Import Data.
  4. Select Choose file, select the JSON file, and click Import.
  5. Your object should now contain the imported data.
  6. For objects with in-built Notes fields, consult that field for tips on usage.

A number of JSON files are downloadable below. Please note, Foundry and its PF2e system update frequently, so I can't always ensure these JSON files are supported by the latest versions.

JSON FileObject TypeDescription
Light Orb Actor A small actor that glows, representing an unattached orb as per the light spell. It can easily be changed to its Heightened (4th) brightness.
Harrow Deck Rollable Table A rollable table for drawing random Harrow cards, with art, with GM-only text explaining the cards' meaning. Note: please see the information below.

🃏Harrow Deck

This rollable table requires an official purchase from Paizo and some semi-technical steps.

  1. You need to have the official Harrow card art available from here.
  2. Download the digital version (as JPGs) and extract the files. You should see files named similar to PZO2236 Harrow Deck Cards2.jpg
  3. Move the directory containing these files into your User Data directory. If you need help, consult User Data vs Core Data and Managing Your User Data.
  4. The JSON file, as downloaded from the table above, expects the images to be in media/pictures/harrow/ within the User Data location. You must either match this location when you copy the directory in the previous step, or you must edit the JSON file and change every instance of the directory (most text editors have a "find and replace" tool).
  5. At this point, import the JSON into a rollable table, and if you've done everything right it should work.



▶️Macros

You can drag-and-drop macros onto your hotbar.

#️⃣Specific Macros

Community-made macros can be found here. There are also some custom macros below. To use a macro:

  1. Click on a blank slot in your hotbar.
  2. In the window that appears, change the Type to "Script".
  3. Paste the code into the Command box.
  4. You can adjust the title and icon as you like.
  5. Click 💾Save Macro.

📃Fast Check Prompt

The PF2e system in Foundry has a skill prompt generator macro. This one needs fewer clicks. That's useful for something used so often.

let showRoll = (name, dc, showDc, isSecret) => {
    let dcText = dc ? `|dc:${dc}` : '';
    let secretText = isSecret ? '|traits:secret' : '';
    let message = `
        <span style="font-size:150%;">
            Please Roll:</br>
            @Check[type:${name}|showDC:${showDc}${dcText}${secretText}]
        </span>
        `;
    let chatData = {
        user: game.user.id,
        content: message,
        speaker: ChatMessage.getSpeaker(),
    }
    ChatMessage.create(chatData, {});
}

let proceedWithRoll = false;
await new Dialog({
    title: "Fast Check Prompt",
    content: `
        <style>
            form.fast-check-prompt ul  {
                vertical-align: top;
                margin: 0;
                padding: 0;
                list-style-type: none;
            }
            form.fast-check-prompt li:hover:not(.empty),
            form.fast-check-prompt li:hover:not(.empty) > *:hover {
                background-color: yellow;
                cursor: pointer;
            }
            form.fast-check-prompt li {
                display: flex;
            }
            form.fast-check-prompt li > label {
                display: inline-block;
                padding-left: 5px;
                flex-grow: 1;
            }
            form.fast-check-prompt li > input {
                display: inline-block;
                width: 14px;
                margin: 0;
                top: 0;
                flex-grow: 0;
            }
        </style>
        <form class="fast-check-prompt">
            <div class="form-group">
                <label>Check DC</label>
                <input id="fast-prompt-dc" name="fast-prompt-dc" type="number" min="0" step="1" />
            </div>
            <div class="form-group">
                <label></label>
                <small><i>Leave blank to have no set DC.</i></small>
            </div>
            <hr/>
            <div class="form-group">
                <ul>
                    <li>
                        <input type="radio" id="all" name="fast-prompt-show-dc" value="all" checked />
                        <label for="all"><i class="fas fa-eye"></i> Show DC</label>
                    </li>
                </ul>
                <ul>
                    <li>
                        <input type="radio" id="gm" name="fast-prompt-show-dc" value="gm" />
                        <label for="gm"><i class="fas fa-eye-slash"></i> Hide DC</label>
                    </li>
                </ul>
            </div>
            <hr/>
            <div class="form-group">
                <ul>
                    <li>
                        <input type="radio" id="flat" name="fast-prompt-skill" value="flat" />
                        <label for="flat"><i class="fas fa-horizontal-rule"></i> Flat</label>
                    </li>
                    <li>
                        <input type="radio" id="perception" name="fast-prompt-skill" value="perception" checked />
                        <label for="perception"><i class="fas fa-search"></i> Perception</label>
                    </li>
                    <li class="empty">
                        <label>&nbsp;</label>
                    </li>
                    <li class="empty">
                        <hr/>
                    </li>
                    <li>
                        <input type="radio" id="acrobatics" name="fast-prompt-skill" value="acrobatics" />
                        <label for="acrobatics"><i class="fas fa-child"></i>‍ Acrobatics</label>
                    </li>
                    <li>
                        <input type="radio" id="arcana" name="fast-prompt-skill" value="arcana" />
                        <label for="arcana"><i class="fas fa-hat-wizard"></i> Arcana</label>
                    </li>
                    <li>
                        <input type="radio" id="athletics" name="fast-prompt-skill" value="athletics" />
                        <label for="athletics"><i class="fas fa-running"></i></i>️ Athletics</label>
                    </li>
                    <li>
                        <input type="radio" id="crafting" name="fast-prompt-skill" value="crafting" />
                        <label for="crafting"><i class="fas fa-pencil-ruler"></i> Crafting</label>
                    </li>
                    <li>
                        <input type="radio" id="deception" name="fast-prompt-skill" value="deception" />
                        <label for="deception"><i class="fas fa-smile-wink"></i> Deception</label>
                    </li>
                    <li>
                        <input type="radio" id="diplomacy" name="fast-prompt-skill" value="diplomacy" />
                        <label for="diplomacy"><i class="fas fa-kiss-wink-heart"></i> Diplomacy</label>
                    </li>
                    <li>
                        <input type="radio" id="intimidation" name="fast-prompt-skill" value="intimidation" />
                        <label for="intimidation"><i class="fas fa-tired"></i> Intimidation</label>
                    </li>
                    <li>
                        <input type="radio" id="medicine" name="fast-prompt-skill" value="medicine" />
                        <label for="medicine"><i class="fas fa-hand-holding-medical"></i> Medicine</label>
                    </li>
                </ul>
                <ul>
                    <li>
                        <input type="radio" id="fortitude" name="fast-prompt-skill" value="fortitude" />
                        <label for="fortitude"><i class="fas fa-heartbeat"></i> Fortitude</label>
                    </li>
                    <li>
                        <input type="radio" id="reflex" name="fast-prompt-skill" value="reflex" />
                        <label for="reflex"><i class="fas fa-rabbit-fast"></i> Reflex</label>
                    </li>
                    <li>
                        <input type="radio" id="will" name="fast-prompt-skill" value="will" />
                        <label for="will"><i class="fas fa-head-side-brain"></i> Will</label>
                    </li>
                    <li class="empty">
                        <hr/>
                    </li>
                    <li>
                        <input type="radio" id="nature" name="fast-prompt-skill" value="nature" />
                        <label for="nature"><i class="fas fa-leaf"></i> Nature</label>
                    </li>
                    <li>
                        <input type="radio" id="occultism" name="fast-prompt-skill" value="occultism" />
                        <label for="occultism"><i class="fas fa-ghost"></i> Occultism</label>
                    </li>
                    <li>
                        <input type="radio" id="performance" name="fast-prompt-skill" value="performance" />
                        <label for="performance"><i class="fas fa-saxophone"></i> Performance</label>
                    </li>
                    <li>
                        <input type="radio" id="religion" name="fast-prompt-skill" value="religion" />
                        <label for="religion"><i class="fas fa-pray"></i> Religion</label>
                    </li>
                    <li>
                        <input type="radio" id="society" name="fast-prompt-skill" value="society" />
                        <label for="society"><i class="fas fa-users-crown"></i> Society</label>
                    </li>
                    <li>
                        <input type="radio" id="stealth" name="fast-prompt-skill" value="stealth" />
                        <label for="stealth"><i class="fas fa-user-ninja"></i> Stealth</label>
                    </li>
                    <li>
                        <input type="radio" id="survival" name="fast-prompt-skill" value="survival" />
                        <label for="survival"><i class="fas fa-campground"></i> Survival</label>
                    </li>
                    <li>
                        <input type="radio" id="thievery" name="fast-prompt-skill" value="thievery" />
                        <label for="thievery"><i class="fas fa-lock-open"></i> Thievery</label>
                    </li>
                </ul>
            </div>
            <hr/>
        </form>
        `,
    buttons: {
        public: {
            icon: '<i class="fas fa-users"></i>',
            label: "Public",
            callback: () => { proceedWithRoll = true; isSecret = false; }
        },
        secret: {
            icon: '<i class="fas fa-user-secret"></i>',
            label: "Secret",
            callback: () => { proceedWithRoll = true; isSecret = true; }
        },
        cancel: {
            icon: '<i class="fas fa-ban"></i>',
            label: "Cancel",
            callback: () => { }
        }
    },
    close: html => {
        if(proceedWithRoll) {
            let dc = html.find('[name="fast-prompt-dc"]')[0].value || '';
            let showDc = html.find('[name="fast-prompt-show-dc"]:checked')[0].value || "all";
            let skill = html.find('[name="fast-prompt-skill"]:checked')[0].value || "flat";
            showRoll(skill, dc, showDc, isSecret);
        }
    }
}).render(true);

🔤Fix Fonts in Firefox

There is a font-related bug with Foundry in Firefox. This macro will fix it.

(function(){FontConfig._loadFonts();})();

🎲Flat Check Roller

A one-stop macro for rolling common flat checks, such as those involved with Concealed, Hidden, Grabbed, Stupefied and Dying.

// Set auto to true to change the macro so it
// auto-rolls, rather than prompting for a roll:
let auto = false;

let html=`
<table>
<tbody>
<tr>
<th>Situation</th>
<th style="width:33%;">Needed DC</th>
</tr>
<tr><td>Manipulate when @UUID[Compendium.pf2e.conditionitems.Item.kWc1fhmv9LBiTuei]{Grabbed}</td><td>5</td></tr>
<tr><td>Target @UUID[Compendium.pf2e.conditionitems.Item.DmAIPqOBomZ7H95W]{Concealed}</td><td>5</td></tr>
<tr><td>Target @UUID[Compendium.pf2e.conditionitems.Item.iU0fEDdBp3rXpTMC]{Hidden}</td><td>11</td></tr>
<tr><td>Cast while @UUID[Compendium.pf2e.conditionitems.Item.e1XGnhKNSQIm5IXg]{Stupefied}</td><td>5 + Stupefied value</td>
</tr></tr>
<tr><td>@UUID[Compendium.pf2e.conditionitems.Item.yZRUzMqrMmfLu0V1]{Dying} Recovery Check</td><td>10 + Dying value</td>
</tr>
<tr>
<tr><td>Persistent Damage Recovery</td><td>15</td>
</tr>
<tr>
<th><span style="font-size:125%">Flat Check Result:</span></th>
<th><span style="font-size:125%">`

if(auto) {
html += "[[1d20]]";
}
else{
html += "[[/r 1d20 # Flat Check Roll]]";
}

html += `</span></th>
</tr>
</tbody>`;

let chatMessageData = {
user: game.user.id,
speaker: ChatMessage.getSpeaker(),
content: html,
type: CONST.CHAT_MESSAGE_TYPES.OTHER
};
ChatMessage.create(chatMessageData);

🔁Flip Token

Flips the currently-selected token horizontally. This can be useful if you've got a token that "faces" either left or right, and you want them to be "looking" in the right direction on the map.

// Change animate: false to animate: true if you
// want a cool flipping animation. But don't click
// the macro too fast or you'll break your token!
// (Simply delete and re-create it if it happens.)
for (let t of canvas.tokens.controlled) {
    await t.document.update(
        {"texture.scaleX": t.document.texture.scaleX * -1},
        {animate: false, animation: {duration: 100}});
}

⛔End Turn

There is an end-turn button on the ⚔️Encounters tab, but it can be nice to have it in easier reach.

game.combat.nextTurn();

👤Token Image Picker (Basic)

Quickly change your token's image to one selected from a list. Edit start of the code to choose the images.

// The height and width of the dialog that's shown:
width = 320;
height = 320;

// A list of images.
// This can be any number of images (within reason):
// You can get this value from your token.
// See: Appearance > Image Path
// All items need to be surrounded in quotes (").
// The all but the last item needs to end with a comma (,).
// Example: "media/pics/mypic1.webp",
let myTokenImages = [
"media/pics/mypic1.webp",
"media/pics/cooltoken.png"
];

// You don't need to change anything under this line.

if (canvas.tokens.controlled.length == 0) {
    ui.notifications.warn("Please select at least one token.");
    return;
} 

let d = new Dialog({});
d.data.title = "Choose an Image";
d.position.height = height;
d.position.width = width;
d.data.buttons = {};
myTokenImages.forEach(function(tokenImage, index) {
    d.data.buttons["image" + index] = {
        icon: '<img src="' + tokenImage + '"/><br/>',
        label: "<p style='line-height:1.2;'>Image " + (index + 1) + "</p>",
        callback: () => setTokenImage(tokenImage)
    };
});
d.render(true);

function setTokenImage(imgString) {
    const updates = [];
    for (let token of canvas.tokens.controlled) {
        updates.push({
            _id: token.id,
            texture: {src: imgString}
        });
    }
    canvas.scene.updateEmbeddedDocuments("Token", updates); 
}