In Generation IV, the damage formula was derived empirically by X-Act from running it countless times, an approach that is both tedious and prone to errors. The good understanding of the ARM code for Black & White allows us to document the damage formula based on the actual source code of the game. It doesn't guarantee that we didn't make any mistake (interpreting assembly language is in itself a tricky task) but having the documented source along with the formula backs up our claims and allows anyone who spots any error to fix it by themselves.
Roughly speaking, the damage formula in Pokémon is a big multiplication, each factor representing the user's level and attack stat, the foe's defense stat, and a bunch of factors for STAB, held items, abilities and other field effects. In a perfect world where ARM CPUs could work on real numbers, it would be possible to multiply each factor in any order and get the same result, but in practice the game will round some multiplications and truncate others, meaning that in order to get accurate damage results, it is of utmost importance to perform the multiplication in the same order as the game and using the same rounding methods. Even though rounding errors might not sound like a big problem, they will be amplified at each step, and a few factors such as Reflect and Life Orb in a double battle can cause a significant difference between an unrounded and a properly rounded calculation.
There are three main parameters for damage calculation: the user's attack stat, the target's defense stat and the move's base power. To compute these stats, the game starts from a base value and apply a modifier to reflect the various effects that can alter the base value. This modifier is obtained by running through a list of short functions called triggers that are called based on the current active effects on field. Different triggers can modify the same modifier before it is applied, this operation is called chaining and is explained below.
Once the main parameters are set, the general steps of the calculation are as follows:
BaseDamage = ((((2 × Level) ÷ 5 + 2) * BasePower * [Sp]Atk) ÷ [Sp]Def) ÷ 50 + 2
In this article, ÷ always denotes the in-game unsigned divmod function, i.e. the unrounded/truncated integer division. By contrast, "apply a modifier" is a rounded operation explained in the next subsection.
There are some exceptions to the formula above that correspond to the set of triggers at the very top of the damage function; they are detailed in a separate section.
A modifier is a 16 bit fixed point factor, i.e. a fraction whose divisor is always 0x1000 (4096). For instance, 0x14cc is the modifier for Life Orb (0x14cc/0x1000 is about 1.3). Applying the modifier M to the damage value D means multiplying D by M and dividing the result by 0x1000; then if the decimal part is ≤0.5, round the result down, otherwise round it up. Simply put: D' = round(D * M / 0x1000)
Recall that modifiers for a given parameters are computed by the triggers for that parameter. This means that when multiple triggers apply, you have to chain the modifier for the parameter, starting from 0x1000. If the current modifier is M and you want to chain with another modifier M', the resulting modifier would be: M'' = ((M * M') + 0x800) >> 12
Even though the weather modifier has its own set of triggers listed below, they never affect the actual value of the modifier: a water move used during rain or a fire move used during intense sunlight will use 0x1800 as modifier, while a fire move used during rain or a water move during intense sunlight will use 0x800.
Trigger address | Trigger description |
---|---|
21d9850 | Cancel weather if any Pokémon on field has Air Lock or Cloud Nine. |
21d9084 | Internal. |
Trigger address | Trigger description |
---|---|
21d9be8 | Super Luck: increase user's critical hit level by 1. |
21d9bc4 | Battle Armor / Shell Armor: if the target has either of these abilities, bypass critical hit checks. |
21dae18 | Internal. |
21de5fc | Stick: if user is Farfetch'd and holds Stick, increase critical hit level by 2. |
21de5b8 | Lucky Punch: if user is Chansey and holds Lucky Punch, increase critical hit level by 2. |
21de584 | Razor Claw: increase holder's critical hit level by 1. |
21e53b4 | Internal. |
6899210 | Lucky Chant: if the user's party is protected by Lucky Chant, bypass critical hit checks. |
Provided the battle isn't rigged to always use minimum damage, the current damage value D is altered using a random number 0 ≤ R ≤ 15:
D' = (D * (100-R)) ÷ 100
If the type of the move match one of its users', the STAB modifier is set to 0x1800. The only trigger for this modifier is listed below.
Trigger address | Trigger description |
---|---|
21D8C2D | Adaptability: if the user has this ability and move matches one of the user's types, the initial value for the final modifier is set to 0x2000. |
Type effectiveness doesn't use a modifier but a simple left (respectively right) shift of one for a simple and two for a double weakness (respectively resistance), in other words an unrounded division or multiplication by 2 or 4.
The effect of a burn is directly taken into account in the damage formula. First, the game checks if the attack is physical, then if the user is burned, and finally if its ability is different than Guts. If all conditions are satisfied, the current damage is divided by 2 with no rounding.
Trigger address | Modifier | Trigger description |
---|---|---|
6898E29 | Variable | If the target's side is affected by Reflect, the move used was physical, the user's ability isn't Infiltrator and the critical hit flag isn't set.
The value of the modificator is 0xA8F if there is more than one Pokémon per side of the field and 0x800 otherwise. |
6898E45 | Variable | Same as above with Light Screen and special moves. |
21DC125 | 0x800 | If the target's ability is Multiscale and the target is at full health. |
21D8B3D | 0x2000 | If the user's ability is Tinted Lens and the move wasn't very effective. |
21DC15D | 0xC00 | If one of the target's allies' ability is Friend Guard. |
21D8BA5 | 0x1800 | If user has ability Sniper and move was a critical hit. |
21D8B71 | 0xC00 | If the target's ability is Solid Rock or Filter and the move was super effective. |
21DBA95 | Internal. | |
21DEC91 | Variable | If the user is holding the item Metronome. If n is the number of time the current move was used successfully and successively, the value of the modifier is 0x1000+n*0x333 if n≤4 and 0x2000 otherwise. |
21DEBD5 | 0x1333 | If the user is holding an expert belt and the move was super effective. |
21DEC65 | 0x14CC | If the user is holding a Life Orb. |
21DDB85 | 0x800 | If the target is holding a damage lowering berry of the attack's type. There is one trigger for each type of berry, the others are at: 21DDC05, 21DDAE5, 21DDB05, 21DDB25, 21DDB45, 21DDB65, 21DDBA5, 21DDBC5, 21DDBE5, 21DDC25, 21DDC45, 21DDC65, 21DDC85, 21DDCA5, 21DDCC5 and 21DDCE5. |
21E3A25 | 0x2000 | If move is Stomp and target has used Minimize. |
21E316D | 0x2000 | If move is Earthquake and target is in the charging turn of Dig. |
21E39E1 | 0x2000 | If move is Surf and target is in the charging turn of Dive. |
21E1455 | 0x2000 | If move is Steamroller and target has used Minimize. |
Trigger address | Summary of BP formula | Move and remarks. |
---|---|---|
21d88cc | Internal. | |
21e2aec | ((255 - Happiness) * 10) ÷ 25 | Frustration: if result is 0 add 1. |
21e2968 | 50, 100 | Payback: BP is doubled to 100 if target has moved this turn, 50 otherwise. |
21e2aa0 | (Happiness * 10) ÷ 25 | Return: if result is 0 add 1. |
21e7184 | 150, 120, 80, 60, 40 | Electro Ball: Let S = UserModSpeed ÷ TargetModSpeed. BP = {150: S ≥ 4, 120: 3 ≤ S < 4, 80: 2 ≤ S < 3, 60: 1 ≤ S < 2, 40: otherwise}; |
21e283c | 60, 120 | Avalanche: BP is doubled to 120 if the target has inflicted non-effect damage to the user this turn. |
21e27d0 | min(150, 25 * TargetSpd ÷ UserSpd) | Gyro Ball. |
21e29a8 | (150 * CurrentHP) ÷ MaxHP | Eruption, Water Spout: if result is 0 set BP to 1. |
21e2de0 | min(120, 60 + 20 * statup_total) | Punishment: statup_total is the sum of the target's stat levels that are ≥ 0, including accuracy and evasion. |
21e2e48 | 20 * 2^(use_counter) | Fury Cutter: use_counter counts successive and successful previous uses up to a maximum of 3. |
21e2ef4 | 20, 40, 60, 80, 100, 120 | Low Kick, Grass Knot: let W be the final weight after modifiers. If W ≥ 200, BP is 120, else if W ≥ 100, BP is 100, else if W ≥ 50, BP is 80, else if W ≥ 25, BP is 60, else if W ≥ 10, BP is 40, else BP is 20. |
21e7204 | 40, 80, 120, 160, 200 | Echoed Voice: BP increases in the listed order every turn this move is used successively on the user's side of the field. |
21e702c | 50, 100 | Hex: BP is doubled to 100 if target has a status problem. |
21e2a08 | round(120 * TargetHP%) ÷ 100 | Wring Out, Crush Grip: TargetHP% is computed by a fixed point division using 0x1000 as the scaling factor. |
21e2eb0 | 50, 100 | Assurance: BP is doubled to 100 if target has already been inflicted non-effect damage this turn. |
21e7104 | 120, 100, 80, 60, 40 | Heavy Slam, Heat Crash: let W = UserModWeight ÷ TargetModWeight. BP = {120: W ≥ 5, 100: 4 ≤ W < 5, 80: 3 ≤ W < 4, 60: 2 ≤ W < 3, 40: W < 2}. |
21e70a0 | 20 + 20 * statups | Stored Power: statups is the sum of all positive stat increases, including accuracy and evasion. |
21e706c | 55, 110 | Acrobatics: BP is doubled to 110 if user has no held item. |
21e28b8 | P = (48 * CurrentHP) ÷ MaxHP | Flail, Reversal: 200 if P ≤ 1, 150 if 2 ≤ P ≤ 4, 100 if 5 ≤ P ≤ 9, 80 if 10 ≤ P ≤ 16, 40 if 17 ≤ P ≤ 32, 20 otherwise. |
21e2d7c | 40, 50, 60, 80, 200 | Trump Card: listed BP correspond to decreasing PP (if PP is ≥ 5 or this move was called by another move BP is 40). |
21e7dd0 | 60, 120 | Round: BP is doubled to 120 if used in direct succession of an ally. |
21e2788 | 10, 20, 30 | Triple Kick: BP is listed for the successive hits. |
21e2b38 | 60, 120 | Wake-Up Slap: BP is doubled to 120 if target is asleep. |
21e2bd4 | 60, 120 | SmellingSalt: BP is doubled to 120 is target is paralyzed. |
21e2fd0 | 50, 100 | Weather Ball: BP is doubled to 100 in any non-default weather. |
21e302c | 40, 80 | Gust, Twister: BP is doubled to 80 is target is in the charging turn of Bounce, Fly or Sky Drop. |
21e6074 | CurrentPartyMemberAttack ÷ 10 + 5 | Beat Up: this move attacks once for every non fainted member in the user's party, including the user. |
21e3318 | 30 + (40 * sum(((IV[i]>>1)&1)<<i)) ÷ 63 | Hidden Power: IV are indexed from 0 and listed as HP, At, Df, Sp, SA, SD. |
21e17d0 | 100 * stockpile | Spit Up: stockpile is the stockpile counter ranging from 0 to 3. |
21e1dbc | 40, 80 | Pursuit: BP is doubled to 80 if target is switching out. |
21e2d40 | 40, 80 or 120 | Present: let 0 ≤ r < 80 be a random number. If r < 40, BP is 40, else if r < 70, BP is 80, otherwise BP is 120. |
21e33dc | Variable | Natural Gift: base power and type depend on held berry. See 2021030 and 20210E4 for corresponding tables. |
21e398c | 10 + 20 * factor | Magnitude: let R = rand(100), factor = {0: R < 5, 1: 5 ≤ R < 15, 2: 15 ≤ R < 35, 3: 35 ≤ R < 65, 4: 65 ≤ R < 85, 5: 85 ≤ R < 95, 7: R ≥ 95}. |
21e2720 | 30 * 2 ^ (use_counter + defense_curl) | Rollout: use_counter counts successive and successful previous uses up to a maximum of 5, defense_curl is 1 if user used Defense Curl previously on field, 0 otherwise. |
21e5d44 | Variable | Fling: base power depends on the held item. See 21D807C for table of items. |
21e84b8 | 150 | Grass/Fire/Water Pledge: if a slower ally used a different Pledge move this turn, it will skip its turn and this move's base power will be set to 150. |
Trigger address | Modifier | Trigger description |
---|---|---|
21d9108 | 0x1800 | If user has ability Technician and move's base power is ≤60. |
21dc27c | 0x1800 | If user has ability Flare Boost, is burned and uses a special move. |
21dc6c0 | 0x14CD | If user has ability Analytic, move isn't Future Sight or Doom Desire and target has already moved this turn. |
21d9174 | 0x1333 | If user has ability Reckless and move has recoil or is either Jump Kick or Hi Jump Kick. |
21d9138 | 0x1333 | If the user has ability Iron Fist and move has the "Punching move" (0x7) flag set. |
21dc238 | 0x1800 | If user has ability Toxic Boost, is poisoned and move is physical. |
21d9090 | Variable | If user has ability Rivalry. The value of the modifier is 0x1000 if either the user or target is genderless, 0x1400 if the user and target are of the same gender and 0xC00 otherwise. |
21dc718 | 0x14CD | If user has ability Sand Force and move is Rock, Ground or Steel type. |
21da864 | 0x800 | If target has ability Heatproof and move is Fire type. |
21daa90 | 0x1400 | If target has ability Dry Skin and move is Fire type. |
21dbf48 | 0x14CD | If the user has ability Sheer Force and move has a flag (0xA) set. |
21d9dc4 | Internal. | |
Multiple | 0x1333 | Type boosting items, plates, incenses. All are wrappers for the 21DF95C trigger. List of locations: 21df7a8, 21df878, 21df760, 21df748, 21df778, 21df7c0, 21df860, 21df890, 21df730, 21df908, 21df950, 21df790, 21df7d8, 21df7f0, 21df808, 21df718, 21df8c0, 21df938, 21df920, 21df8d8, 21df8a8. |
21de6ec | 0x1199 | If user holds a Muscle Band and move is physical. |
21df994 | 0x1333 | If user is Palkia, holds the Lustrous Orb and move is Water or Dragon type. |
21de72c | 0x1199 | If user holds Wise Glasses and move is special. |
21df458 | 0x1333 | If user is Giratina, holds the Griseous Orb and move is Dragon or Ghost type. |
21df8f0 | 0x1333 | If user holds Odd Incense and move is Psychic type. |
21df9e8 | 0x1333 | If user is Dialga, holds the Adamant Orb and move is Steel or Dragon type. |
21e01e4 | 0x1800 | If user holds a Normal Gem and move is normal type. Similar triggers for the other types are at: 21DFF14, 21DFF40, 21DFF6C, 21DFF98, 21DFFC4, 21DFFF0, 21E001C, 21E0048, 21E0074, 21E00A0, 21E00CC, 21E00F8, 21E0124, 21E0150, 21E017C, 21E01A8 |
21e2928 | 0x2000 | If move is Facade and user is either paralyzed, poisoned or burned. |
21e2a58 | 0x2000 | If move is Brine and target's HP is ≤ 50%. |
21e6fe8 | 0x2000 | If move is Venoshock and target is poisoned. |
21e729c | 0x2000 | If move is Retaliate and a Pokémon from the target's party fainted on the previous turn. |
21e8330 | 0x2000 | If move is either Fusion Bolt or Fusion Flare and the previously used move was respectively Fusion Flare or Fusion Bolt. |
21e6f34 | 0x1800 | If move was called using Me First. |
21e64a0 | 0x800 | If move is SolarBeam in non-sunny, non-default weather. |
21e1f38 | 0x2000 | If user used Charge the previous turn and move is Electric type. |
21e5ff0 | 0x1800 | If user has been the target of Helping Hand this turn. |
6898158 | 0x548 | If Water Sport was used by any Pokémon still on the field and move is Fire type. |
6898110 | 0x548 | If Mud Sport was used by any Pokémon still on the field and move is Electric type. |
The first step of computing the attack stat is to decide whether the attack or special attack stat should be used, and on which Pokémon. By default, the user's attack is used if the move is physical and the special attack otherwise but this behavior can be altered by the following triggers:
Trigger address | Trigger description |
---|---|
21da828 | Unaware: if target has ability Unaware do not apply any attack level boosts. |
21d8db0 | Internal. |
21e7320 | Foul Play: use the target's base attack stat instead of the user's. |
21e39b0 | Internal. |
Stat boost level | Multiplier | Decimal Approximate |
---|---|---|
-6 | 2/8 | 0.25 |
-5 | 2/7 | 0.2857 |
-4 | 2/6 | 0.3333 |
-3 | 2/5 | 0.4 |
-2 | 2/4 | 0.5 |
-1 | 2/3 | 0.6667 |
0 | 2/2 | 1 |
+1 | 3/2 | 1.5 |
+2 | 4/2 | 2 |
+3 | 5/2 | 2.5 |
+4 | 6/2 | 3 |
+5 | 7/2 | 3.5 |
+6 | 8/2 | 4 |
Trigger address | Modifier | Trigger description |
---|---|---|
21d871c | 0x800 | If target has ability Thick Fat and move is Ice or Fire type. |
21d8c78 | 0x1800 | If user has ability Torrent, has MaxHP ÷ 3 or less HP and move is water type. |
21d8d14 | 0x1800 | If user has ability Guts, has a status problem and move is physical. |
21d8cb0 | 0x1800 | If user has ability Swarm, has MaxHP ÷ 3 or less HP and move is bug type. |
21d8c94 | 0x1800 | If user has ability Overgrow, has MaxHP ÷ 3 or less HP and move is grass type. |
21d8d60 | 0x1800 | If user has ability Plus or Minus and an ally has ability Plus or Minus and move is special. |
21d8c5c | 0x1800 | If user has ability Blaze, has MaxHP ÷ 3 or less HP and move is fire type. |
21dc0dc | 0x800 | If user has ability Defeatist and CurrentHP ≤ MaxHP ÷ 2. |
21d8754 | 0x2000 | If user has ability Pure Power or Huge Power and move is physical. |
21d9954 | 0x1800 | If user has ability Solar Power and weather is intense sunlight and move is special. |
21d8894 | 0x1800 | If user has ability Hustle and move is physical. This is a special trigger in the sense that instead of chaining it will directly apply the 0x1800 on the current attack stat instead of being chained with others. |
21daf04 | 0x1800 | If user has ability Flash Fire activated and move is Fire type. |
21d892c | 0x800 | If user has ability Slow Start, has been on field for less than 5 turns and move is physical. |
21d8fec | 0x1800 | If ally is Cherrim and has ability Flower Gift, weather is intense sunlight and move is physical. |
21db424 | Internal. | |
21de91c | 0x2000 | If user is Cubone or Marowak, holds a Thick Club and move is physical. |
21de76c | 0x2000 | If user is Clamperl, holds a DeepSeaTooth and move is special. |
21df53c | 0x2000 | If user is Pikachu and holds a Light Ball. |
21de898 | 0x1800 | If user is Latios or Latias, holds a Soul Dew and move is special. |
21de968 | 0x1800 | If user is holding Choice Band and move is physical. |
21de9a0 | 0x1800 | If user is holding Choice Specs and move is special. |
21e310c | Internal. |
Just like for the attack stat, the first step is to decide which defense stat to use and whether to apply the active boost level. This is done by the following triggers:
Trigger address | Trigger description |
---|---|
21da840 | Unaware: if foe has ability Unaware do not apply any Defense level boosts. |
21d8db0 | Internal. |
21e7944 | This triggers is used for special moves that deal physical damage. It replaces the identifier of the base special defense stat with the one for defense. |
21e797c | Chip Away: ignore defense level boosts if foe has it. |
68981a0 | Wonder Room: has the same effect as 21e7944 but for all Pokémon on field. Will also cancel the effect of 21e7944. |
Trigger address | Modifier | Trigger description |
---|---|---|
21d91bc | 0x1800 | If target has ability Marvel Scale, has a status problem and move is physical. |
21d903c | 0x1800 | If ally is Cherrim and has ability Flower Gift, weather is intense sunlight and move is special. |
21db8f0 | Internal. | |
21de7bc | 0x1800 | Is target is Clamperl, holds a DeepSeaScale and move is special. |
21de804 | 0x2000 | Is target is (untransformed) Ditto, holds Metal Powder and move is physical. |
21dfaa8 | 0x1800 | If target is holding Eviolite and is not fully evolved. |
21de8d4 | 0x1800 | If target is Latios or Latias holding a Soul Dew and move is special. |
Trigger address | Trigger description |
---|---|
21e1608 | Psywave: damage is always max(1, ((rand(101) + 50) * UserLevel) ÷ 100) |
21e15d0 | Night Shade: damage is always UserLevel. |
21e1504 | SonicBoom: damage is always 20. |
21e1498 | Super Fang: damage is always max(1, TargetHP ÷ 2). |
21e14e0 | Dragon Rage: damage is always 40. |
21e1578 | Endeavor: damage is always max(0, TargetHP-UserHP). |
21e7c98 | Final Gambit: damage is always UserHP. |
21e0838 | Brick Break: cancels the effect of Reflect / Light Screen. |
21e1978 | Counter: if last Pokémon to hit the user was a foe using a physical move, use double the set damage. |
21e19bc | Mirror Coat: same as Counter for special moves. |
21e1a00 | Metal Burst: if the user was hit by an attack earlier this turn, use 1.5 times the set damage. |
21e3e50 | Bide: store energy for 2 turns, then set damage to twice the total damage dealt to user during the charging turns. |