Damage modifier
A damage modifier changes a damage calculation by changing an input or transforming an intermediate or final value.
A damage modifier changes a damage calculation by changing an input or transforming an intermediate or final value. Games use additions, multipliers, and formula changes, so the phrase does not imply one shared operation1,2,3. The recurring kinds covered here are critical hits, elemental weakness, same-type attack bonus (STAB), and type effectiveness.
#What changes
| Operation | Example | Point in the calculation |
|---|---|---|
| Add to an input | Final Fantasy II adds 20 to attack power when the weapon type or element matches the target1. | Before the damage roll and defense subtraction1,4. |
| Scale an input | Final Fantasy’s spell elements halve or multiply spell power by 1.52. | Before the spell’s damage roll from power to twice power2,5. |
| Multiply damage | Red and Blue’s STAB adds half the current damage, rounded down6. | Before its type-chart rows6. |
| Change the formula or add damage | Red and Blue doubles the level used by the base formula on a critical3. Final Fantasy adds the swing’s damage roll again7. | Inside the base formula in Red and Blue; after the ordinary damage roll in Final Fantasy3,7. |
These labels describe different arithmetic. STAB’s half-again bonus is equivalent to multiplying non-negative integer damage by 1.5 and rounding down6. Type effectiveness instead multiplies the current damage once for each matching defender type, truncating after each row in Red and Blue8. Fire Emblem: The Sacred Stones applies effectiveness to weapon might plus the weapon-triangle bonus before adding Strength9.
Critical hits also vary in what they change. Pokémon Red and Blue changes the level and stat inputs; Pokémon Emerald doubles base damage and ignores some stat changes; Fire Emblem: The Sacred Stones triples the hit’s damage3,10,11. Final Fantasy’s physical critical adds that swing’s damage again without subtracting absorb from the added amount7.
#Order and stacking
There is no shared stacking order. In Pokémon Red and Blue, a damaging move checks for a critical, computes base damage, applies STAB, walks the type rows, applies the random factor, and then checks accuracy12. The critical changes the base-formula inputs before that formula runs3. Each type row truncates before the next row, so reversing two opposing rows can change the result8,13.
Emerald keeps the same broad placement of critical calculation, base damage, STAB and type rows, then the random factor14. Its critical multiplier applies during base damage, before STAB and the chart10,15,16. Other games put modifiers at different points: Final Fantasy II adds its weakness bonus to attack before rolling damage, then adds attack again for a critical hit within each hit’s damage calculation1,4.
The damage formula page describes each game’s full calculation. A modifier’s name alone does not establish its arithmetic or order; those come from the game’s implementation.
References
- ^ abcdWhen the weapon's type bonus matches the target's type, or the weapon's element matches one of the target's weak elements, the attack power gains 20 before the damage is rolled.Codeeverything8215, FF2 disassembly
How we know
163320C/B086: B1 9F LDA ($9F),Y ; main hand attack power ⋮ 163370C/B090: B1 9F LDA ($9F),Y ; main hand type bonus 163380C/B092: A0 15 LDY #$15 163390C/B094: 31 A1 AND ($A1),Y ; target type 163400C/B096: D0 0A BNE $B0A2 163410C/B098: A0 1B LDY #$1B 163420C/B09A: B1 9F LDA ($9F),Y ; main hand element 163430C/B09C: A0 16 LDY #$16 163440C/B09E: 31 A1 AND ($A1),Y ; target weak elements 163450C/B0A0: F0 0D BEQ $B0AF 163460C/B0A2: 18 CLC 163470C/B0A3: A5 44 LDA $44 ⋮
ff2j.asm lines 16331–16360 at 8d26190 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^ abcA resisted element halves a damage spell's power and drops the 148 from its doubling chance; a weakness multiplies the power by 1.5 and adds 40 to the chance.CodeDisch, FF1 disassembly
How we know
8289 AND btlmag_defender_elemresist ; see if the defender resists this element ⋮ 8291 JSR BtlMag_ZeroHitChance ; ... zero the hit/crit chance 8292 LSR math_basedamage+1 ; and halve the damage ⋮ 8296 AND btlmag_defender_elemweakness ; see if they are weak to the element ⋮ 8300 JSR MathBuf_Add ; crit bonus of +40 ⋮ 8302 ; damage *= 1.5
Final Fantasy Disassembly/bank_0C.asm lines 8288–8313 at cbb87d3 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^ abcdeA critical hit doubles the level in the damage formula and takes both Pokémon's stats from their party data, so stat stages, Reflect, and Light Screen drop out.Codepret/pokered
How we know
4056 ld a, [wCriticalHitOrOHKO] 4057 and a ; check for critical hit 4058 jr z, .scaleStats 4059; in the case of a critical hit, reset the player's attack and the enemy's defense to their base values 4060 ld c, STAT_DEFENSE 4061 call GetEnemyMonStat
engine/battle/core.asm lines 4054–4072 at af51989 · upstream ↗ 4131 ld a, [wBattleMonLevel] 4132 ld e, a ; e = level 4133 ld a, [wCriticalHitOrOHKO] 4134 and a ; check for critical hit 4135 jr z, .done 4136 sla e ; double level if it was a critical hit
engine/battle/core.asm lines 4131–4136 at af51989 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^ abEach hit that gets through deals attack plus a random 0 to attack, less the target's defense (at least 0), and the hits add up. Each hit also rolls 0–100, and a roll under 5 makes it critical, adding the attack again.Codeeverything8215, FF2 disassembly
How we know
18008; [ calculate damage ] ⋮ 18010; $44: attack 18011; $46: defense 18012; $48: number of hits 18013; +$4A: damage ⋮ 18030; start of hit loop 180310C/BCA7: A2 00 LDX #$00 180320C/BCA9: A5 44 LDA $44 180330C/BCAB: 20 11 FD JSR $FD11 ; random (X..A) 180340C/BCAE: 18 CLC 180350C/BCAF: 65 44 ADC $44 ; attack * (0..1) ⋮ 180410C/BCBA: A5 4C LDA $4C ; subtract defense ⋮
ff2j.asm lines 18008–18074 at 8d26190 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^A damage spell always connects, for a random value from its power to ; its roll of 0–200 against 148 + the spell's hit rate − the target's magic defense doubles the damage instead of deciding a hit.CodeDisch, FF1 disassembly
How we know
8284 JSR BtlMag_MarkSpellConnected ; damage spells always connect 8285 JSR BtlMag_LoadBaseHitChance ; load base hit chance (since damage always hits, this becomes more of a "critical" chance)
Final Fantasy Disassembly/bank_0C.asm lines 8283–8286 at cbb87d3 · upstream ↗ 8208 LDA #<148 ; base hit chance of 148Final Fantasy Disassembly/bank_0C.asm lines 8207–8211 at cbb87d3 · upstream ↗ 8156 JSR MathBuf_Add ; math_hitchance += spell's base hit rate ⋮ 8160 JSR MathBuf_Sub ; math_hitchance -= defender's magdef ⋮ 8168 JSR MathBuf_Add ; math_basedamage = rand[ spelldamage, spelldamage*2 ]
Final Fantasy Disassembly/bank_0C.asm lines 8153–8171 at cbb87d3 · upstream ↗ 8328 BEQ :+ ; if the hit/crit roll was 200, this is NOT a crit ⋮ 8331 ASL math_basedamage ; ... do 2x damage
Final Fantasy Disassembly/bank_0C.asm lines 8325–8332 at cbb87d3 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^ abc
AdjustDamageForMoveTypeapplies STAB before any type row: when the move's type matches either attacker type.Codepret/pokeredHow we know
5116 srl b 5117 rr c ; bc = floor(0.5 * damage) 5118 add hl, bc ; hl = floor(1.5 * damage)
engine/battle/core.asm lines 5101–5125 at af51989 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^ abcA swing is critical when its roll is at most the crit chance, which is capped at the hit chance; a critical adds the swing's random damage again, with no absorb taken from it.CodeDisch, FF1 disassembly
How we know
4404 LDA math_hitchance ; crit chance cannot exceed hit chanceFinal Fantasy Disassembly/bank_0C.asm lines 4401–4405 at cbb87d3 · upstream ↗ 4515 LDA math_critchance ; see if hit value is <= crit chance (this will be impossible if the attack was a miss) ⋮ 4519 LDX math_basedamage ; add random damage to our total 4520 JSR MathBuf_Add 4521 INC battle_critsconnected
Final Fantasy Disassembly/bank_0C.asm lines 4514–4521 at cbb87d3 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^ abIn table order, each
TypeEffectsrow matching the move's type and either defender type sets damage to ; 0 marks a miss.Codepret/pokeredHow we know
5161 call Multiply 5162 ld a, 10 5163 ldh [hDivisor], a 5164 ld b, 4 5165 call Divide
engine/battle/core.asm lines 5127–5185 at af51989 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^In the North American build, damage is attack less defense, where attack is the weapon's might plus the triangle's damage bonus, tripled when the attacker or its weapon is effective against the target (doubled instead when the effective weapon is one of eight legendary weapons), plus the attacker's strength, and defense is terrain defense plus Defense, or terrain resistance plus Resistance against magic; no roll changes it except two skills, Pierce (which sets defense to 0) and Great Shield (which sets the damage to 0); a critical triples it, and the result is held within 0–127.Codefireemblem8urevised
How we know
512 if (GetItemAttributes(defender->weapon) & IA_MAGICDAMAGE) 513 attacker->battleDefense = attacker->terrainResistance + attacker->unit.res; ⋮ 515 attacker->battleDefense = attacker->terrainResistance + attacker->unit.res; ⋮ 517 attacker->battleDefense = attacker->terrainDefense + attacker->unit.def;
src/bmbattle.c lines 511–517 at 04d1edb · upstream ↗ 527 attacker->battleAttack = GetItemMight(attacker->weapon) + attacker->wTriangleDmgBonus; ⋮ 530 if (IsUnitEffectiveAgainst(&attacker->unit, &defender->unit) == TRUE) 531 attack = attacker->battleAttack * 3; ⋮ 533 if (IsItemEffectiveAgainst(attacker->weapon, &defender->unit) == TRUE) { ⋮ 538 case ITEM_SWORD_AUDHULMA: ⋮ 545 case ITEM_LANCE_SIEGMUND: 546 attack *= 2; ⋮ 549 default: 550 attack *= 3; ⋮ 556 attacker->battleAttack = attack; 557 attacker->battleAttack += attacker->unit.pow;
src/bmbattle.c lines 527–557 at 04d1edb · upstream ↗ 1022 if (gBattleHitIterator->attributes & BATTLE_HIT_ATTR_PIERCE) 1023 defense = 0; ⋮ 1025 gBattleStats.damage = attack - defense; ⋮ 1027 if (gBattleHitIterator->attributes & BATTLE_HIT_ATTR_GREATSHLD) 1028 gBattleStats.damage = 0;
src/bmbattle.c lines 1022–1028 at 04d1edb · upstream ↗ 1030 if (BattleRoll1RN(gBattleStats.critRate, FALSE) == TRUE) { ⋮ 1039 gBattleStats.damage = gBattleStats.damage * 3;
src/bmbattle.c lines 1030–1039 at 04d1edb · upstream ↗ 1043 if (gBattleStats.damage > BATTLE_MAX_DAMAGE) 1044 gBattleStats.damage = BATTLE_MAX_DAMAGE; ⋮ 1046 if (gBattleStats.damage < 0) 1047 gBattleStats.damage = 0;
src/bmbattle.c lines 1043–1047 at 04d1edb · upstream ↗ 16 // Maximum battle damage 17 BATTLE_MAX_DAMAGE = 127,
include/bmbattle.h lines 16–17 at 04d1edb · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Revised after a check by a second AI model, 2026-10-21.
- ^ ab
Cmd_damagecalcmultiplies the base damage by 2 on a critical;CalculateBaseDamagethen ignores the attacker's lowered attacking stat, the defender's raised defending stat, and Reflect or Light Screen.Codepret/pokeemeraldHow we know
1296 gBattleMoveDamage = gBattleMoveDamage * gCritMultiplier * gBattleScripting.dmgMultiplier;src/battle_script_commands.c line 1296 at 731ad5b · upstream ↗ 3234 if (gCritMultiplier == 2) ⋮ 3236 // Critical hit, if attacker has lost attack stat stages then ignore stat drop ⋮ 3248 if (gCritMultiplier == 2) ⋮ 3250 // Critical hit, if defender has gained defense stat stages then ignore stat increase ⋮ 3267 if ((sideStatus & SIDE_STATUS_REFLECT) && gCritMultiplier == 1)
src/pokemon.c lines 3234–3268 at 731ad5b · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^In the North American build, a unit's crit is its weapon's crit plus half its skill, plus 15 for classes with a crit bonus; the crit shown and rolled is that less the defender's luck, at least 0, and one random number from 0 to 99 below it triples the hit's damage.Codefireemblem8u
How we know
589 bu->battleCritRate = GetItemCrit(bu->weapon) + (bu->unit.skl / 2); ⋮ 591 if (UNIT_CATTRIBUTES(&bu->unit) & CA_CRITBONUS) 592 bu->battleCritRate += 15; ⋮ 596 bu->battleDodgeRate = bu->unit.lck;
src/bmbattle.c lines 588–597 at 04d1edb · upstream ↗ 612 attacker->battleEffectiveCritRate = attacker->battleCritRate - defender->battleDodgeRate; ⋮ 615 attacker->battleEffectiveCritRate = 0; ⋮ 617 if (attacker->battleEffectiveCritRate < 0) 618 attacker->battleEffectiveCritRate = 0;
src/bmbattle.c lines 612–618 at 04d1edb · upstream ↗ 85s8 Roll1RN(int threshold) { 86 return (threshold > NextRN_100());
src/rng.c lines 85–87 at 04d1edb · upstream ↗ 1030 if (BattleRoll1RN(gBattleStats.critRate, FALSE) == TRUE) { ⋮ 1038 gBattleHitIterator->attributes = gBattleHitIterator->attributes | BATTLE_HIT_ATTR_CRIT; 1039 gBattleStats.damage = gBattleStats.damage * 3;
src/bmbattle.c lines 1030–1039 at 04d1edb · upstream ↗ 883 gBattleStats.critRate = attacker->battleEffectiveCritRate;src/bmbattle.c line 883 at 04d1edb · upstream ↗ 243 critRate = gBattleActor.battleEffectiveCritRate;src/bksel.c line 243 at 04d1edb · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^In Red and Blue, a damaging move runs
CriticalHitTest,CalculateDamage(base formula),AdjustDamageForMoveType(STAB, then type rows),RandomizeDamage, and thenMoveHitTest(accuracy).Codepret/pokeredHow we know
3144 call CalculateDamage ⋮ 3147 call AdjustDamageForMoveType 3148 call RandomizeDamage 3149.moveHitTest 3150 call MoveHitTest
engine/battle/core.asm lines 3140–3150 at af51989 · upstream ↗ engine/battle/core.asm#L5531-L5543 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^Truncating after each row can cost a hit that nets ×1 damage when its ½ row comes first: Ice against Water/Flying takes 3 to ⌊3 × 5 / 10⌋ = 1, then ⌊1 × 20 / 10⌋ = 2, not 3.Codepret/pokeredrevised
How we know
33 db ICE, WATER, NOT_VERY_EFFECTIVE ⋮ 36 db ICE, FLYING, SUPER_EFFECTIVE
data/types/type_matchups.asm lines 33–36 at af51989 · upstream ↗ Measured by a script. It fails if the result disagrees with the claim.
Checked against the evidence by its author, an AI model, 2026-10-20.
Revised after a check by a second AI model, 2026-10-21.
- ^A plain damaging move runs critcalc, damagecalc (base damage), typecalc (STAB, then type rows), and then adjustnormaldamage (random factor).Codepret/pokeemerald
How we know
249 critcalc 250 damagecalc 251 typecalc 252 adjustnormaldamage
data/battle_scripts_1.s lines 249–252 at 731ad5b · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^Before the type chart,
Cmd_typecalcapplies STAB as when either attacker type equals the move's type.Codepret/pokeemeraldHow we know
1368 // check stab 1369 if (IS_BATTLER_OF_TYPE(gBattlerAttacker, moveType)) ⋮ 1371 gBattleMoveDamage = gBattleMoveDamage * 15; 1372 gBattleMoveDamage = gBattleMoveDamage / 10;
src/battle_script_commands.c lines 1368–1373 at 731ad5b · upstream ↗ include/battle.h#L471 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^For each row of the move's type,
ModulateDmgByTyperuns once per distinct target type it matches: , raised from 0 to 1 unless the multiplier is 0.Codepret/pokeemeraldHow we know
1323 gBattleMoveDamage = gBattleMoveDamage * multiplier / 10; 1324 if (gBattleMoveDamage == 0 && multiplier != 0) 1325 gBattleMoveDamage = 1;
src/battle_script_commands.c lines 1321–1325 at 731ad5b · upstream ↗ 1401 if (TYPE_EFFECT_DEF_TYPE(i) == gBattleMons[gBattlerTarget].types[1] && 1402 gBattleMons[gBattlerTarget].types[0] != gBattleMons[gBattlerTarget].types[1])
src/battle_script_commands.c lines 1386–1406 at 731ad5b · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
Sources
Code
- everything8215. 2022. “Final Fantasy II (NES) disassembly and ROM info.” Commit 8d26190. everything8215/ff2 @ 8d26190 · licence, all uses
- Disch. 2019. “Final Fantasy Disassembly.” Commit cbb87d3. BenWenger/FinalFantasyDisassembly @ cbb87d3 · licence, all uses
- pret contributors. 2026. “pokered: disassembly of Pokémon Red and Blue.” pret. Commit af51989. pret/pokered @ af51989 · licence, all uses
- FireEmblemUniverse contributors. 2026. “fireemblem8u: decompilation of Fire Emblem: The Sacred Stones.” FireEmblemUniverse. Commit 04d1edb. FireEmblemUniverse/fireemblem8u @ 04d1edb · licence, all uses
- pret contributors. 2026. “pokeemerald: decompilation of Pokémon Emerald.” pret. Commit 731ad5b. pret/pokeemerald @ 731ad5b · licence, all uses