Multi-hit attack
One attack command that resolves as several hits, each dealing damage.
On this page
A multi-hit attack resolves one command as several hits. In Final Fantasy, every physical attack is a series of swings1, for hit rate . In the Pokémon games, a handful of moves hit two to five times2,3,4.
- Swings from a statFinal Fantasy (1987). A character swings more times per attack as their hit rate grows, and each swing can hit or crit.1,5
- Hits less evadesFinal Fantasy II (1988). A trained fighter swings several times in one attack, and each swing that gets past the target's dodges deals its own damage.6,7Final Fantasy III (1990). A fighter strikes several times in one attack, and every strike that gets through deals the same damage.8,9Final Fantasy IV (1991). A stronger, quicker fighter strikes more times in one attack, and every strike that lands deals the same damage.10,11,12
- Repeat the first hitPokémon Red and Blue (1996). 2–5 hits, every one copying the first hit's damage.2,13,14Pokémon Yellow (1998). Red and Blue's 2–5 hits, each copying the first.15
- Per-hit damagePokémon Gold and Silver (1999). 2–5 hits, each with its own critical and damage roll.16Pokémon Crystal (2000). 2–5 hits, each with its own critical and damage roll.3Pokémon Ruby and Sapphire (2002). 2–5 hits at Red and Blue's odds, each with its own critical and damage roll.17Pokémon Emerald (2004). 2–5 hits, each with its own critical and damage roll.4Pokémon FireRed and LeafGreen (2004). Emerald's 2–5 hits, line for line.18
#How it works
n = hit_count(attacker, move) # Final Fantasy: from hit rate; Pokémon: a roll
for each of the n hits:
roll to hit? # Final Fantasy: every swing; Pokémon: once, before the first
roll a critical? # Final Fantasy, Crystal, Emerald: every hit; Red/Blue: once
roll damage? # Final Fantasy, Crystal, Emerald: every hit; Red/Blue: copy the first
The count and the three rolls are the design choices. A per-hit roll smooths the total; a single roll makes every hit alike.
| Hits | Hit roll | Critical | Damage | |
|---|---|---|---|---|
| Final Fantasy | swings1; ×2 with FAST1 | every swing19 | every swing20 | every swing21 |
| Red and Blue | 2 (3/8) · 3 (3/8) · 4 (1/8) · 5 (1/8)2 | once13 | once13 | the first hit’s, repeated13 |
| Crystal | 2 (3/8) · 3 (3/8) · 4 (1/8) · 5 (1/8)3; Triple Kick 1–33 | once3 | every hit3 | every hit3 |
| Emerald | 2 (3/8) · 3 (3/8) · 4 (1/8) · 5 (1/8)4 | once4 | every hit4 | every hit4 |
#Implementations
#Final Fantasy
A character makes swings1 per attack, for hit rate , and FAST doubles the count1. An unarmed Black Belt or Master swings twice as often1. Level-ups raise hit rate up to 200, so the count grows over the game1.
Each swing has its own hit roll, critical test, and damage roll, and the damage of every swing adds into one total19,20,21. Run in the ROM for all 256 generator states, four swings at hit chance 228 land 1,020 of 1,024 swings, 109 of them critical5. With FAST, eight swings land 2,040 of 2,0485.
#Final Fantasy II to V
Final Fantasy II replaces Final Fantasy’s single hit chance with two sets of rolls: one per point of the attacker’s hit multiplier, less the target’s successful evade rolls22,6. Each hit left rolls its own damage, and the hits add up7. Final Fantasy III rolls damage once and multiplies it by the net hits9. Final Fantasy IV keeps that attack, with STR/8 + AGI/16 + 111 hit rolls for a character12. Final Fantasy V drops the loop for one hit roll and one evade roll, so a weapon attack lands or misses as a whole23.
#Pokémon Red and Blue
Doubleslap, Comet Punch, Fury Attack, Pin Missile, Spike Cannon, Barrage, and Fury Swipes hit 2 (3/8) · 3 (3/8) · 4 (1/8) · 5 (1/8)2. The mean is exactly 3 hits:
Double Kick, Bonemerang, and Twineedle always hit twice2. The count is set after the first hit lands, and every later hit skips the critical test, the damage formula, and the accuracy roll, repeating the first hit’s damage13. A critical first hit therefore makes every hit critical, and a first hit that misses ends the move13.
Pokémon Yellow keeps TwoToFiveAttacksEffect and the damage loop, so every hit after the first still repeats it15,13.
#Pokémon Crystal
Crystal keeps the odds of two to five hits and adds Triple Kick, which hits 1, 2, or 3 times, each a third of the time3. After each hit, the battle script jumps back to the critical command, so every hit rolls its own critical and damage3. The accuracy check sits before the loop and runs once3.
Crystal’s loop is Pokémon Gold and Silver’s BattleCommand_EndLoop, kept apart from a comment16,3.
#Pokémon Emerald
Emerald draws the count the same way4. Its loop reruns critcalc and damagecalc for every hit after one accuracycheck, and stops early when the target faints4.
Pokémon Ruby and Sapphire’s atk8D_setmultihitcounter is the same code as Emerald’s, and its script also checks accuracy once and loops the critical and damage rolls17,4. Pokémon FireRed and LeafGreen’s Cmd_setmultihitcounter is Emerald’s line for line18.
#Variants and combinations
- Critical hit and hit chance are the rolls a multi-hit attack can repeat or share; the table above shows each game’s choice.
- Damage formula. Final Fantasy subtracts absorb from each swing separately, at least 1 per hit21.
#History
Final Fantasy (1987) is the earliest game read here with multiple hits per attack24,1. Dragon Warrior’s attacks compute one damage figure and one dodge roll25,26.
Games
| Game | Year | How | Note |
|---|---|---|---|
| Final Fantasy | 1987 | Swings from a stat | a character swings more times per attack as their hit rate grows, and each swing can hit or crit |
| Final Fantasy II | 1988 | Hits less evades | a trained fighter swings several times in one attack, and each swing that gets past the target's dodges deals its own damage |
| Final Fantasy III | 1990 | Hits less evades | a fighter strikes several times in one attack, and every strike that gets through deals the same damage |
| Final Fantasy IV | 1991 | Hits less evades | a stronger, quicker fighter strikes more times in one attack, and every strike that lands deals the same damage |
| Pokémon Red and Blue | 1996 | Repeat the first hit | 2–5 hits, every one copying the first hit's damage |
| Pokémon Yellow | 1998 | Repeat the first hit | Red and Blue's 2–5 hits, each copying the first |
| Pokémon Gold and Silver | 1999 | Per-hit damage | 2–5 hits, each with its own critical and damage roll |
| Pokémon Crystal | 2000 | Per-hit damage | 2–5 hits, each with its own critical and damage roll |
| Pokémon Ruby and Sapphire | 2002 | Per-hit damage | 2–5 hits at Red and Blue's odds, each with its own critical and damage roll |
| Pokémon Emerald | 2004 | Per-hit damage | 2–5 hits, each with its own critical and damage roll |
| Pokémon FireRed and LeafGreen | 2004 | Per-hit damage | Emerald's 2–5 hits, line for line |
Every claim about this mechanic, by game (20)
References
- ^ abcdefghiAn attack swings times for hit rate , times a multiplier that FAST raises from 1 to 2; an unarmed Black Belt or Master swings twice as often.CodeDisch, FF1 disassembly
How we know
5657 LDA (btl_ob_charstat_ptr), Y ; num hits = hitrate / 32 + 1Final Fantasy Disassembly/bank_0C.asm lines 5656–5666 at cbb87d3 · upstream ↗ 4407 : LDA btl_attacker_numhits ; get proper number of hits (numhits * mult) 4408 LDX btl_attacker_numhitsmult ; the mult is essentially the multiplier for the FAST spell 4409 JSR MultiplyXA
Final Fantasy Disassembly/bank_0C.asm lines 4407–4415 at cbb87d3 · upstream ↗ 8618 INC btlmag_defender_numhitsmult ; Increase hit multiplier ⋮ 8625 LDA #$02 ; and max the multiplier at 2
Final Fantasy Disassembly/bank_0C.asm lines 8616–8627 at cbb87d3 · upstream ↗ 5745 LDY #btlch_numhits ; unarmed BB/master gets 2x as many hitsFinal Fantasy Disassembly/bank_0C.asm lines 5745–5748 at cbb87d3 · upstream ↗ 897 LDY #ch_hitrate - ch_stats ; assign Hit Rate bonus ⋮ 900 ADC lut_LvlUpHitRateBonus, X 901 JSR CapAAt200 ; cap hit rate at 200
Final Fantasy Disassembly/bank_0B.asm lines 897–901 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.
- ^ abcdeDoubleslap, Comet Punch, Fury Attack, Pin Missile, Spike Cannon, Barrage, and Fury Swipes hit 2 or 3 times with probability 3/8 each, and 4 or 5 times with 1/8 each; Double Kick, Bonemerang, and Twineedle always hit twice.Codepret/pokered
How we know
946 cp TWINEEDLE_EFFECT 947 jr z, .twineedle 948 cp ATTACK_TWICE_EFFECT 949 ld a, $2 ; number of hits it's always 2 for ATTACK_TWICE_EFFECT ⋮ 951; for TWO_TO_FIVE_ATTACKS_EFFECT 3/8 chance for 2 and 3 hits, and 1/8 chance for 4 and 5 hits 952 call BattleRandom 953 and $3 954 cp $2 955 jr c, .gotNumHits 956; if the number of hits was greater than 2, re-roll again for a lower chance 957 call BattleRandom 958 and $3 ⋮
engine/battle/effects.asm lines 944–966 at af51989 · upstream ↗ 16 move DOUBLESLAP, TWO_TO_FIVE_ATTACKS_EFFECT, 15, NORMAL, 85, 10 17 move COMET_PUNCH, TWO_TO_FIVE_ATTACKS_EFFECT, 18, NORMAL, 85, 15
data/moves/moves.asm lines 16–17 at af51989 · upstream ↗ 37 move DOUBLE_KICK, ATTACK_TWICE_EFFECT, 30, FIGHTING, 100, 30data/moves/moves.asm line 37 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.
- ^ abcdefghijk
BattleCommand_EndLoopgives 2–5 hits with Red and Blue's odds and Triple Kick 1–3 hits, 1/3 each, and jumps back to thecriticalcommand, so every hit rolls its own critical and damage;checkhitsits before the loop and runs once.Codepret/pokecrystalHow we know
5203BattleCommand_EndLoop: 5204; Loop back to 'critical'. ⋮ 5233.reject_triple_kick_sample 5234 call BattleRandom 5235 and $3 5236 jr z, .reject_triple_kick_sample ⋮ 5271.not_triple_kick 5272 call BattleRandom 5273 and $3 5274 cp 2 5275 jr c, .got_number_hits 5276 call BattleRandom ⋮
engine/battle/effect_commands.asm lines 5203–5284 at 97187cd · upstream ↗ 5320.loop_back_to_critical ⋮ 5327 cp critical_command
engine/battle/effect_commands.asm lines 5320–5328 at 97187cd · upstream ↗ 842MultiHit: 843 checkobedience 844 usedmovetext 845 doturn 846 startloop 847 lowersub 848 checkhit 849 critical 850 damagestats 851 damagecalc
data/moves/effects.asm lines 842–851 at 97187cd · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^ abcdefghi
Cmd_setmultihitcountergives 2 or 3 hits with probability 3/8 each and 4 or 5 with 1/8 each; the loop rerunscritcalcanddamagecalcfor every hit, after oneaccuracycheck.Codepret/pokeemeraldHow we know
7145 else ⋮ 7147 gMultiHitCounter = Random() & 3; 7148 if (gMultiHitCounter > 1) 7149 gMultiHitCounter = (Random() & 3) + 2; 7150 else 7151 gMultiHitCounter += 2;
src/battle_script_commands.c lines 7139–7155 at 731ad5b · upstream ↗ 604BattleScript_EffectMultiHit:: 605 attackcanceler 606 accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE ⋮ 609 setmultihitcounter 0 ⋮ 612BattleScript_MultiHitLoop:: ⋮ 620 critcalc 621 damagecalc 622 typecalc ⋮ 639 decrementmultihit BattleScript_MultiHitLoop
data/battle_scripts_1.s lines 604–639 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.
- ^ abcMeasured the same way, four swings with base damage 40, hit rate 100, and crit chance 20 against evade 40 and absorb 10 land 1,020 of 1,024 swings, 109 of them critical, for 129–413 damage; with FAST, eight swings land 2,040 of 2,048, 213 critical.Verified“Final Fantasy (USA)” · Disch, FF1 disassembly
How we know
In the cartridge (“Final Fantasy (USA)”): bank $0C $A68C-$A8D3, as in hit-loop-measured. We don't reproduce the bytes.
4409 JSR MultiplyXA 4410 STA math_numhits
Final Fantasy Disassembly/bank_0C.asm lines 4407–4415 at cbb87d3 · upstream ↗ Measured by a script in MesenCE 2.2.1 (build 4b8a196), on Final Fantasy (USA) (SHA-1
e8f34d935760…). It fails if the result disagrees with the claim.The numbers come from the run; its author, an AI model, checked the script measures what the claim says, 2026-10-25.
Checked by a second AI model, 2026-10-21.
Checked by a second AI model, 2026-10-25.
- ^ abA Fight action rolls 0–100 once per point of the attacker's hit multiplier (adjusted by haste or slow, at least 1) and counts the rolls under its hit %, then rolls once per point of the target's evade multiplier and counts the rolls under its evade %. The evaded rolls are subtracted from the hits, at least 0, and the rest are the hits that deal damage. Blind halves the attacker's hit % and the target's evade %. The check returns no successes when the attacker is a toad or mini, and the disassembly marks as a bug that the evade check reads the attacker's status too.Codeeverything8215, FF2 disassembly
How we know
16227; [ do fight effect ] ⋮ 162300C/AFBF: B1 9F LDA ($9F),Y ; main hand hit multiplier ⋮ 162330C/AFC4: 71 9F ADC ($9F),Y ; add haste/slow modifier ⋮ 162400C/AFD1: E9 14 SBC #$14 ; subtract 20 ⋮ 162460C/AFDD: A2 01 LDX #$01 ; min 1 ⋮ 162510C/AFE6: B1 9F LDA ($9F),Y ; main hand hit % ⋮ 162570C/AFF3: F0 04 BEQ $AFF9 ; branch if not blind ⋮ 162600C/AFF9: 20 2C BC JSR $BC2C ; check for hit ⋮ 162620C/AFFE: 85 52 STA $52 ; +$52: number of successful hits ⋮ 162660C/B006: B1 A1 LDA ($A1),Y ; target's evade multiplier ⋮ 162690C/B00B: B1 A1 LDA ($A1),Y ; target's evade % ⋮ 162790C/B020: 20 2C BC JSR $BC2C ; check for hit ⋮
ff2j.asm lines 16227–16290 at 8d26190 · upstream ↗ 17943; [ check for hit ] ⋮ 17945; $44: hit % 17946; $46: number of hit attempts 17947; $48: number of successful hits (out) ⋮ 17949; *** bug *** should use target status for evade checks ⋮ 179510C/BC2C: A9 00 LDA #$00 ; start with 0 hits ⋮ 179610C/BC40: A4 46 LDY $46 179620C/BC42: A2 00 LDX #$00 179630C/BC44: A9 64 LDA #$64 179640C/BC46: 20 11 FD JSR $FD11 ; random (X..A) 179650C/BC49: 38 SEC 179660C/BC4A: E5 44 SBC $44 ⋮
ff2j.asm lines 17943–17971 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.
- ^ 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 Fight action rolls 0–99 once per point of the attacker's attack multiplier and counts the rolls under its hit %; Blind halves the hit %, and when a back-row penalty applies (not for a harp or bow and arrow) an attacker in the back row halves it, and a target in the back row halves it again and adds one evaded hit. The target then rolls once per point of its evade multiplier against its evade %, with no evade rolls when it is a toad, mini, or jumping, and its successes are subtracted from the hits, at least 0. The net hits multiply one damage roll, and none is a miss. Each hand rolls separately.Codeeverything8215, FF3 disassemblyrevised
How we know
11953; [ get number of hits ] ⋮ 11955; $24: attack/defense multiplier (no. of hits) 11956; $25: hit/def % 11957; $30: number of hits ⋮ 1195931/BB28: A9 00 LDA #$00 1196031/BB2A: 85 30 STA $30 1196131/BB2C: A5 24 LDA $24 ; no. of hits 1196231/BB2E: F0 11 BEQ $BB41 1196331/BB30: A9 63 LDA #$63 1196431/BB32: 20 B4 BE JSR $BEB4 ; random (0..A) 1196531/BB35: C5 25 CMP $25 ; hit % 1196631/BB37: B0 02 BCS $BB3B ⋮
ff3j.asm lines 11953–11972 at 1acef81 · upstream ↗ 8151; start of loop for 2 hands 815230/9F6A: AD 41 74 LDA $7441 ; attack multiplier ⋮ 815430/9F6F: AD 42 74 LDA $7442 ; hit % ⋮ 816030/9F7C: 46 25 LSR $25 ; halve hit % ⋮ 816430/9F84: D0 20 BNE $9FA6 ; branch if harp or bow + arrow ⋮ 816830/9F8C: 20 97 A3 JSR $A397 ; check for back row penalty 816930/9F8F: B0 15 BCS $9FA6 ; branch if no penalty ⋮ 817330/9F97: F0 02 BEQ $9F9B ; branch if attacker not in back row 817430/9F99: 46 25 LSR $25 ; halve hit % ⋮ 817730/9F9F: F0 05 BEQ $9FA6 ; branch if target is not in back row 817830/9FA1: EE E9 7C INC $7CE9 817930/9FA4: 46 25 LSR $25 ; halve hit % ⋮
ff3j.asm lines 8151–8210 at 1acef81 · 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.
- ^ abFinal Fantasy II rolls damage, attack plus 0 to attack less defense, and a critical for each hit that gets through and adds them up; Final Fantasy III rolls damage once, attack plus 0 to half of it, and multiplies it by the net hits, and its single critical roll uses the job's crit probability in place of Final Fantasy II's fixed roll under 5.Codeeverything8215, FF2 disassembly · everything8215, FF3 disassembly
How we know
18030; start of hit loop ⋮ 180350C/BCAF: 65 44 ADC $44 ; attack * (0..1) ⋮ 180610C/BCE2: C9 05 CMP #$05 180620C/BCE4: B0 11 BCS $BCF7 ; 5% chance for crit ⋮ 180720C/BCF7: 88 DEY ; next hit 180730C/BCF8: D0 AD BNE $BCA7
ff2j.asm lines 18030–18073 at 8d26190 · upstream ↗ 1198931/BB4A: 20 B4 BE JSR $BEB4 ; random (0..A) 1199031/BB4D: 18 CLC 1199131/BB4E: 65 25 ADC $25 1199231/BB50: 85 18 STA $18 ; +$18 = attack * (1..3/2)
ff3j.asm lines 11989–11992 at 1acef81 · upstream ↗ 1204231/BBB3: AD 7C 00 LDA $007C ; total no. of hits ⋮ 1204631/BBBD: 85 18 STA $18 ; +$18 = net damage
ff3j.asm lines 12042–12046 at 1acef81 · upstream ↗ 827931/A079: 20 B4 BE JSR $BEB4 ; random (0..A) 828031/A07C: CD 30 74 CMP $7430 ; crit probability
ff3j.asm lines 8278–8282 at 1acef81 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^A Fight command makes one percentage roll per point of the attacker's attack multiplier and counts the rolls under its hit rate; the target rolls once per point of its defense multiplier and blocks one hit for each roll under its defense rate. The hits left after blocking multiply one damage roll, and none left is a miss.Codeeverything8215, FF4 disassembly
How we know
16CalcHits: 17@c987: stz $38fd ; clear number of hits 18 lda $38fb 19 beq @c99e ; return if no base hits 20 tay 21@c990: jsr Rand99 22 cmp $38fa ; check vs. hit rate 23 bcs @c99b 24 inc $38fd ; increment number of hits 25@c99b: dey 26 bne @c990
battle/damage.asm lines 16–27 at a360e2e · upstream ↗ 114@c55b: lda $38f8 115 sta $38fa ; set attack rate 116 lda $269b ; attack multiplier 117 sta $38fb 118 jsr CalcHits 119 lda $38fd 120 sta $38f8 ; set number of hits
battle/fight.asm lines 114–120 at a360e2e · upstream ↗ 147@c59f: lda $2729 ; defense rate 148 sta $38f9 ⋮ 166 sta $38f9 ⋮ 169 lda $2728 ; defense multiplier 170 sta $38fb ⋮ 175@c5e4: jsr CalcHits 176 lda $38fd 177@c5ea: sta $38f9 ; set number of hits defended 178 sec 179 lda $38f8 180 sbc $38f9 ; subtract from number of hits 181 sta $34c8 ⋮
battle/fight.asm lines 147–203 at a360e2e · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^ abA character's attack multiplier, the number of hit rolls, is strength ÷ 8 + agility ÷ 16 + 1; the defense multiplier is agility ÷ 8 plus level ÷ 16 times the shield's multiplier.Codeeverything8215, FF4 disassembly
How we know
240; defense multiplier ⋮ 245 lda $396b ; shield multiplier ⋮ 248 lda $3967 ; agility / 8 249 jsr Lsr_3 250 clc 251 adc $e3 ; add level / 16 * shield multiplier 252 sta ($80),y ; set defense multiplier
battle/equip.asm lines 240–252 at a360e2e · upstream ↗ 546 lda $3966 ; strength / 8 547 jsr Lsr_3 548 sta $a9 549 lda $3967 ; agility / 16 550 jsr Lsr_4 551 clc 552 adc $a9 553 inc 554 ldy #$001b 555 sta ($80),y ; attack multiplier
battle/equip.asm lines 546–555 at a360e2e · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^ abFinal Fantasy IV keeps Final Fantasy III's physical attack: percentage rolls per point of an attack multiplier, the target's successful evade rolls subtracted, and one damage roll of attack plus 0 to half of it, with the crit bonus added before defense, multiplied by the net hits and capped at 9,999.Codeeverything8215, FF3 disassembly · everything8215, FF4 disassembly
How we know
1196331/BB30: A9 63 LDA #$63 1196431/BB32: 20 B4 BE JSR $BEB4 ; random (0..A) 1196531/BB35: C5 25 CMP $25 ; hit %
ff3j.asm lines 11959–11970 at 1acef81 · upstream ↗ 1199231/BB50: 85 18 STA $18 ; +$18 = attack * (1..3/2) ⋮ 1202131/BB89: 85 18 STA $18 ; +$18 = attack + crit bonus ⋮ 1203131/BB9D: E5 26 SBC $26 ; subtract defense ⋮ 1204231/BBB3: AD 7C 00 LDA $007C ; total no. of hits ⋮ 1206231/BBDD: A9 27 LDA #$27 ; max damage is 9999
ff3j.asm lines 11985–12062 at 1acef81 · upstream ↗ 21@c990: jsr Rand99 22 cmp $38fa ; check vs. hit rate
battle/damage.asm lines 16–27 at a360e2e · upstream ↗ 33CalcDmg: 34@c99f: ldx $3902 ; base attack ⋮ 59 adc $3901 ; add crit bonus ⋮ 66 sbc $3904 ⋮ 76 lda $38fc ⋮ 92 cpx #$270f
battle/damage.asm lines 33–99 at a360e2e · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^ abcdefgA multi-hit move runs the critical test, the damage formula, and the accuracy roll once; every later hit repeats the first hit's damage, and a first hit that misses ends the move.Codepret/pokered
How we know
3246 bit ATTACKING_MULTIPLE_TIMES, [hl] 3247 jr z, .executeOtherEffects 3248 ld a, [wPlayerNumAttacksLeft] 3249 dec a 3250 ld [wPlayerNumAttacksLeft], a 3251 jp nz, GetPlayerAnimationType ; for multi-hit moves, apply attack until PlayerNumAttacksLeft hits 0 or the enemy faints. 3252 ; damage calculation and accuracy tests only happen for the first hit
engine/battle/core.asm lines 3246–3253 at af51989 · upstream ↗ 1AlwaysHappenSideEffects: ⋮ 7 db TWO_TO_FIVE_ATTACKS_EFFECT
data/battle/always_happen_effects.asm lines 1–7 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.
- ^Twineedle hits twice because its branch stores the value of
POISON_SIDE_EFFECT1, which is 2, as the hit count, along with making it the move's effect.Codepret/pokeredHow we know
962.saveNumberOfHits 963 ld [de], a 964 ld [bc], a 965 ret 966.twineedle 967 ld a, POISON_SIDE_EFFECT1 968 ld [hl], a ; set Twineedle's effect to poison effect 969 jr .saveNumberOfHits
engine/battle/effects.asm lines 962–969 at af51989 · upstream ↗ 9 const POISON_SIDE_EFFECT1 ; $02constants/move_effect_constants.asm line 9 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.
- ^ abYellow keeps Red and Blue's
TwoToFiveAttacksEffect, 2 or 3 hits at 3/8 each and 4 or 5 at 1/8, and its damage loop, in which every hit after the first repeats it without a new damage calculation or accuracy test.Codepret/pokeyellow · pret/pokeredrevisedHow we know
987; for TWO_TO_FIVE_ATTACKS_EFFECT 3/8 chance for 2 and 3 hits, and 1/8 chance for 4 and 5 hits 988 call BattleRandom 989 and $3 ⋮ 993 call BattleRandom 994 and $3
engine/battle/effects.asm lines 987–997 at b6696f2 · upstream ↗ 3417 bit ATTACKING_MULTIPLE_TIMES, [hl] 3418 jr z, .executeOtherEffects 3419 ld a, [wPlayerNumAttacksLeft] 3420 dec a 3421 ld [wPlayerNumAttacksLeft], a 3422 jp nz, GetPlayerAnimationType ; for multi-hit moves, apply attack until PlayerNumAttacksLeft hits 0 or the enemy faints. 3423 ; damage calculation and accuracy tests only happen for the first hit
engine/battle/core.asm lines 3417–3423 at b6696f2 · upstream ↗ engine/battle/effects.asm#L925-L970 · upstream ↗ engine/battle/core.asm#L3246-L3253 · 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.
- ^ abGold and Silver's
BattleCommand_EndLoop, which Crystal keeps apart from a comment, loops back to the critical command for every hit of a 2–5-hit move, so each hit rolls its own critical and damage.Codepret/pokegold · pret/pokecrystalHow we know
5161BattleCommand_EndLoop:engine/battle/effect_commands.asm lines 5161–5292 at fc702b6 · upstream ↗ engine/battle/effect_commands.asm#L5203-L5335 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^ abRuby and Sapphire's
atk8D_setmultihitcountergives 2 or 3 hits with probability 3/8 each and 4 or 5 with 1/8 each, the same code as Emerald's; the multi-hit battle script runsaccuracycheckonce and then loopscritcalc,damagecalc, andadjustnormaldamagefor every hit.Codepret/pokeruby · pret/pokeemeraldrevisedHow we know
6701 else ⋮ 6703 gMultiHitCounter = Random() & 3; 6704 if (gMultiHitCounter > 1) 6705 gMultiHitCounter = (Random() & 3) + 2; 6706 else 6707 gMultiHitCounter += 2;
src/battle_script_commands.c lines 6697–6710 at 5784633 · upstream ↗ 652BattleScript_EffectMultiHit: @ 81D72ED ⋮ 654 accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE ⋮ 657 setmultihitcounter 0 ⋮ 661BattleScript_MultiHitLoop: @ 81D7300 ⋮ 670 critcalc 671 damagecalc ⋮ 674 adjustnormaldamage ⋮ 690 decrementmultihit BattleScript_MultiHitLoop
data/battle_scripts_1.s lines 652–690 at 5784633 · upstream ↗ 7139static void Cmd_setmultihitcounter(void)src/battle_script_commands.c lines 7139–7155 at 731ad5b · 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.
- ^ abFireRed and LeafGreen's
Cmd_setmultihitcounteris Emerald's, line for line: 2 or 3 hits at 3/8 each and 4 or 5 at 1/8. The battle script runsaccuracycheckonce, then loopscritcalc,damagecalc, andadjustnormaldamagefor every hit.Codepret/pokefirered · pret/pokeemeraldrevisedHow we know
6857static void Cmd_setmultihitcounter(void) ⋮ 6863 else ⋮ 6865 gMultiHitCounter = Random() & 3; 6866 if (gMultiHitCounter > 1) 6867 gMultiHitCounter = (Random() & 3) + 2; 6868 else 6869 gMultiHitCounter += 2;
src/battle_script_commands.c lines 6857–6873 at ce6406d · upstream ↗ 605BattleScript_EffectMultiHit:: ⋮ 607 accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE ⋮ 610 setmultihitcounter 0 ⋮ 613BattleScript_MultiHitLoop:: ⋮ 621 critcalc 622 damagecalc 623 typecalc 624 jumpifmovehadnoeffect BattleScript_MultiHitNoMoreHits 625 adjustnormaldamage ⋮ 640 decrementmultihit BattleScript_MultiHitLoop
data/battle_scripts_1.s lines 605–640 at ce6406d · upstream ↗ 7139static void Cmd_setmultihitcounter(void) ⋮ 7147 gMultiHitCounter = Random() & 3;
src/battle_script_commands.c lines 7139–7155 at 731ad5b · 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.
- ^ abEach swing rolls 0–200 with
RandAX; a roll of 200 always misses, and any other roll hits when it is at most the hit chance.CodeDisch, FF1 disassemblyHow we know
4474 LDX #200 4475 JSR RandAX ; [0,200] ⋮ 4480 JMP @NextHitIteration ; skip if got 200 exactly (guaranteed miss) ⋮ 4484 JSR RandAX ⋮ 4493 CMP math_randhit ; if hit chance is < randhit value, then this was a miss. Jump ahead
Final Fantasy Disassembly/bank_0C.asm lines 4471–4494 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.
- ^ abA 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.
- ^ abcEach swing that rolls under 200 also rolls damage from the base to , capped at 255; a hit subtracts the defender's absorb, with a minimum of 1, and the swings' damage adds up to one total.CodeDisch, FF1 disassembly
How we know
4312 LDA btl_attacker_strength ; base damage of attacker's strength valueFinal Fantasy Disassembly/bank_0C.asm lines 4312–4313 at cbb87d3 · upstream ↗ 3994 LDY #btlch_dmg ; IB damage 3995 LDA (btl_ib_charstat_ptr), Y 3996 STA btl_attacker_strength
Final Fantasy Disassembly/bank_0C.asm lines 3994–3996 at cbb87d3 · upstream ↗ 4482 : LDX $6BAD 4483 LDA #$00 4484 JSR RandAX 4485 CLC 4486 ADC $6BAD 4487 STA math_basedamage ; random between [basedmg, basedmg*2] ⋮ 4500 JSR MathBuf_Sub ; subtract defender's absorb ⋮ 4510 INC math_dmgcalc ⋮ 4520 JSR MathBuf_Add ⋮ 4526 JSR MathBuf_Add16 ; total damage += dmgcalc
Final Fantasy Disassembly/bank_0C.asm lines 4482–4526 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.
- ^Final Fantasy rolls once per swing against a single hit chance that already has the defender's evade subtracted; Final Fantasy II splits that into two sets of rolls, the attacker's against its hit % and the defender's against its evade %, and subtracts the defender's successes from the attacker's.CodeDisch, FF1 disassembly · everything8215, FF2 disassembly
How we know
4378 LDA #MATHBUF_HITCHANCE ; add their hit rate to their hit chance ⋮ 4388 LDX btl_defender_evade ; the hit chance.
Final Fantasy Disassembly/bank_0C.asm lines 4377–4399 at cbb87d3 · upstream ↗ 4474 LDX #200 4475 JSR RandAX ; [0,200] ⋮ 4484 JSR RandAX ⋮ 4493 CMP math_randhit ; if hit chance is < randhit value, then this was a miss. Jump ahead
Final Fantasy Disassembly/bank_0C.asm lines 4471–4494 at cbb87d3 · upstream ↗ 162600C/AFF9: 20 2C BC JSR $BC2C ; check for hit ⋮ 162660C/B006: B1 A1 LDA ($A1),Y ; target's evade multiplier ⋮ 162690C/B00B: B1 A1 LDA ($A1),Y ; target's evade % ⋮ 162790C/B020: 20 2C BC JSR $BC2C ; check for hit ⋮ 162850C/B02C: A5 52 LDA $52 ; subtract evaded hits
ff2j.asm lines 16260–16290 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.
- ^Final Fantasy IV counts a weapon attack's hits from a loop of percentage rolls, one per point of the attack multiplier, less the target's evade rolls; Final Fantasy V's physical check makes one hit roll and one evade roll, and the attack either lands or misses.Codeeverything8215, FF4 disassembly · everything8215, FF5 disassembly
How we know
16CalcHits: ⋮ 21@c990: jsr Rand99 22 cmp $38fa ; check vs. hit rate 23 bcs @c99b 24 inc $38fd ; increment number of hits 25@c99b: dey 26 bne @c990
battle/damage.asm lines 16–27 at a360e2e · upstream ↗ 19092.proc CheckPHit ⋮ 19095 jsr Random_0_99 19096 cmp HitPercent 19097 bcs Miss ⋮ 19106 jsr Random_0_99 19107 cmp EvadePercent ⋮ 19118Miss: 19119 inc AtkMissed
src/battle/battle-main.asm lines 19092–19122 at 997c87d · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^Final Fantasy (developer and publisher Square) came out for the Famicom in Japan on 18 December 1987.WikidataWikidata
How we know
+1987-12-18T00:00:00Z
Q1415970, P178 developer, P123 publisher, and P577 publication date qualified by P291 place and P400 platform · archived copy ↗ The quote matches our archived copy.
Checked by a second AI model, 2026-10-21.
- ^
PlyrCalcHitDmgtakes , the hero's attack power less half the monster's defense byte; if , damage is for a random byte , so from to .Codenmikstas/dragon-warrior-disassembly · Ryan8bit, DW FormulasHow we know
6719LE60C: LDA DisplayedAttck ; 6720LE60E: STA AttackStat ;Save a copy of the player's attack and enemy's defense. 6721LE610: LDA EnBaseDef ; 6722LE613: STA DefenseStat ;
source_files/Bank03.asm lines 6719–6722 at ebe6a13 · upstream ↗ 8492LEFE5: LSR DefenseStat ; 8493LEFE7: LDA AttackStat ; 8494LEFE9: SEC ; A = AttackStat - DefenseStat/2. 8495LEFEA: SBC DefenseStat ; 8496LEFEC: BCC PlyrWeakAttack ;
source_files/Bank03.asm lines 8491–8500 at ebe6a13 · upstream ↗ 8543LF032: STA MultNum2LB ;A = A+1. 8544LF034: INC MultNum2LB ; ⋮ 8554LF046: LDA MultRsltUB ;A = (A/256 + BaseAttack) / 4. 8555LF048: CLC ; 8556LF049: ADC BaseAttack ; 8557LF04B: ROR ;Total equation for normal attack damage:
source_files/Bank03.asm lines 8541–8560 at ebe6a13 · upstream ↗ (HeroAttack - EnemyAgility / 2) / 4,
II.B, Hero attack formulas · archived copy ↗ Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^After the damage is set, an awake monster dodges when a roll of 0–63 falls below , the low nibble of its resistance byte, a chance of ; a sleeping monster never dodges, and spells skip the check.Codenmikstas/dragon-warrior-disassembly · Ryan8bit, DW Formulas
How we know
6780LE66A: BIT PlayerFlags ;Is the enemy asleep? 6781LE66C: BVS PlyrHitEn ;If so, branch. Enemy can't dodge. ⋮ 6786LE673: AND #$3F ;Get a random number and keep lower 6 bits(0-63). ⋮ 6789LE677: LDA EnBaseMDef ;Does enemy have magic defense? 6790LE67A: AND #$0F ; 6791LE67C: BEQ PlyrHitEn ;If not, branch. Enemy can't dodge. ⋮ 6795LE681: CMP RandNumUB ;
source_files/Bank03.asm lines 6775–6796 at ebe6a13 · upstream ↗ 6809SetSpellDmg: 6810LE694: STA EnDamage ; 6811LE696: LDA #$00 ;Set the damage the player will do. Enemy can't dodge spells. ⋮ 6814PlyrHitEn:
source_files/Bank03.asm lines 6809–6814 at ebe6a13 · upstream ↗ The second nibble / 64 is the chance of dodging
III.C, Combat · archived copy ↗ Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
Sources
Code
- 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
- pret contributors. 2026. “pokecrystal: disassembly of Pokémon Crystal.” pret. Commit 97187cd. pret/pokecrystal @ 97187cd · licence, all uses
- pret contributors. 2026. “pokeemerald: decompilation of Pokémon Emerald.” pret. Commit 731ad5b. pret/pokeemerald @ 731ad5b · licence, all uses
- 1990. “Final Fantasy (USA).” · licence, all uses
- everything8215. 2022. “Final Fantasy II (NES) disassembly and ROM info.” Commit 8d26190. everything8215/ff2 @ 8d26190 · licence, all uses
- everything8215. 2022. “Final Fantasy III (NES) disassembly and ROM info.” Commit 1acef81. everything8215/ff3 @ 1acef81 · licence, all uses
- everything8215. 2022. “Final Fantasy IV Disassembly.” Commit a360e2e. everything8215/ff4 @ a360e2e · licence, all uses
- everything8215. 2026. “Final Fantasy V Disassembly.” Commit 997c87d. everything8215/ff5 @ 997c87d · licence, all uses
- pret contributors. 2026. “pokeyellow: disassembly of Pokémon Yellow.” pret. Commit b6696f2. pret/pokeyellow @ b6696f2 · licence, all uses
- pret contributors. 2026. “pokegold: disassembly of Pokémon Gold and Silver.” pret. Commit fc702b6. pret/pokegold @ fc702b6 · licence, all uses
- pret contributors. 2026. “pokeruby: decompilation of Pokémon Ruby and Sapphire.” pret. Commit 5784633. pret/pokeruby @ 5784633 · licence, all uses
- pret contributors. 2026. “pokefirered: decompilation of Pokémon FireRed and LeafGreen.” pret. Commit ce6406d. pret/pokefirered @ ce6406d · licence, all uses
- nmikstas. 2023. “dragon-warrior-disassembly: NES Dragon Warrior software disassembly.” Commit ebe6a13. nmikstas/dragon-warrior-disassembly @ ebe6a13 · licence, all uses
Secondary
- Wikidata contributors. 2026. “Wikidata.” Wikimedia Foundation. original · licence, all uses
- Ryan8bit. 2011. “Dragon Warrior (NES) Formulas.” GameFAQs. v1.0. original · archived · licence, all uses