Wall jump
A jump that pushes off a wall in midair.
On this page
A wall jump starts a new jump from a wall in midair. In Super Metroid it works only from a spin jump: with the d-pad held away from a wall or solid enemy within 8 px, a new jump press pushes off at 4.625 px/frame up1. In Metroid, a jump press in the air works only in lava2. Super Mario 64’s wall kick needs speed, where Super Metroid’s needs a spin3,1. A jump that hits a wall fast enough holds Mario against it, and a press within 7 frames3 kicks him off.
Metroid: Zero Mission needs a spin jump or the Screw Attack, as Super Metroid needs a spin4,1. Touching a wall starts a timer, and a press facing away within 8 frames of the spin handler after the last wall touch4 starts the wall jump. In a decompilation that doesn’t yet match, Super Mario Sunshine holds Mario on the wall and lets a press on any update kick him off, at 62 up, 24 forward, from a slide with no time limit5. Super Mario 64’s kick has a window3.
- NoneMetroid (1986). In the air a jump press works only in lava.2
- Push off from a spinSuper Metroid (1994). From a spin jump, holding away from a wall within 8 px.1
- KickSuper Mario 64 (1996). A wall hit at speed holds Mario against it, and A within 7 frames kicks him off at 62 units/frame up.3
- Wall slideSuper Mario Sunshine (2002). A wall hit above 16 forward holds Mario on the wall, sliding ever faster after 10 updates, and A at any point kicks him off at 62 up and 24 forward.5
- glitch Super Mario Bros. (1985). A foot that dips into a wall near the top of one of its blocks stands Mario on its side for a frame, and A then jumps.6,7,8
#As a glitch
Super Mario Bros. has no wall jump in its jump code, but its foot check lands Mario on any block it finds less than 59 px into, a wall’s side included9,6. For a frame or two he counts as standing on the wall, and a press jumps7. Super Mario Wiki calls it a glitch8.
Games
| Game | Year | How | Note |
|---|---|---|---|
| Super Metroid | 1994 | Push off from a spin | from a spin jump, holding away from a wall within 8 px |
| Metroid: Zero Mission | 2004 | Push off from a spin | from a spin jump, facing away within 8 frames of touching a wall |
| Super Mario 64 | 1996 | Kick | a wall hit at speed holds Mario against it, and A within 7 frames kicks him off at 62 units/frame up |
| Super Mario Sunshine | 2002 | Wall slide | a wall hit above 16 forward holds Mario on the wall, sliding ever faster after 10 updates, and A at any point kicks him off at 62 up and 24 forward |
| Super Mario Bros. | 1985 | glitch | a foot that dips into a wall near the top of one of its blocks stands Mario on its side for a frame, and A then jumps |
Every claim about this mechanic, by game (4)
References
- ^ abcdA wall jump starts only from a spin jump or another wall jump. Once the spin animation reaches its wall-jump frames, with a direction held away from a wall or solid enemy within 8 px, a new jump press jumps off at 4.625 px/frame up, or 5.5 with the Hi-Jump Boots.CodeInsaneFirebat/sm_disassembly
How we know
4838WallJump_Check:src/bank_90.asm lines 4838–4861 at 7af131e · upstream ↗ 4941 .wallJumpEligiblePressingLeft:src/bank_90.asm lines 4941–4951 at 7af131e · upstream ↗ 4960 .wallJumpEligiblePressingRight:src/bank_90.asm lines 4960–4986 at 7af131e · upstream ↗ LDA.W SamusPhysicsConstants_MaximumDistanceFromWallForWallJump STA.B DP_Temp12 STZ.B DP_Temp14 JSR.W WallJump_Check
src/bank_90.asm#L2897-L2900 · upstream ↗ 5072 .MaximumDistanceFromWallForWallJump: 5073; Maximum distance from wall for wall-jump
src/bank_90.asm lines 5072–5074 at 7af131e · upstream ↗ 5136 .InitialYSpeeds_WallJumping: ⋮ 5142 .InitialYSpeeds_HiJumpWallJumping:
src/bank_90.asm lines 5136–5143 at 7af131e · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^ abOnce Samus is airborne, the run and jump handlers start a jump only while she is in lava. Walking off a ledge makes her airborne at once:
VertAcceleratesets the falling gravity on the first frame with nothing below her.Codenmikstas/metroid-disassemblyHow we know
2252SamusRun: 2253LCCC2: ldx SamusDir 2254 lda SamusGravity 2255 beq +++++++
Source_Files/Bank07.asm lines 2252–2255 at 4270d57 · upstream ↗ 2286* lda SamusInLava 2287 beq + 2288 lda Joy1Change 2289 bmi LCD40 ; branch if JUMP pressed
Source_Files/Bank07.asm lines 2286–2289 at 4270d57 · upstream ↗ 2720 LDA SamusInLava 2721 BEQ + 2722 LDA Joy1Change 2723 BPL + ; branch if JUMP not pressed 2724 JSR LCFC3
Source_Files/Bank07.asm lines 2719–2724 at 4270d57 · upstream ↗ 5590LE37A: lda SamusGravity ;Is Samus rising or falling? ⋮ 5599LE38F: jsr CheckMoveDown ;($E7AD)Is Samus obstructed downwards? ⋮ 5606LE3A0: lda #$1A ;Samus is falling. Store falling gravity value. 5607LE3A2: sta SamusGravity ;
Source_Files/Bank07.asm lines 5590–5607 at 4270d57 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^ abcdA jump that hits a wall at a forward speed above 16 turns Mario around and holds him in
ACT_AIR_HIT_WALL. A press on its first 2 frames kicks off the wall. On the 3rd he bonks away,wallKickTimeris set to 5 and counts down once a frame, and A still kicks while it is nonzero: 7 frames in all. The kick takes off at 62 units/frame up and at least 24 forward.Coden64decomp/sm64revisedHow we know
388 case AIR_STEP_HIT_WALL: ⋮ 391 if (m->forwardVel > 16.0f) { ⋮ 396 m->faceAngle[1] += 0x8000; ⋮ 399 set_mario_action(m, ACT_AIR_HIT_WALL, 0);
src/game/mario_actions_airborne.c lines 388–399 at 9921382 · upstream ↗ 1314 if (++(m->actionTimer) <= 2) { 1315 if (m->input & INPUT_A_PRESSED) { ⋮ 1318 return set_mario_action(m, ACT_WALL_KICK_AIR, 0); ⋮ 1320 } else if (m->forwardVel >= 38.0f) { 1321 m->wallKickTimer = 5; ⋮ 1327 return set_mario_action(m, ACT_BACKWARD_AIR_KB, 0); 1328 } else { 1329 m->wallKickTimer = 5; ⋮ 1337 return set_mario_action(m, ACT_SOFT_BONK, 0);
src/game/mario_actions_airborne.c lines 1314–1337 at 9921382 · upstream ↗ 1156s32 act_backward_air_kb(struct MarioState *m) { 1157 if (check_wall_kick(m)) { 1158 return TRUE;
src/game/mario_actions_airborne.c lines 1156–1158 at 9921382 · upstream ↗ 1247s32 act_soft_bonk(struct MarioState *m) { 1248 if (check_wall_kick(m)) { 1249 return TRUE;
src/game/mario_actions_airborne.c lines 1247–1249 at 9921382 · upstream ↗ 1147s32 check_wall_kick(struct MarioState *m) { 1148 if ((m->input & INPUT_A_PRESSED) && m->wallKickTimer != 0 && m->prevAction == ACT_AIR_HIT_WALL) { 1149 m->faceAngle[1] += 0x8000; 1150 return set_mario_action(m, ACT_WALL_KICK_AIR, 0);
src/game/mario_actions_airborne.c lines 1147–1151 at 9921382 · upstream ↗ 1407 if (m->wallKickTimer > 0) { 1408 m->wallKickTimer--;
src/game/mario.c lines 1407–1409 at 9921382 · upstream ↗ 1705 update_mario_inputs(gMarioState); ⋮ 1714 // The function can loop through many action shifts in one frame, ⋮ 1717 while (inLoop) {
src/game/mario.c lines 1705–1717 at 9921382 · upstream ↗ 828 case ACT_WALL_KICK_AIR: 829 case ACT_TOP_OF_POLE_JUMP: 830 set_mario_y_vel_based_on_fspeed(m, 62.0f, 0.0f); 831 if (m->forwardVel < 24.0f) { 832 m->forwardVel = 24.0f;
src/game/mario.c lines 828–834 at 9921382 · 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.
- ^ abWhen a spin jump or Screw Attack touches a wall,
SamusCheckCollisionssetswalljumpTimerto 8 and stores the direction away from the wall. Each timeSamusSpinningruns, unless the Space Jump is active and Samus isn't slowed (slowedByLiquid), it takes 1 from a nonzero timer, and if Samus faces away from the wall, a new A press, with a solid block 10 px (40 subpixels) to the wall's side, starts a wall jump. The jump takes off at the normal or High Jump speed (mzm/jump-speed). Metroid takes a jump press in the air only in lava (metroid-samus/no-air-jump), so it has no wall jump.Codemetroidret/mzmrevisedHow we know
1109 case SPOSE_SPINNING: 1110 case SPOSE_SCREW_ATTACKING: 1111 pData->walljumpTimer = 8; 1112 pData->lastWallTouchedMidAir = pData->direction ^ (KEY_RIGHT | KEY_LEFT);
src/samus.c lines 1109–1112 at 2aae289 · upstream ↗ 4716 if (gEquipment.suitMiscActivation & SMF_SPACE_JUMP && !gSamusPhysics.slowedByLiquid) ⋮ 4723 else ⋮ 4729 else ⋮ 4731 // Check can wall jump 4732 if (pData->walljumpTimer != 0) ⋮ 4734 pData->walljumpTimer--; ⋮ 4736 // Holding correct direction and pressed A 4737 if (pData->direction & pData->lastWallTouchedMidAir) ⋮ 4739 if (gChangedInput & KEY_A) ⋮ 4741 // Get check offset 4742 if (pData->lastWallTouchedMidAir & KEY_RIGHT) 4743 xOffset = -(HALF_BLOCK_SIZE + EIGHTH_BLOCK_SIZE); ⋮
src/samus.c lines 4716–4751 at 2aae289 · upstream ↗ 4760 // Check turn 4761 if (gButtonInput & (OPPOSITE_DIRECTION(pData->direction))) ⋮ 4763 pData->direction ^= KEY_RIGHT | KEY_LEFT;
src/samus.c lines 4760–4763 at 2aae289 · upstream ↗ 1739 // Perform wall jump, set spinning 1740 pData->pose = SPOSE_SPINNING; ⋮ 1742 if (pCopy->forcedMovement == FORCED_MOVEMENT_MID_AIR_JUMP) ⋮ 1744 if (pEquipment->suitMiscActivation & SMF_HIGH_JUMP) 1745 pData->yVelocity = SAMUS_HIGH_JUMP_VELOCITY; 1746 else 1747 pData->yVelocity = SAMUS_LOW_JUMP_VELOCITY;
src/samus.c lines 1739–1747 at 2aae289 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Revised after a check by a second AI model, 2026-10-22.
- ^ abIn Super Mario Sunshine, by the decompilers' Player code, which doesn't yet match, when
jumpProcessreports a wall tojumpingBasicduring a jump, Mario is knocked back if his forward speed is above the parametermClashSpeed(default 50) outside the wire roll jump, stops on Yoshi, stops on a wall markedisNoWallJump, and catches a fence (isFence). Otherwise, at a forward speed above 16, he turns about (afterplayerRefrection) and, against a wall, holds on inMARIO_STATUS_WALL_SLIDE. TherestayWalladds 1 to the status timer each update, capped at 60, and 1 more while it is below 20, so he hangs still for 10 updates and then slides down at half the timer: −10.5 on the 11th update, then 0.5 faster each update to −30 (computed). An A press on any update on the wall kicks:startJumpWallturns him about and entersMARIO_STATUS_WALL_JUMP, whose take-off insetStatusToJumpingis 62 up and 24 forward, constants in the code; the 52 thatstartJumpWallwrites first is overwritten. Landing or losing the wall ends the hold. Super Mario 64 kicks at the same 62 up and at least 24 forward, and itsact_air_hit_wallalso writes a 52 that the kick's take-off overwrites, but it holds Mario only 2 frames and then bonks him away, with A still working for 5 more: 7 frames in all (sm64/wall-kick). With no wall to hold, Sunshine bonks him the way Super Mario 64 does: back down at 38 or faster, and at −8 if faster than 8.Code notesdoldecomp/sms · n64decomp/sm64revisedHow we know
947 Object(NonMatching, "Player/MarioJump.cpp"), ⋮ 949 PCHObject(NonMatching, "Player/MarioMove.cpp"), 950 Object(NonMatching, "Player/MarioPhysics.cpp"), ⋮ 964 PCHObject(NonMatching, "Player/MarioInit.cpp"),
configure.py lines 947–964 at d2cc8f5 · upstream ↗ 201 case 2: 202 if (mStatus != MARIO_STATUS_WIRE_ROLL_JUMP 203 && mForwardVel > mDeParams.mClashSpeed.get()) { ⋮ 205 changePlayerDropping(MARIO_STATUS_JUMP_SHORT_BACK_DOWN, 0U); ⋮ 209 if (onYoshi()) { 210 setPlayerVelocity(0.0f); ⋮ 213 if (mWallPlane != nullptr) { 214 if (mWallPlane->isNoWallJump()) { ⋮ 216 setPlayerVelocity(0.0f); ⋮ 220 if (mWallPlane != nullptr) { 221 if (mWallPlane->isFence()) { ⋮ 228 return changePlayerStatus(MARIO_STATUS_FENCE_JUMP_CATCH, 0, 0); ⋮
src/Player/MarioJump.cpp lines 201–250 at d2cc8f5 · upstream ↗ 252 if (mForwardVel > 8.0f) 253 setPlayerVelocity(-8.0f); 254 return changePlayerStatus(MARIO_STATUS_LAND_SAFE_DOWN, 0, 0);
src/Player/MarioJump.cpp lines 252–254 at d2cc8f5 · upstream ↗ 510 , PARAM_INIT(mClashSpeed, 50.0f)src/Player/MarioInit.cpp line 510 at d2cc8f5 · upstream ↗ 586BOOL TMario::stayWall() ⋮ 588 mStatusTimer += 1; 589 if (mStatusTimer > 60) 590 mStatusTimer = 60; ⋮ 592 if (mInput & 2) 593 return startJumpWall(); ⋮ 598 if (mStatusTimer < 20) { 599 mStatusTimer += 1; 600 mVel.set(0.0f, 0.0f, 0.0f); 601 } else { 602 mVel.y = -mStatusTimer * 0.5f; ⋮ 610 switch (jumpProcess(0)) { ⋮
src/Player/MarioJump.cpp lines 586–620 at d2cc8f5 · upstream ↗ 16BOOL TMario::startJumpWall() ⋮ 25 mVel.y = 52.0f; 26 mFaceAngle.y += 0x8000; 27 if (mVel.y + (160.0f + mPosition.y) >= mFloorPosition.x) 28 mVel.y = 1.0f; ⋮ 30 return changePlayerStatus(MARIO_STATUS_WALL_JUMP, 0, 0);
src/Player/MarioJump.cpp lines 16–30 at d2cc8f5 · upstream ↗ 517 case MARIO_STATUS_WALL_JUMP: 518 setPlayerJumpSpeed(0.0f, 62.0f); 519 mForwardVel = 24.0f;
src/Player/MarioMove.cpp lines 517–519 at d2cc8f5 · upstream ↗ 733 switch (status & MARIO_STATUS_TYPE_MASK) { ⋮ 737 case MARIO_STATUS_TYPE_JUMPING: 738 status = setStatusToJumping(status, arg);
src/Player/MarioMove.cpp lines 733–738 at d2cc8f5 · upstream ↗ 1479 if (mGamePad->checkFrameMeaning(TMarioGamePad::MEANING_A)) 1480 mInput |= 0x2;
src/Player/MarioMove.cpp lines 1479–1480 at d2cc8f5 · upstream ↗ 1314 if (++(m->actionTimer) <= 2) { 1315 if (m->input & INPUT_A_PRESSED) { 1316 m->vel[1] = 52.0f; 1317 m->faceAngle[1] += 0x8000; 1318 return set_mario_action(m, ACT_WALL_KICK_AIR, 0); ⋮ 1320 } else if (m->forwardVel >= 38.0f) { 1321 m->wallKickTimer = 5; ⋮ 1327 return set_mario_action(m, ACT_BACKWARD_AIR_KB, 0); ⋮ 1329 m->wallKickTimer = 5; ⋮ 1334 if (m->forwardVel > 8.0f) { 1335 mario_set_forward_vel(m, -8.0f); ⋮ 1337 return set_mario_action(m, ACT_SOFT_BONK, 0);
src/game/mario_actions_airborne.c lines 1314–1337 at 9921382 · upstream ↗ 1147s32 check_wall_kick(struct MarioState *m) { 1148 if ((m->input & INPUT_A_PRESSED) && m->wallKickTimer != 0 && m->prevAction == ACT_AIR_HIT_WALL) { 1149 m->faceAngle[1] += 0x8000; 1150 return set_mario_action(m, ACT_WALL_KICK_AIR, 0);
src/game/mario_actions_airborne.c lines 1147–1151 at 9921382 · upstream ↗ 1407 if (m->wallKickTimer > 0) { 1408 m->wallKickTimer--;
src/game/mario.c lines 1407–1409 at 9921382 · upstream ↗ 828 case ACT_WALL_KICK_AIR: 829 case ACT_TOP_OF_POLE_JUMP: 830 set_mario_y_vel_based_on_fspeed(m, 62.0f, 0.0f); 831 if (m->forwardVel < 24.0f) { 832 m->forwardVel = 24.0f;
src/game/mario.c lines 828–833 at 9921382 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Revised after a check by a second AI model, 2026-10-22.
- ^ abMario can jump off a wall because the foot check counts a block in the wall's side as ground. If his move into a wall puts a foot point in a wall block while he is falling and less than 5 px below a block boundary,
PlayerBGCollisionlands him there; he starts the next frame on the ground, so a fresh press of A then jumps.CodeXkeeper0/smb1How we know
11215 LDY $04 ; check lower nybble of vertical coordinate returned 11216 CPY #$05 ; from collision detection routine 11217 BCC LandPlyr ; if lower nybble < 5, branch ⋮ 11221LandPlyr: ⋮ 11223 LDA #$f0 11224 AND Player_Y_Position ; mask out lower nybble of player's vertical position 11225 STA Player_Y_Position ; and store as new vertical position to land player properly ⋮ 11227 LDA #$00 ⋮ 11231InitSteP: 11232 LDA #$00 11233 STA Player_State ; set player's state to normal
src/prg.asm lines 11214–11233 at 1cc3c92 · upstream ↗ 4922 LDA Player_State ; check player state 4923 BEQ InitJS ; if on the ground, branch
src/prg.asm lines 4921–4923 at 1cc3c92 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^ abA wall jump's press has to come on a frame that starts with Mario caught on the wall's side, which is the frame after the catch and, when his foot went 1 px deeper, the frame after that too. Measured in the cartridge with big Mario, the window was one frame for a walking jump into a wall laid into World 1-1's start, two for a running hop into the level's first pipe, unedited, and one for a running hop from the bricks into World 2-1's last wall (smb1/world-2-1-wall-jump); a press on the catch frame itself, or one frame after the window, did nothing.VerifiedXkeeper0/smb1revised
How we know
LDY $04 CPY #$05 BCC LandPlyr
src/prg.asm#L11214-L11217 · upstream ↗ 11566 LDY #$00 ⋮ 11573 CLC
src/prg.asm lines 11547–11584 at 1cc3c92 · upstream ↗ 11221LandPlyr: ⋮ 11227 LDA #$00 ⋮ 11231InitSteP: 11232 LDA #$00
src/prg.asm lines 11221–11233 at 1cc3c92 · upstream ↗ 4921ProcJumping:src/prg.asm lines 4921–4923 at 1cc3c92 · upstream ↗ Measured by a script in MesenCE 2.2.1 (build 4b8a196), on . 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.
Revised after a check by a second AI model, 2026-10-22.
Revised after a check by a second AI model, 2026-10-25.
- ^ abSuper Mario Wiki counts Super Mario Bros.' wall jump among the glitches that resemble the later, designed Wall Jump, with "frame-perfect timing"; TASVideos' resource page explains it by the floor check running during the push out of a wall, and asks for speed above 16 (1 px/frame) toward the wall and feet meeting it at a block boundary.WikiSuper Mario Wiki, “Wall Jump” · TASVideos, “Game Resources: NES Super Mario Bros.”
How we know
maneuvers similar to the Wall Jump exist as glitches. For example, in Super Mario Bros., if Mario lands on a wall on a 16×16 boundary (so that his foot is on the top corner of a block), the player is able to jump from that point with frame-perfect timing.
History, Super Mario series · archived copy ↗ Walljump happens because the game does a floor check (a simple "is there a solid block below him?" test) even during a wall-ejection. … Some horizontal speed towards the wall (facing right: X speed > 16, facing left: X speed < 240)
Walljump · archived copy ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^ abWhen a foot point finds an ordinary solid block and Mario isn't moving up,
PlayerBGCollisionlands him if his Y is less than 5 px into the block's 16 px row; 5 px or more, it callsImpedePlayerMovein his moving direction instead, which pushes him 1 px back unless he is already moving away, and leaves without checking his sides.CodeXkeeper0/smb1revisedHow we know
11202ChkFootMTile: ⋮ 11205 LDY Player_Y_Speed ; check player's vertical speed 11206 BMI DoPlayerSideCheck ; if player moving upwards, branch ⋮ 11215 LDY $04 ; check lower nybble of vertical coordinate returned 11216 CPY #$05 ; from collision detection routine 11217 BCC LandPlyr ; if lower nybble < 5, branch 11218 LDA Player_MovingDir 11219 STA $00 ; use player's moving direction as temp variable 11220 JMP ImpedePlayerMove ; jump to impede player's movement in that direction
src/prg.asm lines 11202–11220 at 1cc3c92 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Revised after a check by a second AI model, 2026-10-22.
Sources
Code
- InsaneFirebat and P.JBoy. 2026. “sm_disassembly: a relocatable disassembly of Super Metroid.” Commit 7af131e. InsaneFirebat/sm_disassembly @ 7af131e · licence, all uses
- nmikstas and Kent Hansen. 2025. “metroid-disassembly: Metroid software disassembly.” Commit 4270d57. nmikstas/metroid-disassembly @ 4270d57 · licence, all uses
- n64decomp. 2023. “sm64: a decompilation of Super Mario 64 (n64decomp/sm64).” Commit 9921382. n64decomp/sm64 @ 9921382 · licence, all uses
- metroidret contributors. 2026. “mzm: a decompilation of Metroid: Zero Mission (metroidret/mzm).” Commit 2aae289. metroidret/mzm @ 2aae289 · licence, all uses
- doldecomp. 2026. “sms: a decompilation of Super Mario Sunshine (doldecomp/sms).” Commit d2cc8f5. doldecomp/sms @ d2cc8f5 · licence, all uses
- doppelganger and Xkeeper. 2022. “smb1: Super Mario Bros. disassembly for asm6f (Xkeeper0/smb1).” Commit 1cc3c92. Xkeeper0/smb1 @ 1cc3c92 · licence, all uses
Secondary
- Super Mario Wiki contributors. n.d. “Wall Jump.” Super Mario Wiki. original · archived · licence, all uses
- TASVideos contributors. n.d. “Game Resources: NES Super Mario Bros.” TASVideos. original · archived · licence, all uses