Godbreaker#
The Godbreaker feat (Monk 20, Wrestler 20) is the ultimate Super Sayan move - but how likely are you to pull it off completely?
Let’s compare these builds:
Monk (2. Crushing Grab, 6. Whilrling Throw, 19. Perfected Form, 20. Godbreaker)
Fighter (2. Wrestler Dedication, 4. Crushing Grab, 8. Whirling Throw, 10. Agile Grace, 20. Godbreaker)
Ranger (1. Flurry Edge, 2. Wrestler Dedication, 4. Crushing Grab, 8. Whirling Throw, 20. Godbreaker)
Any other martial, e.g. animal barbarians (2. Wrestler Dedication, 4. Crushing Grab, 8. Whirling Throw, 20. Godbreaker)
Any spellcaster (2. Wrestler Dedication, 4. Crushing Grab, 8. Whirling Throw, 20. Godbreaker)
Assume that:
All use +3 Greater Fearsome Keen Handwraps of Mighty Blows
All martials have an Apex item for +1 STR; start at +4 STR and increase it at all bumps
Non-martials start at +3 STR and increase it at all bumps
All perform the second and third strike with an agile unarmed attack
The turn starts with the target already grabbed
For the sake of tidiness we’re skipping damage calculations.
# Install in JupyterLite
%pip install -q pathfinder2e-stats
import matplotlib as mpl # noqa: F401 # Needed by JupyterLite
import numpy as np
import xarray
import pathfinder2e_stats as pf2
Note: you may need to restart the kernel to use updated packages.
# Keen rune?
keen = True
# Fearsome, Greater Fearsome, Crushing, or Greater Crushing Rune?
# What's the status penalty to AC on a critical hit?
fearsome = -2
# How much help is the attacker getting from the other party members?
# Bestial Mutagen or Fury Cocktail for an extra +1 item bonus to attack
# Aid or Albatross Curse for +1 circumstance bonus
# Bless or Corageous Anthem for +1 status bonus
# Heroism for +1 (3rd), +2 (6th), +3 (9th) status bonus
party_help = {
"dims": ["party help"],
"coords": {"party help": ["nothing", "everything"]},
}
extra_atk_bonus = xarray.DataArray([0, 5], **party_help)
# Did another party member apply Frightened, sickened, or clumsy
# when the attacker's turn begins?
initial_AC_status_penalty = xarray.DataArray([0, -2], **party_help)
atk = (
pf2.tables.SIMPLE_PC.weapon_attack_bonus[
["monk", "fighter", "ranger", "barbarian", "wizard"]
]
.sum("component")
.sel(mastery=True, category="martial", level=20)
.to_array("class")
)
atk.to_pandas().to_frame("attack bonus")
| attack bonus | |
|---|---|
| class | |
| monk | 36 |
| fighter | 38 |
| ranger | 36 |
| barbarian | 36 |
| wizard | 32 |
Three standard targets:
level 18 with low AC
level 20 with moderate AC
level 22 with high AC
The target starts grabbed and remains grabbed throughout all strikes. If a strike fails, the grab is lost and the strikes end.
AC = pf2.tables.SIMPLE_NPC.AC.sel(level=20) - 2
AC.to_pandas().to_frame("AC")
| AC | |
|---|---|
| challenge | |
| Weak | 37 |
| Matched | 42 |
| Boss | 46 |
MAP = xarray.DataArray(
[
[0, -4, -8], # Monk
[0, -3, -6], # Fighter with Agile Grace
[0, -3, -6], # Flurry ranger
[0, -4, -8], # Any other martial
[0, -4, -8], # Any spellcaster
],
dims=["class", "strike"],
coords={"class": atk.coords["class"], "strike": [1, 2, 3]},
)
MAP.to_pandas()
| strike | 1 | 2 | 3 |
|---|---|---|---|
| class | |||
| monk | 0 | -4 | -8 |
| fighter | 0 | -3 | -6 |
| ranger | 0 | -3 | -6 |
| barbarian | 0 | -4 | -8 |
| wizard | 0 | -4 | -8 |
Perfected form (level 19 monk feature): On your first Strike of your turn, if you roll lower than 10, you can treat the attack roll as a 10. This is a fortune effect.
perfected_form = xarray.DataArray(
np.zeros((3, 5), dtype=bool),
dims=["strike", "class"],
coords={"strike": [1, 2, 3], "class": atk.coords["class"]},
)
perfected_form[0, 0] = True
perfected_form.to_pandas()
| class | monk | fighter | ranger | barbarian | wizard |
|---|---|---|---|---|---|
| strike | |||||
| 1 | True | False | False | False | False |
| 2 | False | False | False | False | False |
| 3 | False | False | False | False | False |
kwargs = dict(
bonus=atk + MAP + extra_atk_bonus,
perfected_form=perfected_form,
keen=keen,
# Roll independently for the three strikes...
independent_dims=["strike"],
# ... but roll only once across the different what-if scenarios
# and apply the result of the d20 to different bonuses and DCs.
dependent_dims=["class", "challenge", "party help"],
)
AC_status1 = initial_AC_status_penalty
strike1 = pf2.check(DC=AC + AC_status1, **kwargs).outcome.sel(strike=1, drop=True)
# Critical hits trigger the fearsome rune
AC_status2 = np.minimum(
xarray.where(strike1 == pf2.DoS.critical_success, fearsome, 0),
AC_status1,
)
strike2 = xarray.where(
strike1 >= pf2.DoS.success,
pf2.check(DC=AC + AC_status2, **kwargs).outcome.sel(strike=2, drop=True),
pf2.DoS.no_roll,
)
# Critical hits trigger the fearsome rune
AC_status3 = np.minimum(
xarray.where(strike2 == pf2.DoS.critical_success, fearsome, 0),
AC_status2,
)
strike3 = xarray.where(
strike2 >= pf2.DoS.success,
pf2.check(DC=AC + AC_status3, **kwargs).outcome.sel(strike=3, drop=True),
pf2.DoS.no_roll,
)
strikes = xarray.concat([strike1, strike2, strike3], dim="strike")
strikes.coords["strike"] = [1, 2, 3]
counts = pf2.outcome_counts(strikes)
Probability to obtain at least a hit on each strike#
A hit on the second strike can only happen if you hit on the first.
A hit on the third strike, and consecutive final slam into the ground, can only happen if you hit on the first two.
The probability to fully complete the Godbreaker three-action activity is equal to the probability of hitting on the third strike.
(
counts.sel(outcome=["Critical success", "Success"])
.sum("outcome")
.stack(row=["challenge", "class"], column=["party help", "strike"])
.to_pandas()
.round(3)
* 100
)
| party help | nothing | everything | |||||
|---|---|---|---|---|---|---|---|
| strike | 1 | 2 | 3 | 1 | 2 | 3 | |
| challenge | class | ||||||
| Weak | monk | 100.0 | 84.9 | 56.7 | 100.0 | 94.9 | 90.1 |
| fighter | 94.9 | 90.1 | 79.3 | 94.9 | 90.1 | 85.5 | |
| ranger | 94.9 | 85.6 | 66.2 | 94.9 | 90.1 | 85.5 | |
| barbarian | 94.9 | 80.9 | 54.2 | 94.9 | 90.1 | 85.5 | |
| wizard | 80.1 | 51.1 | 22.9 | 94.9 | 90.1 | 67.5 | |
| Matched | monk | 100.0 | 57.6 | 22.5 | 100.0 | 89.9 | 62.7 |
| fighter | 85.0 | 63.0 | 38.3 | 94.9 | 90.1 | 81.1 | |
| ranger | 75.2 | 47.7 | 23.5 | 94.9 | 90.1 | 72.0 | |
| barbarian | 75.2 | 44.0 | 17.5 | 94.9 | 85.4 | 59.6 | |
| wizard | 55.0 | 20.1 | 3.9 | 90.0 | 63.0 | 31.3 | |
| Boss | monk | 100.0 | 36.0 | 6.8 | 100.0 | 70.0 | 34.9 |
| fighter | 65.1 | 34.1 | 13.2 | 94.9 | 80.6 | 56.2 | |
| ranger | 55.0 | 22.9 | 6.6 | 90.0 | 67.4 | 40.2 | |
| barbarian | 55.0 | 20.1 | 3.9 | 90.0 | 63.0 | 31.3 | |
| wizard | 35.0 | 6.1 | 0.3 | 70.1 | 35.1 | 10.4 | |
Aside#
Godbreaker has the following extra damage and effects, compared to three iterative strikes:
0 hits: 10 falling damage
1 hit: 20 falling damage
2 hits: 30 falling damage
3 hits: 40 falling damage + Crushing Grab + 1 strike damage + grapple continues into next round
Probability of completing the Godbreaker#
This is just a selection of strike=3 from the previous table, for ease of reading.
(
counts.sel(outcome=["Critical success", "Success"])
.sum("outcome")
.sel(strike=3)
.stack(row=["party help", "challenge"])
.to_pandas()
.round(3)
* 100
).T
| class | monk | fighter | ranger | barbarian | wizard | |
|---|---|---|---|---|---|---|
| party help | challenge | |||||
| nothing | Weak | 56.7 | 79.3 | 66.2 | 54.2 | 22.9 |
| Matched | 22.5 | 38.3 | 23.5 | 17.5 | 3.9 | |
| Boss | 6.8 | 13.2 | 6.6 | 3.9 | 0.3 | |
| everything | Weak | 90.1 | 85.5 | 85.5 | 85.5 | 67.5 |
| Matched | 62.7 | 81.1 | 72.0 | 59.6 | 31.3 | |
| Boss | 34.9 | 56.2 | 40.2 | 31.3 | 10.4 |
Conclusions#
The Godbreaker activity has a very slim chance of complete success as a baseline, with a big risk of feeling underwhelming.
Party assistance makes an enormous difference.
The various classes compare as follows:
Fighter/Wrestlers are by far the best at applying GodBreaker in all situations, thanks to their higher baseline attack bonus plus Agile Grace;
Flurry Ranger/Wrestlers come second thanks to their low MAP;
Monks, for which this feat was designed, are only third best despite their Perfected Form;
Other martials and spellcasters should just avoid this feat due to their inability to consistently connect 3 strikes in a row with MAP.