| Latest version | 1.2.6 |
|---|---|
| Minimum Core | 14 |
| Compatible Core | 14 |
| Last updated | 1 day ago |
| Created | 1 month ago |
| Authors | |
| Languages |
English 日本語 |
| Systems |
Pf2e |
| Project source | Project URL |
PF2e Combater is a floating combat advisor for Foundry VTT's Pathfinder 2e system. It reads the acting creature's real options — strikes, spells, feats, generic actions — together with the battlefield around it, and helps you plan a whole turn, see it on the canvas, and execute it step by step (with one-click undo). GMs get tactical recommendations for the creatures they run; players plan their own turns.

🚧 Work in progress. The Auto-fill planner and the GM aggro/target-picking engine are actively evolving. The exact scores, weights, and heuristics below are current-but-not-final and will change as they're tuned — treat the numbers as illustrative, not a contract. Feedback, disagreements, and "it picked a weird turn here" reports are genuinely wanted: please open an issue with the situation.
No AI, no LLM, no cloud. Auto-fill is 100% deterministic, rules-based math that runs entirely in your browser. Nothing is sent anywhere, it works offline, and the same board always produces the same plan. It reads the PF2e rules and the battlefield — it doesn't "ask a model."
Auto-fill isn't a fixed script — it scores every action the creature can take, then searches for the best combination that fits the turn. Two stages:
Every option starts from a base value by how confidently it's understood (curated spell > strike > generic action), then gets adjusted for the actual situation:
Everything that depends on hidden knowledge — a target's weaknesses, resistances, immunities, save DCs, AC, skill DCs, hidden traits, and "which PC is the juiciest target" — is GM-only. When a player auto-fills, the enemy's defensive data is never even loaded, so none of those factors touch the score, and any explanation text that would leak them is stripped out too.
That splits the scoring into two honest modes:
Every action the creature has lands in exactly one "source" bucket, and the bucket sets the starting score. The bucket reflects how confidently Combater understands the action, not how good it is — it's just a small tie-breaking prior. The situational math below (a Strike in range is already +24, damage adds up to +40, etc.) easily overturns it, and a great-fit action from a low bucket beats a poor-fit one from a high bucket every time.
| Source bucket | Base | What falls here |
|---|---|---|
spell-curated |
50 | A spell in the hand-tuned catalog (known role, targeting, save profile). |
custom-curated |
48 | An actor-specific action Combater recognizes (a class feature/impulse). |
strike |
46 | Any weapon or unarmed Strike read off the actor. |
system-inferred |
44 | A non-spell action recognized by pattern (feats, system actions). |
spell-inferred |
44 | A spell auto-classified by pattern (damage / save / area / buff / heal…). |
generic |
42 | The basic actions — Stride, Step, Demoralize, Trip, Grapple, Seek… |
| (anything else) | 20 | The fallback: a spell that couldn't be classified at all (spell-unknown) or any action with an unrecognized source. Still offered, just ranked cautiously. |
So there's no spell or action that gets ignored — unrecognized ones simply start at 20 and rise or fall on their situational fit like everything else.
Beyond the base, a few of the actual values the engine uses (🔒 = GM-only, skipped for player auto-fill):
| Factor | Effect on score |
|---|---|
| Base value (by source) | see the source table above |
| Strike is in range/reach | +24 |
| Strike damage (your own weapon) | min(avg damage × 2, 40) |
| 🔒 Target weakness to the damage type | +min(weakness × 4, 45) |
| 🔒 Target resistance | −min(resistance × 3, 35) |
| 🔒 Target immunity | −70 (effectively removes it) |
| 🔒 Save spell vs target's save DC | expected-damage multiplier (see below) |
| 🔒 Skill action vs target's defense DC | degree-of-success delta from your skill modifier vs the target's Will/Reflex/Fort/Perception DC (Demoralize→Will, Trip/Disarm/Tumble Through→Reflex, Grapple/Shove/Reposition→Fort, Feint/Create a Diversion→Perception). A likely critical success is worth extra (crit Demoralize = frightened 2, etc.); a likely crit failure costs. |
| 🔒 Incapacitation spell vs a much higher-level target | resistance modeled — a target of more than twice the spell's rank saves one degree better, so hard control (Slow, Paralyze…) is scored down against over-leveled foes |
| 🔒 Poor skill odds (< 35% success) | −4 |
| Untrained (proficiency rank 0) in the skill | −6, and the action is hidden entirely if Hide untrained skill actions is on |
| Untrained Athletics for a melee maneuver (own skill) | −80 (PC) / −42 (NPC), −110 for a primary spellcaster; low Athletics (mod < 5) −12 |
| Multiple attack penalty (2nd / 3rd attack) | −15 / −30 (agile: −12 / −24) |
| Heal when you or an ally is injured (< 50% HP) | +34; if nobody is hurt, −10 (don't waste the spell) |
| Area spell hits multiple enemies | +34 + 18 per enemy; a single enemy in the blast +14; no enemy in it −28 |
| An ally caught in your area | −18 each; a clean placement that hits 2+ enemies and no allies +8 |
| 🔒 Debuff spell on an enemy | +20 |
| Setup that enables a follow-up (Feint, Recall, etc.) | +20, or +28 if it specifically sets up precision damage (sneak attack) |
| Draw a weapon then Strike | +82 if nothing else is in reach, +18 if an in-hand Strike is already available, −40 if still out of range after drawing |
| Stand up while prone | +18, +22 if an enemy is in melee |
| Stride/Step that actually closes distance | Stride +8, Step +4 |
| Move toward a target already in reach | forced to −10 (won't pad the turn) |
| Volley weapon fired inside its volley range | −10 |
| Leftover unused action | −1 each (nudges toward a full turn) |
Hard limits: max 2 Strike steps per plan, an action budget of 3 (± Slowed / Stunned / Quickened), and a Quickened action may only be a Strike or Stride.
When the actor is hurt (own HP < 50%), self-preservation factors climb — healing, defensive, and retreat options gain extra weight — so a badly wounded creature is nudged toward staying alive rather than trading blows.
Everything above scores actions. The aggro engine answers the other half — who to point them at — and it's GM-only, for the NPCs a GM runs. When a player auto-fills, aggro contributes nothing (it would require reading party members' kits), so this whole layer is skipped.
For each possible target, the engine builds an aggro profile by reading that creature's kit — the slugs, names, and traits of its spells, feats, and actions (identity fields only, not the rules prose, so a description that merely mentions a condition doesn't trip a false match) — and matching them against role cue-words. Each role a target fills adds to its priority:
| Target role | Priority | How it's detected |
|---|---|---|
| Finisher target — nearly down | +24 (+34 at ≤ 20% HP) |
HP ≤ 35%, or dying (not the wounded counter, which can sit on a full-HP creature) |
| Immediate threat — in your face | +10 (+18 at ≤ 5 ft) |
within 10 ft |
| Healer | +42 |
kit has heal / lay on hands / battle medicine / restore… |
| Controller | +26 |
kit has slow / fear / grapple / wall / command… |
| Caster | +18 + 2 per spell (max +12) |
has spells or a spellcasting entry |
| Main attacker | +8, scaled by stacked offense (+3 per weapon, +4 per damage feat/impulse/spell, capped) |
so a glass-cannon striker outranks a one-weapon mook, instead of everyone with a weapon reading the same |
| Main defender | +18 |
AC a clear margin above the average of the other targets in the fight (whoever's hardest to hit here), or shield/guardian/intercept cues |
Then the target's priority is weighted by the action you'd use on it, so the engine spends the right tool on the right enemy:
×−0.45), only control ×0.35 — don't waste swings on the wall built to eat them.×0.65) so the NPC isn't tunnel-visioned on whoever's adjacent.The finisher and immediate-threat cues need no hidden data, but because the whole layer only runs for GM-controlled NPCs, players never see or benefit from any of it.
"Swing twice, or hit and run?" — Fighter with a non-agile weapon (avg 11 damage), one goblin in reach, three actions.
46 + 24 + 22 = 9292 − 15 (MAP) = 77"Which damage type?" 🔒 (GM-run NPC) — an enemy caster with both a fire and a cold spell, targeting a PC with fire weakness 5.
+min(5 × 4, 45) = +20"Is the save spell worth it?" 🔒 (GM-run NPC) — an enemy caster's Fireball (basic Reflex) at a PC. The engine rolls the PC's save against the spell DC across all 20 die faces and weights the outcomes: multiplier = P(crit fail) × 2 + P(fail) × 1 + P(success) × 0.5. A weak-save target pushes the multiplier up (bigger odds bonus and bigger expected-damage bonus); a strong-save target drags it below a plain Strike. For a player, this whole comparison is skipped — the save spell is scored on its base value alone.
"Is Demoralize worth an action?" 🔒 (GM-run NPC) — an NPC deciding between Demoralize (Intimidation) on two PCs. The engine rolls the Intimidation modifier against each PC's Will DC across all 20 die faces and weights the degrees of success — a critical success (frightened 2) counts extra, a critical failure counts against it. Against a low-Will PC that means frequent successes and the occasional crit, so Demoralize scores well; against a high-Will PC it slides toward failure and the NPC leans on the softer target. An untrained NPC also eats −6 (or the action is hidden outright). Proficiency rank and skill modifier both feed this — rank gates/penalizes, the modifier drives the odds. For a player, the target's DC is never read, so a skill action is ranked on its base value and own conditions only.
"Buffs, but only useful ones." — Heroism on a martial ally: 12 (ally) + 24 (attack buff on a martial) = +36. The same ally who already has Heroism: −60 → never suggested. A wounded ally under fire nudges it up a further +14. (This one works for players too — it reads ally class and buff state, not hidden enemy stats.)
"Heal now, or keep swinging?" — a cleric with a Heal spell. If nobody is below half HP, the Heal takes −10 and a Strike wins. The moment the cleric or an ally drops under 50%, Heal gains +34 and jumps ahead — and if a party member is dying, the healing role is prioritized outright. (Reads ally HP, not hidden enemy stats, so it works for players too.)
"Fireball placement." 🔒 (GM-run NPC) — a caster's Fireball. Two PCs clustered with no allies nearby: 34 + 18 × 2 = +70, plus the Reflex-save math. Drag the same blast so it also clips an NPC ally: each ally in the radius is −18, quickly dropping it below a single-target spell — so the engine prefers the clean placement.
"Who do I hit?" 🔒 (GM-run NPC) — a monster faces a fighter (AC 26, sword) and an enemy cleric (spells, a Heal). The cleric profiles as healer + caster (42 + ~20), the fighter as main-defender + main-attacker. A damaging Strike aimed at the cleric keeps most of that priority, but aimed at the tank it's multiplied by −0.45 — so the engine steers the attack at the healer. Had the monster a Slow spell, it'd weight even harder toward the caster (control ×1.8). Whenever a PC drops to dying, that PC lights up as a finisher target and jumps the queue.
"Don't waste the spare action." — Enemy already in reach with one action to spare: a generic Stride toward it is forced to −10, which is worse than the −1 for simply leaving the action unused — so the planner leaves it empty rather than tack on a pointless move. (Still addable by hand in Browse.)
The highest-scoring plan is what lands in the panel. It's always a suggestion — every step is editable, and Browse lets you build the turn by hand instead.
To install this package, open your Foundry Setup screen and navigate to your Module tab and click the Install Module button.
From there, you can either search for the package unique name: pf2e-combater or copy its manifest URL:
And paste it to the input box at the bottom of your window.

You can install this package directly to your Forge account.