A few weeks ago,
Marty and I put our heads together to figure out how all the damage modifiers are applied. This math is reverse-engineered from the game binary, so it should be exactly how the game calculates damage and applies all the modifiers. I finally got some time this week to verify the math in-game.
A note on rounding before we start... I will use this notation to indicate rounding 0.5 and under down to the next lowest integer, and everything else up:
Additionally, it's impossible to have every single modifier, but I'll still use alphabetical variables to show how it is applied to the damage value from previous steps.
1. Initial Damage
This is what the
Japanese video determined empirically early on. The actual calculation looks like this:
Code:
initial_damage = (unsigned int)(float)((float)(unsigned int)(float)((float)(unsigned int)(float)((float)((float)(damage_atk_power_coef + (float)damage_calc_info->attacker_atk)
+ (float)(damage_atk_level_coef * (float)damage_calc_info->attacker_lvl))
* (float)damage_calc_info->base_power)
/ (float)(damage_def_power_coef + (float)damage_calc_info->opponent_defense)) / damage_denominator);
I've simplified it to be a bit more readable. The game fetches these variables from a flatbuffer and then does float arithmetic with them, so the order of operations is important for precision.
2. Attack/Defense Modifiers
This is the offensive and defensive multipliers for "Power Boost", "Guard Boost", "Power Drop", "Guard Drop". These can only have one of 3 stages: -1, 0, and +1. If the attacking Pokémon’s attack stage is the same as the opponent Pokémon’s defense stage, skip this step. Critical hits do not affect this step.
If the attacker’s attack stage is boosted or the opponent’s defense stage is decreased, then the respective modifier is 1.5.
If the attacker’s attack stage is decreased or the opponent’s defense stage is boosted, then the respective modifier is 0.66.
3. Unknown Modifier
Potentially unused. See
this post for what’s been tried. Every case where it was observed used 4096. This modifier was also present in v1.0.0. I include this for completeness sake in case someone figures out what it is in the future. If the modifier is not 4096, this is applied to it:
4. Rain Fire Damage Modifier
Active when a fire move is used in the rain. The inner calculations are done as floats. The value of this modifier is 75.
First, convert the modifier into a multiple of 4096:
If rain_fire_damage_mod_4096 is 4096, this step is skipped. Otherwise, it's applied like so:
5. Critical Hit Modifier
This is a simple 1.5x multiplier. Again, this doesn't negate defense boosts.
6. Damage Roll Modifier
Similar to the main games, this has the option to use the minimum damage roll of 85. I do not know if/where this is used in LA.
Otherwise, this ranges from 85 to 100. The RNG is Xoroshiro128+.
7. STAB (Same Type Attack Bonus)
If the attack is the same type as the user, this modifier is 5120; otherwise it is 4096.
8. Effectiveness Modifier
This is whether a move is super effective or not very effective. This uses float multiplication. In LA, the exact modifiers are:
- 0.4 - Both types resist the attack type.
- 0.5 - One type resists the attack type and the other is neutral.
- 1.0 - Neutral damage.
- 2.0 - One type is weak to the attack type and the other is neutral.
- 2.5 - Both types are weak to the attack type.
9. Burn/Frostbite Modifier
Burn weakens physical attacks and Frostbite weakens special attacks. Both modifiers are set to 50.
10. Drowsy Modifier
Drowsy Pokémon take more damage. This modifier has a value of 133.
11. Fixated Offensive Modifier
Fixated Pokémon deal more damage. This modifier has a value of 150.
12. Fixated Defensive Modifier
Fixated Pokémon also take more damage. This modifier has a value of 133.
13. Primed Modifier
The primed status, e.g. from Double Hit, Victory Dance, or the Twice-Spiced Radish, increases damage. This modifier has a value of 150.
At this point, the final damage is dealt to the target.
I've included all the disassembly on my
GitHub gist for people who are curious to see what I worked with.