Knockback
A push away from whatever hit the character.
Knockback pushes a character away from whatever hit it. The Legend of Zelda moves Link a fixed distance at a fixed speed1,2. Metroid gives Samus a speed that fades as her blink runs down3. In both, the hit that pushes also starts the invincibility window1,4.
Super Smash Bros. grows the knockback with the target’s damage percent and the hit’s damage, where Zelda’s shove is a fixed distance5,1. In its NTSC 1.02 version, Super Smash Bros. Melee keeps the terms in the same places but reads their constants from a disc file, and its weight term divides where Super Smash Bros.’s multiplies6.
- LaunchCastlevania II: Simon's Quest (1987). A hit throws Simon up and back, falling like a jump.7Zelda II: The Adventure of Link (1987). A body hit sets a sideways speed and a small hop.8Super Mario Bros. 2 (1988). A hit that leaves two marks or more launches the player up and away.9Castlevania III: Dracula's Curse (1989). A hit throws the character up and sideways in an arc.10Sonic the Hedgehog (1991). A hit throws him up and back, under lighter gravity.11Sonic the Hedgehog 2 (1992). A hit throws him up and back, under lighter gravity.12Sonic 3 & Knuckles (1994). A hit throws him up and back at the speeds of the first two games.13
- Fading pushMetroid (1986). A push that fades with the blink.4,3,14
- Fixed shoveThe Legend of Zelda (1986). A fixed 32 px shove at 4 px per frame.2,15,16,17,18Mega Man (1987). A hit pushes him up and back until its animation ends.19,20Mega Man 2 (1988). A hit pops him up and pushes him back until its animation ends.21,20Mega Man 3 (1990). A hit pushes him slowly back until the hurt animation ends.22Mega Man 4 (1991). A hit pushes him slowly back until the hurt animation ends.23The Legend of Zelda: A Link to the Past (1991). A speed of 24 away from the monster and a hop, at least 19 frames without control.24Mega Man 5 (1992). A hit pushes him back, and holding the way he faces halves the push.25The Legend of Zelda: Link's Awakening (1993). 16 frames; in DX at a set speed away from the monster, with no steering.26
- Table arcCastlevania (1986). A hit throws Simon up and back in a short, fixed hop.27
- Percent-scaledSuper Smash Bros. (1999). The launch grows with the target's percent and the hit's damage, scaled by the target's weight and the move's growth and base, capped at 2500.5,28Super Smash Bros. Melee (2001). Super Smash Bros.'s formula with its constants moved to a data file, and the weight dividing the launch rather than multiplying it.6
#How it works
A distance-based push spends a budget of pixels:
on a hit: dir = away from the attacker; left = D
every frame: move up to S px in dir, 1 px at a time; left -= 1 per px
stop when left = 0 or the next pixel is blocked
A speed-based push sets a velocity each frame and lets the movement code apply it:
on a hit: dir = away from the attacker; timer = T
every frame: speed = f(timer) toward dir; timer -= 1
The first fixes the distance unless a wall cuts it short. The second fixes the duration, and the distance depends on what else moves the character.
#Implementations
#The Legend of Zelda (1986)
A hit gives Link a shove of 32 px1. The shove moves him 4 px/frame2, one pixel of distance at a time, and ends early at the room’s edge or at an unwalkable tile2. It points away from the monster along one axis16. While it lasts, it replaces Link’s walking, so the player can’t steer15. Measured in the ROM, a shove covers 32 px in 8 frames17, and one that starts 8 px from the room’s edge covers 8 px17.
Link’s weapons shove monsters the same way, 64 px in the weapon’s direction18. After hitting Link, most monsters turn around16.
#Metroid (1986)
A hit gives Samus an upward speed and a push direction away from the enemy4. On each frame of the blink, the game sets her horizontal speed to the blink counter divided by 16. The push fades as the counter runs down and ends when it falls below 163. Once the counter is below 48, any frame on which Samus accelerates sideways skips the push, so the player can steer out of it3. Measured in the ROM with no input, the push carried Samus 37–45 px14,14. Lava blinks Samus with no push29.
#Mega Man 3 to 5
Mega Man 3 pushes Mega Man against his facing at 0.5 px/frame back22 under gravity until the hurt animation’s state reaches 9, and a hit during a slide doesn’t push him22. The push lasts as long as the animation takes to get there, where Zelda’s shove spends a budget of pixels22,2. Mega Man 4 keeps that knockback23. Mega Man 5 lets the player resist it: holding the direction Mega Man faces drops the push to 0.25 px/frame25.
#Castlevania II and III
Castlevania II: Simon’s Quest replaces Castlevania’s table arc with a launch7. Simon moves away at 2.5 px/frame up and 1 px/frame back, held for 32 frames in a hurt state that runs the jump’s speed and gravity code7. Castlevania III: Dracula’s Curse launches the character at 2 px/frame up and 1 px/frame sideways, under 0.125 px/frame² of gravity up to a 5 px/frame fall10. When the byte at $90 is nonzero, the character faces left and is pushed right; otherwise it faces right and is pushed left10. What $90 records hasn’t been traced10.
#Sonic 2 and Sonic 3 & Knuckles
A hit in Sonic the Hedgehog 2 throws Sonic 4 px/frame up, 2 px/frame back12, half both underwater, under a hurt gravity of $30. Sonic 3 & Knuckles keeps those speeds from Sonic 1 and Sonic 213.
#Compared
| The Legend of Zelda | Metroid | |
|---|---|---|
| Kind | distance: 32 px1 | speed from the blink counter3 |
| Rate | 4 px a frame2 | fades with the counter3 |
| Player control | none until it ends15 | input overrides it after the first frames3 |
| Measured | 32 px in 8 frames17 | 37–45 px14 |
| Direction | away from the monster, along one axis16 | away from the enemy, with an upward speed4 |
Games
| Game | Year | How | Note |
|---|---|---|---|
| Castlevania II: Simon's Quest | 1987 | Launch | a hit throws Simon up and back, falling like a jump |
| Zelda II: The Adventure of Link | 1987 | Launch | a body hit sets a sideways speed and a small hop |
| Super Mario Bros. 2 | 1988 | Launch | a hit that leaves two marks or more launches the player up and away |
| Castlevania III: Dracula's Curse | 1989 | Launch | a hit throws the character up and sideways in an arc |
| Sonic the Hedgehog | 1991 | Launch | a hit throws him up and back, under lighter gravity |
| Sonic the Hedgehog 2 | 1992 | Launch | a hit throws him up and back, under lighter gravity |
| Sonic 3 & Knuckles | 1994 | Launch | a hit throws him up and back at the speeds of the first two games |
| Super Metroid | 1994 | Launch | 5 px/frame up, then the usual gravity |
| Metroid | 1986 | Fading push | a push that fades with the blink |
| The Legend of Zelda | 1986 | Fixed shove | a fixed 32 px shove at 4 px per frame |
| Mega Man | 1987 | Fixed shove | a hit pushes him up and back until its animation ends |
| Mega Man 2 | 1988 | Fixed shove | a hit pops him up and pushes him back until its animation ends |
| Mega Man 3 | 1990 | Fixed shove | a hit pushes him slowly back until the hurt animation ends |
| Mega Man 4 | 1991 | Fixed shove | a hit pushes him slowly back until the hurt animation ends |
| The Legend of Zelda: A Link to the Past | 1991 | Fixed shove | a speed of 24 away from the monster and a hop, at least 19 frames without control |
| Mega Man 5 | 1992 | Fixed shove | a hit pushes him back, and holding the way he faces halves the push |
| Mega Man 6 | 1993 | Fixed shove | Mega Man 5's push, halved by holding the way he faces |
| The Legend of Zelda: Link's Awakening | 1993 | Fixed shove | 16 frames; in DX at a set speed away from the monster, with no steering |
| The Legend of Zelda: Oracle of Seasons and Oracle of Ages | 2001 | Fixed shove | 15 frames at 1.25 pixels a frame for a standard enemy, halved by the Steadfast Ring, with no steering |
| The Legend of Zelda: The Minish Cap | 2004 | Fixed shove | a set speed for as long as the collision matrix says, with no steering |
| Castlevania | 1986 | Table arc | a hit throws Simon up and back in a short, fixed hop |
| Metroid II: Return of Samus | 1991 | Table arc | a fixed arc from its own table, 3 px/frame up and 1 sideways, which a jump press cancels |
| Super Smash Bros. | 1999 | Percent-scaled | the launch grows with the target's percent and the hit's damage, scaled by the target's weight and the move's growth and base, capped at 2500 |
| Super Smash Bros. Melee | 2001 | Percent-scaled | Super Smash Bros.'s formula with its constants moved to a data file, and the weight dividing the launch rather than multiplying it |
Every claim about this mechanic, by game (34)
References
- ^ abcdeA monster that touches Link while his invincibility timer is above 0 does nothing; a hit sets the timer to 24 and his shove distance to 32 px.Codealdonunez/zelda1-disassembly · “Legend of Zelda, The (USA) (Rev 1)”
How we know
5610 ; If Link is invincible, or we have the magic clock, 5611 ; or Link is stunned, or the monster is stunned; 5612 ; then return no collision. 5613 LDA ObjInvincibilityTimer 5614 ORA InvClock 5615 ORA ObjStunTimer 5616 ORA ObjStunTimer, X 5617 BNE L73A9_Exit
src/Z_01.asm lines 5610–5617 at 50a1c86 · upstream ↗ 6589 ; If Link is invincible, return without shoving. 6590 LDA ObjInvincibilityTimer 6591 BNE @Exit ⋮ 6601 ; Mark Link invincible $18 frames, and should move $20 pixels. 6602 LDA #$18 6603 STA ObjInvincibilityTimer 6604 LDA #$20 6605 STA ObjShoveDistance
src/Z_01.asm lines 6589–6605 at 50a1c86 · upstream ↗ In the cartridge (“Legend of Zelda, The (USA) (Rev 1)”): bank 1 BeginShove, run from RAM at $7E26. We don't reproduce the bytes.
Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^ abcdefA shoved object moves 4 px a frame, 1 px of shove distance at a time, and the shove ends early when the object reaches the room's edge or, aligned to the grid, an unwalkable tile.Codealdonunez/zelda1-disassembly · “Legend of Zelda, The (USA) (Rev 1)”
How we know
2397ShoveMoveMin: 2398 ; Try to move 4 pixels. [03] is the counter. 2399 LDA #$04 2400 STA $03 ⋮ 2411 JSR GetCollidingTileMoving 2412 CMP ObjectFirstUnwalkableTile 2413 BCS ResetShoveInfo ⋮ 2416 ; Regardless of the grid offset, if the object runs into the 2417 ; bounds of the room, then stop shoving.
src/Z_07.asm lines 2397–2420 at 50a1c86 · upstream ↗ 2450 ; We're OK to change the position. So, decrease the distance 2451 ; that's left to move. 2452 DEC ObjShoveDistance, X
src/Z_07.asm lines 2450–2452 at 50a1c86 · upstream ↗ In the cartridge (“Legend of Zelda, The (USA) (Rev 1)”): bank 7 Obj_Shove and ShoveMoveMin, $EEB8. We don't reproduce the bytes.
Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^ abcdefgOn each frame of the blink,
CheckHealthStatussets Samus's horizontal speed in the push direction to the blink counter divided by 16, so the push ends when the counter falls below 16; below 48, it skips the push on any frame Samus has horizontal acceleration.Codenmikstas/metroid-disassembly · “Metroid (USA)”How we know
2451 ldx DmgPushDir 2452 inx 2453 beq +++ 2454 jsr Adiv16 ; / 16 2455 cmp #$03 2456 bcs + 2457 ldy SamusHorzAccel 2458 bne +++ 2459 jsr LCF4E 2460* dex 2461 bne + 2462 jsr TwosCompliment ;($C3D4) ⋮
Source_Files/Bank07.asm lines 2451–2463 at 4270d57 · upstream ↗ 165.alias DmgPushDir $72 ;#$00=Push Samus left when hit, #$01=Push right, #$FF=No push.Source_Files/Metroid_Defines.asm line 165 at 4270d57 · upstream ↗ In the cartridge (“Metroid (USA)”): bank 7 CheckHealthStatus. We don't reproduce the bytes.
Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^ abcdA hit sets
SamusBlinkto$32, which is 50, gives Samus an upward speed of$FDwith the hit gravity$38, and takes the push direction from the hit; the comment says "Set blink for 32 frames".Codenmikstas/metroid-disassembly · “Metroid (USA)”How we know
2421CheckHealthStatus: 2422LCDFA: lda SamusHit ; 2423 and #$20 ;Has Samus been hit? 2424 beq +++ ;If not, branch to check if still blinking from recent hit. 2425 lda #$32 ; 2426 sta SamusBlink ;Samus has been hit. Set blink for 32 frames. ⋮ 2428 sta DmgPushDir ⋮ 2431 beq ++ ⋮ 2434* lda SamusHit 2435 and #$08 2436 lsr 2437 lsr ⋮
Source_Files/Bank07.asm lines 2421–2443 at 4270d57 · upstream ↗ In the cartridge (“Metroid (USA)”): bank 7 CheckHealthStatus, $CDFA. We don't reproduce the bytes.
Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^ abIn the US version of Super Smash Bros.,
ftParamGetCommonKnockbackcomputes a hit's knockback as times an attacker and a defender factor from a handicap table. Here d is the target's damage percent plusdamage_queue, the damage queued against it, whichftMainProcParamsadds to the percent and then clears; h is the hit's damage; w is the target'sweightattribute, which the decompilers comment "Or, rather, \"knockback multiplier\""; g and b are the hit'sknockback_scaleandknockback_base; and r is the battle'sdamage_ratio. A hit with a nonzeroknockback_weightk puts 1 + 0.5k in place of the d term, the value that term takes at d = 10 and h = k (computed), so that launch doesn't grow with the percent. The result is capped at 2500. Of the hits a fighter takes together,ftMainProcessHitCollisionStatsMainkeeps the largest knockback, andftMainProcParamsmultiplies it by 2/3 while the fighter is crouching (nFTCommonStatusSquatornFTCommonStatusSquatWait) and subtracts the larger of two knockback-resistance values, down to 0.CodeVetriTheRetri/ssb-decomp-reHow we know
1451f32 ftParamGetCommonKnockback(s32 percent_damage, s32 recent_damage, s32 hit_damage, s32 knockback_weight, s32 knockback_scale, s32 knockback_base, f32 weight, s32 attack_handicap, s32 defend_handicap) ⋮ 1455 if (knockback_weight != 0) ⋮ 1457 knockback = ( ( ( ( ( ( 1 + ( 10.0F * knockback_weight * 0.05F ) ) * weight * 1.4F ) + 18.0F ) * ( knockback_scale * 0.01F ) ) + knockback_base ) * ( gSCManagerBattleState->damage_ratio * 0.01F ) * dFTCommonDataHandicapTable[attack_handicap - 1][0] ) * dFTCommonDataHandicapTable[defend_handicap - 1][1]; ⋮ 1459 else ⋮ 1461 f32 damage_add = percent_damage + recent_damage; ⋮ 1463 knockback = ( ( ( ( ( ( ( damage_add * 0.1F ) + ( damage_add * hit_damage * 0.05F ) ) * weight * 1.4F ) + 18.0F ) * ( knockback_scale * 0.01F ) ) + knockback_base ) * ( gSCManagerBattleState->damage_ratio * 0.01F ) * dFTCommonDataHandicapTable[attack_handicap - 1][0] ) * dFTCommonDataHandicapTable[defend_handicap - 1][1]; ⋮ 1465 if (knockback >= 2500.0F) ⋮ 1467 knockback = 2500.0F;
src/ft/ftparam.c lines 1451–1468 at 572a747 · upstream ↗ 2699 knockback_temp = ftParamGetCommonKnockback ⋮ 2701 this_fp->percent_damage, 2702 this_fp->damage_queue, ft_attack_coll->damage, 2703 ft_attack_coll->knockback_weight, 2704 ft_attack_coll->knockback_scale, 2705 ft_attack_coll->knockback_base, 2706 attr->weight, 2707 attacker_fp->handicap, 2708 this_fp->handicap
src/ft/ftmain.c lines 2699–2709 at 572a747 · upstream ↗ 2672 FTAttributes *attr = this_fp->attr;src/ft/ftmain.c line 2672 at 572a747 · upstream ↗ 898 f32 weight; // Or, rather, "knockback multiplier"src/ft/fttypes.h line 898 at 572a747 · upstream ↗ 2845 if (knockback < knockback_temp) ⋮ 2847 knockback = knockback_temp;
src/ft/ftmain.c lines 2845–2847 at 572a747 · upstream ↗ 2990 this_fp->damage_knockback = knockback;src/ft/ftmain.c line 2990 at 572a747 · upstream ↗ 3856 if (fp->damage_knockback != 0.0F) ⋮ 3858 if ((fp->status_id == nFTCommonStatusSquat) || (fp->status_id == nFTCommonStatusSquatWait)) ⋮ 3860 fp->damage_knockback *= (2.0F / 3.0F); ⋮ 3866 if (fp->knockback_resist_status < fp->knockback_resist_passive) ⋮ 3868 knockback_resist = fp->knockback_resist_passive; ⋮ 3870 else knockback_resist = fp->knockback_resist_status; ⋮ 3872 fp->damage_knockback -= knockback_resist; ⋮ 3874 if (fp->damage_knockback <= 0) ⋮ 3876 fp->damage_knockback = 0; ⋮ 3878 ftParamUpdateDamage(fp, fp->damage_queue);
src/ft/ftmain.c lines 3856–3878 at 572a747 · upstream ↗ 3816void ftMainProcParams(GObj *fighter_gobj)src/ft/ftmain.c line 3816 at 572a747 · upstream ↗ 4007 fp->damage_queue = 0;src/ft/ftmain.c line 4007 at 572a747 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^ abIn the NTSC 1.02 version of Super Smash Bros. Melee,
ftColl_80079AB0computes a hit's knockback as capped at c_108. Every c is an unnamed field ofp_ftCommonData, whichFighter_LoadCommonDataloads from the disc file PlCo.dat, so the constants aren't in the code. Here d is the target'sx1830_percentplusx1838_percentTemp, or, while the unnamed flagx2225_b7is set, c_6D4 (c_6D8 ifstamina_dead) plusx1838_percentTemp; n is the hit capsule'sunk_count; w is the target'sweightattribute times c_F4; g and b are the capsule's unnamedx24andx2C; r isgm_8016B248(), the match rules'x30, which the VS setup in gm_1601.c sets to 0.1 × the rules'damage_ratio; and A and D arePlayer_GetAttackRatiofor the attacker andPlayer_GetDefenseRatiofor the target. A capsule whose unnamedx28(k) isn't 0 uses c_118·c_110 + c_114·c_118·k in place of the percent term. The terms sit where Super Smash Bros.'s 0.1, 0.05, 1.4, 18, and its set-knockback 10 and cap 2500 do (ssb64/knockback), and the atlas reads g as the growth and b as the base by that position. Where Super Smash Bros. multiplies by its weight attribute, Melee's weight term equals c_F8 / (1 + w) (computed), so the weight divides. Of the hits a fighter logs in one update,ftColl_8007A06Ckeeps the largest knockback and writes it tokb_applied;ftCo_Damage_CalcKnockbackthen multiplies it bykb_squat_mulinftCo_MS_SquatorftCo_MS_SquatWait, bykb_ice_mulinftCo_MS_DamageIce, and bykb_smashcharge_mulwhile a smash attack charges, rescales it withftCo_CalcYScaledKnockbackwhen the fighter's vertical scale isn't 1, subtracts the larger ofarmor0andarmor1(plusmetal_armorfor a metal fighter), and raises it tokb_minif it falls below.Codedoldecomp/melee · VetriTheRetri/ssb-decomp-reHow we know
2061static inline s32 ftColl_GetDamageCount(Fighter* fp, ftCommonData* ftd) ⋮ 2063 if (fp->x2225_b7) { 2064 if (fp->stamina_dead) { 2065 return ftd->x6D8; ⋮ 2067 return ftd->x6D4; ⋮ 2069 return (s32) fp->dmg.x1830_percent;
src/melee/ft/ftcoll.c lines 2061–2069 at f0cdbb0 · upstream ↗ 2075#define KNOCKBACK(defense, attack, arg3, one, ftd, hit, w, inner) \ 2076 ((defense) * \ 2077 ((attack) * \ 2078 ((arg3) * ((0.01F * (hit)->x24 * \ 2079 ((ftd)->x11C * \ 2080 (((ftd)->xF8 - (((w) * (ftd)->xF8) / ((one) + (w)))) * \ 2081 (inner)) + \ 2082 (ftd)->x120)) + \ 2083 (hit)->x2C)))) ⋮ 2091 float w = weight; 2092 w *= ftd->xF4; ⋮ 2094 if (hit->x28 != 0) { ⋮
src/melee/ft/ftcoll.c lines 2075–2118 at f0cdbb0 · upstream ↗ 2120float ftColl_80079C70(Fighter* fp, Fighter* attacker, HitCapsule* hit, 2121 int unk_count) ⋮ 2123 ftCo_DatAttrs* co = &fp->co_attrs; 2124 return ftColl_80079AB0(fp, hit, unk_count, gm_8016B248(), 2125 Player_GetAttackRatio(attacker->player_idx), 2126 Player_GetDefenseRatio(fp->player_idx), co->weight);
src/melee/ft/ftcoll.c lines 2120–2126 at f0cdbb0 · upstream ↗ 37 /* +8 */ u32 unk_count; ⋮ 42 /* +24 */ u32 x24; 43 /* +28 */ u32 x28; 44 /* +2C */ u32 x2C;
src/melee/lb/types.h lines 37–44 at f0cdbb0 · upstream ↗ 918 /* +088 fp+198 */ float weight;src/melee/ft/types.h line 918 at f0cdbb0 · upstream ↗ 182 lbArchive_LoadSymbols("PlCo.dat", &data, "ftLoadCommonData", 0); ⋮ 188 p_ftCommonData = data->common; // p_ftCommonData
src/melee/ft/fighter.c lines 182–189 at f0cdbb0 · upstream ↗ 263f32 gm_8016B248(void) ⋮ 265 return gm_GetStartMeleeRules()->x30;
src/melee/gm/gmvs.c lines 263–266 at f0cdbb0 · upstream ↗ 3810 vs_data->start.rules.x30 = 0.1f * rules->damage_ratio;src/melee/gm/gm_1601.c line 3810 at f0cdbb0 · upstream ↗ 2253 kb = ftColl_80079C70(fp, attacker_fp, hit, unk_count);src/melee/ft/ftcoll.c line 2253 at f0cdbb0 · upstream ↗ 2298 if (kb > best_kb.v) { ⋮ 2306 best_kb.v = kb; 2307 best_idx = i;
src/melee/ft/ftcoll.c lines 2298–2307 at f0cdbb0 · upstream ↗ 2194struct DmgResult { 2195 /* 0x00 */ float dir; 2196 /* 0x04 */ int angle; 2197 /* 0x08 */ int hurt_height; 2198 /* 0x0C */ float kb;
src/melee/ft/ftcoll.c lines 2194–2198 at f0cdbb0 · upstream ↗ 2389 out->kb = best_kb.v;src/melee/ft/ftcoll.c line 2389 at f0cdbb0 · upstream ↗ 2452 ftColl_8007A06C(gobj, &fp->dmg.facing_dir_1, dmg_log0, dmg_log0_idx, 1);src/melee/ft/ftcoll.c line 2452 at f0cdbb0 · upstream ↗ 1660 /* fp+1844 */ float facing_dir_1; 1661 /* fp+1848 */ int x1848_kb_angle; 1662 /* fp+184C */ int x184c_damaged_hurtbox; 1663 /* fp+1850 */ float kb_applied;
src/melee/ft/types.h lines 1660–1663 at f0cdbb0 · upstream ↗ 2852 forceAppliedOnHit = fp->dmg.kb_applied; ⋮ 2859 ftCo_Damage_CalcKnockback(fp);
src/melee/ft/fighter.c lines 2852–2859 at f0cdbb0 · upstream ↗ 118void ftCo_Damage_CalcKnockback(Fighter* fp) ⋮ 120 if (!fp->dmg.kb_applied) { 121 return; ⋮ 123 if (fp->motion_id == ftCo_MS_Squat || fp->motion_id == ftCo_MS_SquatWait) { 124 fp->dmg.kb_applied *= p_ftCommonData->kb_squat_mul; ⋮ 126 if (fp->motion_id == ftCo_MS_DamageIce) { 127 fp->dmg.kb_applied *= p_ftCommonData->kb_ice_mul; ⋮ 129 if (fp->smash_attrs.state == SmashState_Charging) { 130 fp->dmg.kb_applied *= p_ftCommonData->kb_smashcharge_mul; ⋮ 132 if (fp->x34_scale.y != 1) { 133 fp->dmg.kb_applied = ftCo_CalcYScaledKnockback( 134 fp->dmg.kb_applied, fp->x34_scale.y, Fighter_804D6524->x0); ⋮
src/melee/ft/kinds/ftCommon/ftCo_Damage.c lines 118–146 at f0cdbb0 · upstream ↗ 1451f32 ftParamGetCommonKnockback(s32 percent_damage, s32 recent_damage, s32 hit_damage, s32 knockback_weight, s32 knockback_scale, s32 knockback_base, f32 weight, s32 attack_handicap, s32 defend_handicap) ⋮ 1457 knockback = ( ( ( ( ( ( 1 + ( 10.0F * knockback_weight * 0.05F ) ) * weight * 1.4F ) + 18.0F ) * ( knockback_scale * 0.01F ) ) + knockback_base ) * ( gSCManagerBattleState->damage_ratio * 0.01F ) * dFTCommonDataHandicapTable[attack_handicap - 1][0] ) * dFTCommonDataHandicapTable[defend_handicap - 1][1]; ⋮ 1463 knockback = ( ( ( ( ( ( ( damage_add * 0.1F ) + ( damage_add * hit_damage * 0.05F ) ) * weight * 1.4F ) + 18.0F ) * ( knockback_scale * 0.01F ) ) + knockback_base ) * ( gSCManagerBattleState->damage_ratio * 0.01F ) * dFTCommonDataHandicapTable[attack_handicap - 1][0] ) * dFTCommonDataHandicapTable[defend_handicap - 1][1]; ⋮ 1465 if (knockback >= 2500.0F) ⋮ 1467 knockback = 2500.0F;
src/ft/ftparam.c lines 1451–1468 at 572a747 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^ abcSimon's Quest turns an enemy's touch into a launch, not Castlevania's table arc; as in Castlevania, Simon is turned to face the enemy and moved away from it, here at 2.5 px/frame up and 1 px/frame back, held in a hurt state for 32 frames that runs the jump's speed and gravity code before he falls normally.Code“Castlevania II - Simon's Quest (USA)” · “Castlevania (USA) (Rev 1)”revised
How we know
In the cartridge (“Castlevania II - Simon's Quest (USA)”): bank 1 $8844-$8854, after the hit's damage: facing $0420 = 1 if the enemy's X is at or right of Simon's, else 0; then jump to $D36F; bank 7 $D36F-$D3A7: X speed −1.0 if $0420 is nonzero, else +1.0; Y speed −2.5 ($FD.$80); action 6; a 32-frame counter $04B0 = $20; bank 3 $8A0E-$8A21, action 6: count down $04B0, running the jumping physics at $89D6, then action 2. We don't reproduce the bytes.
In the cartridge (“Castlevania (USA) (Rev 1)”): Castlevania's hit, which points Simon's arc at a second table (castlevania-line/knockback). We don't reproduce the bytes.
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.
- ^A monster's body hit sets Link's horizontal speed from a table,
$0Dor$F3(−13) by the comments for facing left or right, and his vertical speed to$FE(−2), a hop away.CodeFiendsOfTheElements/z2disassemblyHow we know
0D = X Velocity when Link is hit - Facing left … F3 = X Velocity when Link is hit - Facing right … This applies to being hit by the enemy itself, but not its weapon
src/prg7.asm#L5491-L5497 · upstream ↗ 5543 LDA LE36C,y ; 0x1e3c3 $E3B3 B9 6C E3 ; 5544 STA $70 ; 0x1e3c6 $E3B6 85 70 ; Link's X Velocity
src/prg7.asm lines 5525–5545 at c4c3a4c · upstream ↗ 5469 LDA #$FE ; 0x1e371 $E361 A9 FE ; A = FE 5470 STA $057D ; 0x1e373 $E363 8D 7D 05 ; Link's Y Velocity when hit
src/prg7.asm lines 5469–5470 at c4c3a4c · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^Health is
$0Ffor one mark of the life meter and$10more for each further mark, up to$3Ffor four. A hit takes$10, one mark, and setsDamageInvulnTimeto$7F, during whichDamagePlayerreturns at once; the timer drops every frame. If the health left is$10or more, two marks or more, the hit also launches the player upward at$C0and sideways at four times the screen distance from the enemy. A hit on the last mark (health under$10) stores no health and sets no invulnerability: it turns the enemy toward the player (for the types beforeEnemy_BeezoDiving), stuns it for$10frames, sets the player's vertical speed to$C0andPlayerStateTimerto$20, and jumps toKillPlayer, which sets the dying state and health to 0. A dying player holds still for those 32 frames, then rises at$C0and falls back, gaining$02a frame up to$39, and loses a life once below the screen.CodeSMB2 DiscombobulatedrevisedHow we know
11362DamagePlayer: 11363 LDA DamageInvulnTime 11364 BNE locret_BANK3_BA31 ⋮ 11366 LDA PlayerHealth 11367 SEC 11368 SBC #$10 11369 BCC loc_BANK3_BA32 ⋮ 11371 STA PlayerHealth 11372 LDY #$7F 11373 STY DamageInvulnTime 11374 LDY #$00 11375 STY PlayerYVelocity ⋮
src/prg-2-3.asm lines 11362–11388 at b73415e · upstream ↗ 3171 ; Decrement player state timers 3172 LDX #$03 3173DecrementPlayerStateTimers_Loop: 3174 LDA PlayerStateTimer, X ⋮ 3177 DEC PlayerStateTimer, X
src/prg-e-f.asm lines 3171–3177 at b73415e · upstream ↗ 291PlayerStateTimer: ⋮ 297DamageInvulnTime:
src/ram.asm lines 291–298 at b73415e · upstream ↗ 11404loc_BANK3_BA32: 11405 TXA ⋮ 11407loc_BANK3_BA33: 11408 PHA 11409 LDX byte_RAM_12 11410 LDA ObjectType, X 11411 CMP #Enemy_BeezoDiving 11412 BCS loc_BANK3_BA48 ⋮ 11414 JSR EnemyFindWhichSidePlayerIsOn ⋮ 11416 INY 11417 TYA 11418 CMP EnemyMovementDirection, X ⋮
src/prg-2-3.asm lines 11404–11439 at b73415e · upstream ↗ 5154KillPlayer: 5155 LDA #PlayerState_Dying ; Mark player as dead 5156 STA PlayerState 5157 LDA #$00 ; Clear some variables 5158IFNDEF RESPAWN_INSTEAD_OF_DEATH 5159 STA PlayerHealth
src/prg-e-f.asm lines 5154–5159 at b73415e · upstream ↗ 1995HandlePlayerState_Dying: 1996 LDA PlayerStateTimer 1997 BNE locret_BANK0_8A86 ⋮ 1999 LDA PlayerScreenYHi 2000 CMP #02 2001 BEQ LoseALife ⋮ 2003 JSR ApplyPlayerPhysicsY ⋮ 2005 LDA PlayerYVelocity 2006 BMI loc_BANK0_8A72 ⋮ 2008 CMP #$39 2009 BCS locret_BANK0_8A86 ⋮ 2011loc_BANK0_8A72: ⋮
src/prg-0-1.asm lines 1995–2014 at b73415e · upstream ↗ 270; enum PlayerHealthValues 271PlayerHealth_1_HP = $0F 272PlayerHealth_2_HP = $1F 273PlayerHealth_3_HP = $2F 274PlayerHealth_4_HP = $3F
src/defs.asm lines 270–274 at b73415e · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-26.
Checked by a second AI model, 2026-10-21.
Revised after a check by a second AI model, 2026-10-26.
- ^ abcdDracula's Curse turns a hit into a launch, where Castlevania steps a second table; the character is given 2 px/frame up and 1 px/frame sideways and faces opposite to that push (facing left with +1 speed when $90 is nonzero, else facing right with −1), and the hurt state adds 0.125 px/frame² of gravity each frame up to a 5 px/frame fall.Codevinheim3/castlevania3-disasm · “Castlevania III - Dracula's Curse (USA)” · “Castlevania (USA) (Rev 1)”revised
How we know
lda #$26 … sta wPlayerStateDoubled.w … lda #$fe … sta wEntityVertSpeed.w … lda $90 … sta wEntityFacingLeft.w … lda #$01 … lda #$ff … sta wEntityHorizSpeed.w
code/playerStateProcessing_b1c.s#L326-L349 · upstream ↗ lda wPlayerStateDoubled.w … cmp #$26
code/playerStateProcessing_b1c.s#L4182-L4185 · upstream ↗ In the cartridge (“Castlevania III - Dracula's Curse (USA)”): bank $1C $9892-$98BE: vertical sub-speed + $20, carried into the speed; a falling speed capped at 5.0. We don't reproduce the bytes.
In the cartridge (“Castlevania (USA) (Rev 1)”): Castlevania's hit, which points the arc at a second table (castlevania-line/knockback). We don't reproduce the bytes.
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.
- ^A hit throws Sonic up at
-$400and away from the object at$200(-$200and$100underwater), and the hurt routine's gravity is$30, 8 less than the usual$38.Codesonicretro/s1disasmHow we know
394 move.w #-$400,obVelY(a0) ; bounce Sonic vertically 395 move.w #-$200,obVelX(a0) ; bounce Sonic horizontally ⋮ 405 neg.w obVelX(a0) ; if Sonic is right of the object, reverse
_incObj/Sonic ReactToItem.asm lines 394–405 at 15dfa3a · upstream ↗ 1869 addi.w #gravity-8,obVelY(a0) ; apply gravity (this is 8 less than the normal gravity of $38)_incObj/01 Sonic.asm lines 1868–1869 at 15dfa3a · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^ abA hit throws Sonic up at
-$400and away from the object at$200(half both underwater), and the hurt routine's gravity is$30.Codesonicretro/s2disasm · sonicretro/s1disasmrevisedHow we know
85678 move.w #-$400,y_vel(a0) ; make Sonic bounce away from the object 85679 move.w #-$200,x_vel(a0) ⋮ 85689 blo.s Hurt_ChkSpikes ; if Sonic is left of the object, branch 85690 neg.w x_vel(a0) ; if Sonic is right of the object, reverse
s2.asm lines 85677–85690 at 4ef457c · upstream ↗ 38222 jsr (ObjectMove).l 38223 addi.w #$30,y_vel(a0)
s2.asm lines 38222–38223 at 4ef457c · upstream ↗ 394 move.w #-$400,obVelY(a0) ; bounce Sonic vertically 395 move.w #-$200,obVelX(a0) ; bounce Sonic horizontally
_incObj/Sonic ReactToItem.asm lines 394–395 at 15dfa3a · upstream ↗ addi.w #gravity-8,obVelY(a0)
_incObj/01 Sonic.asm#L1869 · 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.
- ^ abA hit throws the player up at
-$400and away from the object at$200(half both underwater), the speeds of Sonic 1 and Sonic 2.Codesonicretro/skdisasm · sonicretro/s1disasm · sonicretro/s2disasmrevisedHow we know
21130 move.w #-$400,y_vel(a0) 21131 move.w #-$200,x_vel(a0) ⋮ 21134 move.w #-$200,y_vel(a0) 21135 move.w #-$100,x_vel(a0) ⋮ 21141 neg.w x_vel(a0)
sonic3k.asm lines 21130–21141 at 73de97c · upstream ↗ 394 move.w #-$400,obVelY(a0) ; bounce Sonic vertically 395 move.w #-$200,obVelX(a0) ; bounce Sonic horizontally
_incObj/Sonic ReactToItem.asm lines 394–395 at 15dfa3a · upstream ↗ 85678 move.w #-$400,y_vel(a0) ; make Sonic bounce away from the object 85679 move.w #-$200,x_vel(a0)
s2.asm lines 85678–85679 at 4ef457c · 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.
- ^ abcdMeasured the same way, with the crawler moved off Samus during each blink, the three pushes carried her 37, 45, and 44 px away from it; two lifted her 19 px and one 2 px.Verified“Metroid (USA)” · nmikstas/metroid-disassembly
How we know
In the cartridge (“Metroid (USA)”): bank 7 CheckHealthStatus. We don't reproduce the bytes.
2428 sta DmgPushDir ⋮ 2435 and #$08 2436 lsr 2437 lsr 2438 lsr 2439 sta DmgPushDir 2440* lda #$FD 2441 sta ObjVertSpeed
Source_Files/Bank07.asm lines 2421–2463 at 4270d57 · upstream ↗ Measured by a script in MesenCE 2.2.1 (build 4b8a196), on Metroid (USA) (SHA-1
2080059bea45…). 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.
- ^ abc
Walker_Movemoves a walking object by its shove whenever one is set, in place of its walking, so Link can't steer during a shove.Codealdonunez/zelda1-disassembly · “Legend of Zelda, The (USA) (Rev 1)”How we know
2600Walker_Move: 2601 ; If the object is being shoved, then go shove it. 2602 LDA ObjShoveDir, X 2603 BEQ @ChooseObjDirOrInputDir 2604 JMP Obj_Shove
src/Z_07.asm lines 2600–2604 at 50a1c86 · upstream ↗ In the cartridge (“Legend of Zelda, The (USA) (Rev 1)”): bank 7 $EFD0. We don't reproduce the bytes.
Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^ abcdWhen a monster hits Link, the shove points away from the monster along one axis: the horizontal one when Link is between grid squares and faces left or right, the vertical one when he is between squares facing up or down. The monster then turns around, unless bit 7 of its object attributes is set (a flag the disassembly's comments name "reverse after hit Link") or it is a Vire (object type
$12).Codealdonunez/zelda1-disassembly · “Legend of Zelda, The (USA) (Rev 1)”How we know
6528 LDA #$08 6529 STA $08 6530 LDA ObjY, X 6531 STA $04 6532 LDA a:ObjY, Y 6533 STA $05 ⋮ 6538 CPY #$00 6539 BNE :+ 6540 LDA ObjGridOffset 6541 BEQ :+ 6542 LDA ObjDir 6543 AND #$03 ⋮
src/Z_01.asm lines 6528–6581 at 50a1c86 · upstream ↗ 6597 LDA $08 6598 ORA #$80 6599 STA ObjShoveDir
src/Z_01.asm lines 6597–6599 at 50a1c86 · upstream ↗ 6614 ; If the monster's object attribute "reverse after hit Link" is set, 6615 ; then return. 6616 LDA ObjAttr, X 6617 AND #$80 6618 BNE @Exit ⋮ 6621 LDA ObjType, X 6622 CMP #$12 6623 BEQ @Exit ⋮ 6626 LDA ObjDir, X 6627 JSR GetOppositeDir 6628 STA ObjDir, X
src/Z_01.asm lines 6612–6628 at 50a1c86 · upstream ↗ 5321UpdateObject_JumpTable: 5322 .ADDR DoNothing ⋮ 5340 .ADDR UpdateVire
src/Z_07.asm lines 5321–5340 at 50a1c86 · upstream ↗ In the cartridge (“Legend of Zelda, The (USA) (Rev 1)”): bank 1 BeginShove. We don't reproduce the bytes.
Checked against the evidence by its author, an AI model, 2026-10-25.
Checked by a second AI model, 2026-10-21.
Checked by a second AI model, 2026-10-25.
- ^ abcdMeasured in Rev 1, each of the Tektite's first three hits shoves Link 32 px to the right in 8 frames.Verified“Legend of Zelda, The (USA) (Rev 1)” · aldonunez/zelda1-disassemblyrevised
How we know
In the cartridge (“Legend of Zelda, The (USA) (Rev 1)”): bank 7 Obj_Shove and ShoveMoveMin, which move Link in the probe. We don't reproduce the bytes.
2348 LDA ObjGridOffset, X ⋮ 2397ShoveMoveMin: ⋮ 2399 LDA #$04 2400 STA $03 ⋮ 2405 LDA ObjGridOffset, X ⋮ 2452 DEC ObjShoveDistance, X ⋮ 2455 LDA ObjGridOffset, X 2456 CLC 2457 ADC $02 2458 STA ObjGridOffset, X ⋮ 2470 STA ObjGridOffset, X
src/Z_07.asm lines 2323–2470 at 50a1c86 · upstream ↗ Measured by a script in MesenCE 2.2.1 (build 4b8a196), on Legend of Zelda, The (USA) (Rev 1) (SHA-1
4671517d72d0…). 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.
Revised after a check by a second AI model, 2026-10-25.
- ^ abA weapon that hurts a monster sets the monster's invincibility timer to 16, which lasts 32 frames, and shoves it 64 px in the weapon's direction, unless the monster is already invincible or immune to the weapon's damage type.Codealdonunez/zelda1-disassembly · “Legend of Zelda, The (USA) (Rev 1)”
How we know
6503BeginShove: 6504 ; If a weapon attacks a monster, and the weapon's damage 6505 ; type matches the monster's invincibility mask; 6506 ; then return without shoving.
src/Z_01.asm lines 6503–6514 at 50a1c86 · upstream ↗ 6636 ; Set the shove direction to the weapon's direction, ⋮ 6653 ; If the monster is invincible, then return without shoving. 6654 LDA ObjInvincibilityTimer, X 6655 BNE @Exit2 ⋮ 6671 BNE @Exit2 ⋮ 6676 BNE @Exit2 ⋮ 6687 ; Mark the monster invincible $10 frames, and should move $40 pixels. 6688 LDA #$40 6689 STA ObjShoveDistance, X 6690 LDA #$10 6691 STA ObjInvincibilityTimer, X
src/Z_01.asm lines 6636–6691 at 50a1c86 · upstream ↗ In the cartridge (“Legend of Zelda, The (USA) (Rev 1)”): bank 1 BeginShove. We don't reproduce the bytes.
Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^A hit faces Mega Man against the enemy's facing and puts him in the hit animation (
$12), which sets his upward speed to 1.25 px/frame ($01.$40) once and pushes him backward, against his own facing, at 0.5625 px/frame ($90) under the usual gravity until the animation ends.Codelsmmega/mm1How we know
124 LDA z:z0D 125 AND #objects_right 126 EOR #objects_right 127 ORA #$03 128 STA aobject_flag
engine/check_megaman_damaged.asm lines 124–128 at b606a84 · upstream ↗ 1_handle_megaman_heavily_objects: 2 ASL 3 TAX 4 LDY megaman_heavily_objects_and_ycoord_speed_table - 2, X 5 LDA megaman_heavily_objects_and_ycoord_speed_table - 1, X ⋮ 12 JSR _handle_special_megaman_objects 13 LDA aobject_frameset_timer 14 BEQ _handle_megaman_heavily_objects_unforced 15 JSR _ice_tsa_move 16 LDA z:zentire_toward ⋮ 30 AND #objects_right 31 BNE @right ⋮
engine/handle_special_megaman_objects.asm lines 1–64 at b606a84 · upstream ↗ 152 .BYTE $12 ⋮ 163 .BYTE $09
engine/ice_tsa.asm lines 151–163 at b606a84 · upstream ↗ 12 .BYTE $00 | $90data/special_xcoord_speed_table.asm line 12 at b606a84 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^ abMega Man 2 keeps Mega Man's hit numbers too, 111 frames of invincibility (
$6F) and a knockback of 1.25 px/frame up and 0.5625 back.Codelsmmega/mm1 · lsmmega/mm2How we know
129 LDA #$6F 130 STA z:zmegaman_invincibility_time
engine/check_megaman_damaged.asm lines 129–130 at b606a84 · upstream ↗ 64 .BYTE $12, $01 | $40engine/handle_special_megaman_objects.asm line 64 at b606a84 · upstream ↗ 12 .BYTE $00 | $90data/special_xcoord_speed_table.asm line 12 at b606a84 · upstream ↗ 11 LDA #$6F 12 STA z:zmegaman_invincibility_time 13 LDA #$01 14 STA aobject_ycoord_speed 15 LDA #$40 16 STA aobject_ycoord_speed_fraction 17 LDA #$00 18 STA aobject_xcoord_speed 19 LDA #$90 20 STA aobject_xcoord_speed_fraction
home/megaman_hit.asm lines 11–20 at 94f0bf3 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^
_megaman_hitsets Mega Man's upward speed to 1.25 px/frame ($01.$40) and his horizontal speed to 0.5625 ($90) once; the hit state then moves him against his facing under the usual gravity until his animation's upper timer returns to 0, and leaves to the jumping or standing state.Codelsmmega/mm2How we know
6 LDA #$02 7 STA z:zmegaman_status 8 JSR _check_megaman_hit_status 9 LDA #$01 10 STA aobject_frameset_upper_timer 11 LDA #$6F 12 STA z:zmegaman_invincibility_time 13 LDA #$01 14 STA aobject_ycoord_speed 15 LDA #$40 16 STA aobject_ycoord_speed_fraction 17 LDA #$00 ⋮
home/megaman_hit.asm lines 5–20 at 94f0bf3 · upstream ↗ 52_run_megaman_megaman_hit: 53 LDA aobject_flag 54 AND #objects_right 55 EOR #objects_right 56 STA z:ztoward 57 JSR _check_object_horizontal_move 58 JSR _check_object_vertical_move 59 LDA aobject_frameset_upper_timer 60 BEQ @knock_back_done 61 JSR _check_megaman_hit_status 62 RTS ⋮ 64@knock_back_done: ⋮
engine/run_megaman.asm lines 52–72 at 94f0bf3 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^ abcdA hit (state
$06) sets Mega Man's vertical speed to the resting$FF.$C0on its first frame, then each frame applies gravity and pushes him against his facing at 0.5 px/frame ($00.$80) until the hurt animation's state reaches 9; a hit during a slide doesn't push him.Codeplasticsmoke/megaman3-disassembly-ca65How we know
750player_damage_anim_set: jsr reset_sprite_anim ; set player damage animation 751 lda #$00 ; clear walk/shoot flag 752 sta shoot_anim_timer ; clear walk/shoot flag 753 jsr reset_gravity ; reset vertical velocity
src/fixed/player_states.asm lines 750–753 at 58ca1c3 · upstream ↗ 776player_knockback_physics: lda $3E ; check saved OAM for special cases: 777 cmp #$10 ; $10 = sliding (no knockback physics) 778 beq player_knockback_landing ; sliding → skip knockback 779 cmp #$79 ; >= $79 = special state (skip physics) 780 bcs player_knockback_landing ; special OAM → skip knockback physics 781 ldy #$00 ; Y = 0 (player slot) 782 jsr move_vertical_gravity ; apply gravity, carry = landed 783 lda #$80 ; knockback speed = $00.80 (half pixel/frame) 784 sta ent_xvel_sub ; set knockback X speed sub 785 lda #$00 ; knockback X speed whole = 0 786 sta ent_xvel ; x_speed whole = 0 787 lda ent_flags ; save facing before move ⋮
src/fixed/player_states.asm lines 776–790 at 58ca1c3 · upstream ↗ 806player_knockback_landing: lda ent_anim_state ; ent_anim_state = animation/collision state 807 cmp #$09 ; $09 = landed after knockback 808 bne player_knockback_done ; not landed → continue knockback
src/fixed/player_states.asm lines 806–808 at 58ca1c3 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^ abMega Man 4 keeps Mega Man 3's knockback, 0.5 px/frame (
$00.$80) against his facing under gravity until the hurt animation reaches 9, with no push when the hit lands during a slide.Codeplasticsmoke/megaman4-disassembly-ca65 · plasticsmoke/megaman3-disassembly-ca65How we know
801 LDY ent_var5 ; knockback probe selector 802 JSR entity_player_collide ; ride/collide with platforms 803 LDA #$80 ; knockback speed 0.5 px/frame 804 STA ent_xvel_sub ; X velocity sub 805 LDA #$00 ; zero 806 STA ent_xvel ; X velocity px 807 LDA ent_flags ; player flags 808 PHA ; save (facing) 809 LDA ent_hp ; hurt sub-state 810 CMP #$02 ; $02 = was sliding 811 BEQ L_8616 ; sliding: skip pushback
src/bank3C.asm lines 801–811 at a63bb6e · upstream ↗ 830 LDA ent_anim_phase ; player anim counter 831 CMP #$09 ; knockback anim done (frame 9)? 832 BNE L_865B ; not yet: keep flying back
src/bank3C.asm lines 830–832 at a63bb6e · upstream ↗ 776player_knockback_physics: lda $3E ; check saved OAM for special cases: 777 cmp #$10 ; $10 = sliding (no knockback physics) 778 beq player_knockback_landing ; sliding → skip knockback ⋮ 783 lda #$80 ; knockback speed = $00.80 (half pixel/frame) 784 sta ent_xvel_sub ; set knockback X speed sub 785 lda #$00 ; knockback X speed whole = 0 786 sta ent_xvel ; x_speed whole = 0
src/fixed/player_states.asm lines 776–786 at 58ca1c3 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^A monster's touch sets Link's speed to 24 on the longer axis of the line from the monster to Link, the other axis in proportion, with a hop of vertical speed 12. It also sets a timer to 19 and Link's recoil flag. While the flag is set, his state handler runs the recoil state instead of the code that reads the buttons, and that state counts the timer down each frame, holding it at 1 until Link lands, so the recoil lasts at least 19 frames.Codespannerisms/usdasmrevised
How we know
22720|06F3E3| LDA.b #$13 22721|06F3E5| STA.b $46 ⋮ 22723|06F3E7| LDA.b #$18 22724|06F3E9| JSR ApplyRecoilToLink ⋮ 22726|06F3EC| LDA.b #$01 22727|06F3EE| STA.b $4D
bank_06.asm lines 22720–22727 at bcdd96e · upstream ↗ 23385ApplyRecoilToLink: 23386|06F688| PHA ⋮ 23397|06F695| LSR A 23398|06F696| STA.b $29
bank_06.asm lines 23385–23399 at bcdd96e · upstream ↗ 20385ProjectSpriteSpeedTowardsLink: ⋮ 20438.x_is_bigger ⋮ 20446.next 20447|06E9CC| LDA.b $0B 20448|06E9CE| CLC 20449|06E9CF| ADC.b $0C 20450|06E9D1| CMP.b $0D ⋮ 20459|06E9DB| DEX 20460|06E9DC| BNE .next
bank_06.asm lines 20385–20492 at bcdd96e · upstream ↗ 239|07812C| LDA.b $4D 240|07812E| BEQ .not_recoiling ⋮ 320|078199| LDA.b #$02 ; LINKSTATE 02 321|07819B| STA.b $5D ⋮ 323|07819D| BRL LinkState_Recoil
bank_07.asm lines 239–323 at bcdd96e · upstream ↗ 1450HandleRecoilAndTimer: ⋮ 1457|07871A| DEC.b $46 ⋮ 1459|07871C| LDA.b $46 1460|07871E| BEQ .delay ⋮ 1462.airborne ⋮ 1467.delay 1468|078723| INC A 1469|078724| STA.b $46 ⋮ 1471|078726| LDA.b $24 ⋮ 1476.no_height 1477|07872E| LDA.b $29 1478|078730| BPL .airborne
bank_07.asm lines 1450–1478 at bcdd96e · 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.
- ^ abMega Man 5 keeps the 0.5 px/frame knockback, always against the way Mega Man faces, but lets the player resist it: with the direction he faces held, the push drops to 0.25 px/frame (
$40).Codeplasticsmoke/megaman5-disassembly-ca65 · plasticsmoke/megaman4-disassembly-ca65revisedHow we know
615player_st_hurt:src/bank1B.asm lines 615–637 at 7fd6512 · upstream ↗ L80C2: lda #$02 sta $08 lda $0528 and #$20 beq L80D1 lda #$01 sta $08
src/bank1B.asm#L138-L144 · upstream ↗ 803 LDA #$80 ; knockback speed 0.5 px/frame 804 STA ent_xvel_sub ; X velocity sub 805 LDA #$00 ; zero 806 STA ent_xvel ; X velocity px
src/bank3C.asm lines 803–806 at a63bb6e · 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.
- ^A monster's touch starts a 16-frame countdown and picks a speed of
$14($18for Moldorm), in both releases. In DX the speed goes along the line from the monster to Link, and while the countdown runs a routine at the top of Link's movement moves him by that speed and skips the rest, so the player can't steer.Codezladx/LADX-Disassembly · “Legend of Zelda, The - Link's Awakening (USA, Europe) (Rev 2)”revisedHow we know
ld a, $10 … ld [wIgnoreLinkCollisionsCountdown], a … cp ENTITY_MOLDORM … ld a, $14 … ld a, $18 … call func_003_7565
src/code/entities/bank3.asm#L5376-L5398 · upstream ↗ 6809func_003_7565::src/code/entities/bank3.asm lines 6809–6814 at 2a5c2c0 · upstream ↗ 588func_002_44C2::src/code/bank2.asm lines 588–614 at 2a5c2c0 · upstream ↗ In the cartridge (“Legend of Zelda, The - Link's Awakening (USA, Europe) (Rev 2)”): the 1993 release's knockback setup, bank 3, byte for byte DX's from the `$10` store to the Moldorm speed but for one jump address. We don't reproduce the bytes.
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.
- ^When an enemy touches Simon and there's room above him, Castlevania turns him to face the enemy, points his arc at a second, shorter table, and puts him in a hurt state that moves him away from the enemy with the walking move routine while it steps that table; the table rises 3, 3, 2, 1, 1, 1, 1, 1, 0, and 1 px, then holds for 7 steps, 14 px in all.Code“Castlevania (USA) (Rev 1)”
How we know
In the cartridge (“Castlevania (USA) (Rev 1)”): bank 7 $E734-$E73B, the contact code the Castlevania-Labelled-Disassembly labels BumpIntoEnemy: play the hurt sound, then call $FC97; bank 7 $FC97-$FCA1, which switches to bank 6 and calls $96C1; bank 6 $96D1-$971C: the take-off's ceiling test ($9998), then the arc pointer from $9BA5, rising, state 5; facing $0450 = 1 (left) unless the enemy's X is at or right of Simon's; direction $3C = (facing + 1) XOR 3, the other way; bank 6 $9BA5-$9BB9, the pointer ($9BA8), a $80 start marker, 17 signed steps ($FD = −3, up), and a $81 turn marker; bank 6 $936C-$9377, the state table's first six entries; state 5 runs $965B; bank 6 $965B-$9690, state 5: a short count, then each frame $970B (direction away from the facing), the move routine $989A, and the arc routine $9B1E. We don't reproduce the bytes.
Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^In the US version of Super Smash Bros., when a saved error flag the decompilers name
LBBACKUP_ERROR_RANDOMKNOCKBACKis set,ftParamGetCommonKnockbackreplaces every knockback it computes with a random value below 200. The VS mode menu sets that flag when the save's boot count is above 21 andgSYMainImemOKis false, whichsyMainSetImemStatussets when the word it reads at the start of the RSP's instruction memory (SP_IMEM_START) isn't 6103.CodeVetriTheRetri/ssb-decomp-reHow we know
1469 if (gSCManagerBackupData.error_flags & LBBACKUP_ERROR_RANDOMKNOCKBACK) ⋮ 1471 knockback = syUtilsRandFloat() * 200.0F; ⋮ 1473 return knockback;
src/ft/ftparam.c lines 1469–1473 at 572a747 · upstream ↗ 168#define LBBACKUP_ERROR_RANDOMKNOCKBACK (1 << nLBBackupErrorRandomKnockback) // 0x1 - Random knockback between 0.1 (?) and 1.0 x 200usrc/lb/lbdef.h line 168 at 572a747 · upstream ↗ 1622 if (!(gSCManagerBackupData.error_flags & LBBACKUP_ERROR_RANDOMKNOCKBACK) && (gSCManagerBackupData.boot > 21) && (gSYMainImemOK == FALSE)) ⋮ 1624 gSCManagerBackupData.error_flags |= LBBACKUP_ERROR_RANDOMKNOCKBACK;
src/mn/mnvsmode/mnvsmode.c lines 1622–1625 at 572a747 · upstream ↗ 134void syMainSetImemStatus(void) ⋮ 136 if (IO_READ(SP_IMEM_START) == 6103) ⋮ 138 gSYMainImemOK = TRUE; ⋮ 140 else gSYMainImemOK = FALSE;
src/sys/main.c lines 134–141 at 572a747 · upstream ↗ 172f32 syUtilsRandFloat(void) ⋮ 177 return ((step >> 16) & 0xFFFF) / 65536.0F;
src/sys/utils.c lines 172–177 at 572a747 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^In lava, Samus's blink is set to 50 on every frame, so enemies can't touch her, while the lava takes 0.7 units twice every 8 frames without a push; the Varia suit cuts that to once, and
SubtractHealthhalves it to 0.3 units.Codenmikstas/metroid-disassembly · “Metroid (USA)”revisedHow we know
5432LE27B: sty DmgPushDir ;Don't push Samus from lava damage. 5433LE27D: jsr ClearHealthChange ;($F323)Clear any pending health changes to Samus. 5434LE280: lda #$32 ; 5435LE282: sta SamusBlink ;Make Samus blink. ⋮ 5441LE28F: lsr ;This portion of the code causes Samus to be damaged by 5442LE290: and #$03 ;lava twice every 8 frames if she does not have the varia 5443LE292: bne ++ ;but only once every 8 frames if she does. ⋮ 5448LE29D:* lda #$07 ; 5449LE29F: sta HealthLoChange ;Samus takes lava damage. 5450LE2A1: jsr SubtractHealth ;($CE92)
Source_Files/Bank07.asm lines 5432–5450 at 4270d57 · upstream ↗ 2523LCEAC: lda SamusGear ; 2524LCEAF: and #gr_VARIA ;Check is Samus has Varia. ⋮ 2526LCEB3: lsr HealthLoChange ;If Samus has Varia, divide damage by 2.
Source_Files/Bank07.asm lines 2523–2527 at 4270d57 · upstream ↗ In the cartridge (“Metroid (USA)”): bank 7 LavaAndMoveCheck, $E269. We don't reproduce the bytes.
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: The Varia suit halves lava damage, to 0.3 units.
Sources
Code
- Núñez, Aldo. 2021. “zelda1-disassembly: A complete disassembly of The Legend of Zelda.” Commit 50a1c86. aldonunez/zelda1-disassembly @ 50a1c86 · licence, all uses
- n.d. “Legend of Zelda, The (USA) (Rev 1).” · licence, all uses
- nmikstas and Kent Hansen. 2025. “metroid-disassembly: Metroid software disassembly.” Commit 4270d57. nmikstas/metroid-disassembly @ 4270d57 · licence, all uses
- n.d. “Metroid (USA).” · licence, all uses
- VetriTheRetri. 2026. “ssb-decomp-re: a decompilation of Super Smash Bros. (VetriTheRetri/ssb-decomp-re).” Commit 572a747. VetriTheRetri/ssb-decomp-re @ 572a747 · licence, all uses
- doldecomp. 2026. “melee: a decompilation of Super Smash Bros. Melee (doldecomp/melee).” Commit f0cdbb0. doldecomp/melee @ f0cdbb0 · licence, all uses
- plasticsmoke. 2026. “Mega Man 3 (U), annotated ca65 disassembly (plasticsmoke).” Commit 58ca1c3. plasticsmoke/megaman3-disassembly-ca65 @ 58ca1c3 · licence, all uses
- plasticsmoke. 2026. “Mega Man 4 (U), annotated ca65 disassembly (plasticsmoke).” Commit a63bb6e. plasticsmoke/megaman4-disassembly-ca65 @ a63bb6e · licence, all uses
- plasticsmoke. 2026. “Mega Man 5 (U), annotated ca65 disassembly (plasticsmoke).” Commit 7fd6512. plasticsmoke/megaman5-disassembly-ca65 @ 7fd6512 · licence, all uses
- 1988. “Castlevania II - Simon's Quest (USA).” · licence, all uses
- 1987. “Castlevania (USA) (Rev 1).” · licence, all uses
- vinheim3. 2020. “castlevania3-disasm: a disassembly of Castlevania III: Dracula's Curse.” Commit 3272648. vinheim3/castlevania3-disasm @ 3272648 · licence, all uses
- 1990. “Castlevania III - Dracula's Curse (USA).” · licence, all uses
- Sonic Retro contributors. 2026. “s2disasm: Sonic the Hedgehog 2 (16-bit) disassembly (sonicretro/s2disasm).” Commit 4ef457c. sonicretro/s2disasm @ 4ef457c · licence, all uses
- Sonic Retro contributors. 2026. “s1disasm: Sonic the Hedgehog (16-bit) disassembly (sonicretro/s1disasm).” Commit 15dfa3a. sonicretro/s1disasm @ 15dfa3a · licence, all uses
- Sonic Retro contributors. 2026. “skdisasm: Sonic 3 & Knuckles disassembly (sonicretro/skdisasm).” Commit 73de97c. sonicretro/skdisasm @ 73de97c · licence, all uses