• Smogon Premier League is here and the team collection is now available. Support your team!

Mechanics [Gens 2-3] Pursuit should double damage instead of Base Power

What type of bug are you reporting? Mechanics

What is the bug?
In gen 3 (possibly in other gens as well), we believe that Pursuit damage is not calculated correctly on switching out targets in PS!

You'll notice in the damage calculator here that when Tyranitar uses Pursuit on a switching out Gengar, the damage rolls are not identical to Crunch. This is because of the way floor functions are repeatedly applied and boosted pursuit is boosted at a different point from base power from my understanding.

TEvywCm.png


Here is a desmos replicating the max damage rolls of Unboosted Pursuit, Crunch, and Boosted suit in this scenario which agrees with the damage calculator https://www.desmos.com/calculator/eheoj7ajyh. tl;dr we believe the pursuit calculations are right in the calculator and wrong on PS.

However, when boosted pursuit is actually used in PS, it appears to do damage from the Crunch damage roll table which should be impossible. Example replay https://replay.pokemonshowdown.com/gen3customgame-2488331184-csh97ite5gd9ojy3458fyf9v3ehoainpw

fIfrHB4.png


thanks to Johnald and Tetrafolium for their help

Are you able to replicate it? If so, how?
Use pursuit in a tyranitar vs gengar scenario and check whether the damage roll comes from the boosted pursuit rolls in the calculator or the crunch / 80 base power dark move rolls in the calculator
 
Have you checked if the damage numbers are accurate to cart as well? ADV code can be jank, so could be possible that pursuit acts like crunch on switch-out in-game even though the calculation shouldn't work that way.
 
WraxiusGaming I ran the following on a Emerald ROM edited with Hex Maniac Advance for the set-up. In short, I believe this shows that Pursuit is correct in the calculator. Note that in the calcs below, the TTar is -SpA because the ROM editor does not allow you to choose natures (screenshot #3), only IV/Mon/Moveset/Items, thus the nature is randomly chosen. Min roll on neutral nature is 214 though.

0- SpA Tyranitar switching boosted Pursuit vs. 0 HP / 0 SpD Gengar: 193-228 (73.9 - 87.3%) -- guaranteed 2HKO after sandstorm damage and Leftovers recovery
Possible damage amounts: (193, 196, 198, 200, 202, 205, 207, 209, 212, 214, 216, 218, 221, 223, 225, 228)

0- SpA Tyranitar Crunch vs. 0 HP / 0 SpD Gengar: 190-224 (72.7 - 85.8%) -- guaranteed 2HKO after sandstorm damage and Leftovers recovery
Possible damage amounts: (190, 192, 194, 197, 199, 201, 203, 206, 208, 210, 212, 215, 217, 219, 221, 224)

Damage Values: 198, 205, 216, 218, 228 (See screenshot #1). See bold markings above where the Pursuit rolls match but not the Crunch rolls.
 

Attachments

  • gardamage.png
    gardamage.png
    130.3 KB · Views: 40
  • garstats.PNG
    garstats.PNG
    152.9 KB · Views: 38
  • ttarstats.png
    ttarstats.png
    5.1 KB · Views: 40
I have a theory that might explain the discrepancy. Note that this is mostly speculation on my part because I do not have access to the code that is used to calculate the damage dealt on the simulator, in the damage calculator app (which I will be referring to as the "calc" from now on), or on cartridge.

Damage Formula

As we know from the holy text, the damage formula in Gen 3 is
1765469503073.png
P = Base Power of the attacking move
A = The offensive stat of the attacking Pokemon (could be physical or special)
D = The defensive stat of the defending Pokemon
C_1 = Multiplicative factors due to burn, screens, multi-target, weather, and Flash Fire
C_2 = Multiplicative factors due to Stockpile, critical hits, damage doubling effects (e.g. Pursuit on switching target), Charge (followed by an Electric-type move), Helping Hand, STAB, and type effectiveness
RandInt = A random integer between 85 and 100, which might also be referred to as the "damage roll".

I emphasize STAB and type effectiveness since they are the most commonly applied modifiers in single battles.

We can cut this formula down with the following assumptions: Level is set to 100 and nothing from C_1 is in effect. Thus, a simplified damage formula might look like:
1765470239722.png

Rounding

Now that the damage formula has been established, we can get right into calculations, right? Well... not quite yet. Pokemon damage is always dealt in integer values. Hence, we have to account for some rounding. The rule of thumb is that damage values round down, so we can "floor" the Damage value that we calculate and get the result that we want.
1765470585475.png
Let's use this inconspicuously, not-at-all-cherry-picked example to demonstrate.
252+ SpA Zapdos Thunderbolt vs. 252 HP / 212+ SpD Zapdos: 132-156 (34.3 - 40.6%) -- 49.8% chance to 3HKO after Leftovers recovery
Possible rolls: (132, 134, 135, 137, 138, 140, 141, 143, 145, 146, 148, 149, 151, 152, 154, 156) [source: calc.pokemonshowdown.com]
For this case, P = 95, A = 383, D = 295, and C_2 = 1.5 since T-Bolt is STAB and neutrally effective. For simplicity, let's assume the max roll, so RandInt = 100. If our formula works, then we should get 156.
1765472236420.png
Huh. That can't be right. Maybe there's a mistake in our formula.

It turns out there is. Gen 3 (and possibly other gens) doesn't save numbers as "floats" (i.e. numbers with decimals) but rather as integers. So at every step of multiplication, we need to add a floor function. Thus, the "correct" calculation is
1765472656702.png
We can change the 100 in the numerator to any integer between 85 and 100 and see that this is consistent with the calc. Now, we certainly would expect that this is how the simulator has implemented the damage formula, right?

The Simulator

https://replay.pokemonshowdown.com/gen3ou-2494815342-8os1p90tkayt16oveppt4dlfj7skkpnpw
ತ_ʖತ
Okay, but that's just hearsay from StormCrow92. What if they just miscalculated the damage on turn 1?
|turn|1
|inactive|Battle timer is ON: inactive players will automatically lose when time's up. (requested by therunna)
|inactive|Time left: 150 sec this turn | 150 sec total | 60 sec grace|
|t:|1765050827
|move|p1a: oi UE|Thunderbolt|p2a: Zapdos
|-damage|p2a: Zapdos|229\/384
|move|p2a: Zapdos|Toxic|p1a: oi UE
|-status|p1a: oi UE|tox|
|-damage|p1a: oi UE|94\/100 tox|[from] psn
|-heal|p2a: Zapdos|253\/384|[from] item: Leftovers
|upkeep
°O°

The line of code that reads "|-damage|p2a: Zapdos|229\/384" tells us that Stormcrow's Zapdos went from 384 HP to 229 HP, which is 155 damage dealt. This is not possible according to the damage rolls from the calculator. RandInt = 100 gives us 156 damage dealt as we saw from the previous section. RandInt = 99 gives 154, and any lower roll obvious deals less than 154.

Formulas implemented in Desmos to demonstrate the possible issue: https://www.desmos.com/calculator/oosncfodhe

Conclusion

I suspect that there are some floor functions missing in the simulation's implementation of the damage formula. Most likely, the floors are missing when applying either the STAB or RandInt. I don't have access to any of the code related to damage in the simulator, so I can't say for certain, but based on the replay example, I think it's safe to say that some discrepancy exists.

Thanks to Spreek for starting this thread.
 
Hey, I discovered the problem. In Gens 4–9, Pursuit doubles the move's base power, but in Gens 2 and 3, Pursuit is applied as a late damage modifier. On PS, Pursuit always doubles the move's base power. Smogon's Damage Calculator calculates the damage correctly.

This probably calls for a full review of the damage formula used in Gens 1-4.
 
Back
Top