Claim set · data/claims/mzm.yaml

Metroid - Zero Mission (metroidret's decompilation of the US release)

Game: Metroid: Zero Mission.

The mzm decompilation's README names mzm_us.gba, the North American release, as its default build and gives its SHA-1 as 5de8536afe1f0078ee6fe1089f890e8c7aa0a6e8, which is the SHA-1 of the No-Intro file Metroid - Zero Mission (USA).gba. The atlas hasn't built it. mzm/build

Codemzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · README.md#L9-L12This repository can be used to build multiple ROMs. The ROMs are named like this: `mzm_{region}.gba` (or `mzm_{region}_debug.gba`) … - us: USA, North America `sha1: 5de8536afe1f0078ee6fe1089f890e8c7aa0a6e8`mzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · README.md#L21The default built ROM is mzm_us.gbamzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · mzm_us.sha1#L15de8536afe1f0078ee6fe1089f890e8c7aa0a6e8 mzm_us.gbaChecked by claude-agent, 2026-10-22 — read the README and mzm_us.sha1, and ran sha1sum on /data/roms/gba/Metroid - Zero Mission (USA).gba, which gives the same hash

Cited by: Metroid: Zero Mission

When a game starts rather than loads a file (gIsLoadingFile clear), SamusInit fills gEquipment with zeros and then sets Samus's maximum and current energy to 99, so she starts with 99 energy, no tanks, and no missiles, super missiles, or power bombs. Metroid starts her with 30 units. mzm/start-energy

About: Metroid: Zero Mission Health upgrade

Value: 99 energy

Codemzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · src/samus.c#L8071-L8088if (!gIsLoadingFile) { // Zero out most of samus's data DMA3_FILL_32(0, &gSamusData, sizeof(gSamusData)); DMA3_FILL_32(0, &gEquipment, sizeof(gEquipment)); … // Set starting info gSamusData.pose = SPOSE_FACING_THE_FOREGROUND; gSamusData.direction = KEY_LEFT; … gEquipment.maxEnergy = 99; gEquipment.currentEnergy = 99;mzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · include/structs/samus.h#L16-L24struct Equipment { u16 maxEnergy; u16 maxMissiles; u8 maxSuperMissiles; u8 maxPowerBombs; u16 currentEnergy; u16 currentMissiles; u8 currentSuperMissiles; u8 currentPowerBombs;metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L1580-L1583LDA #$00 ; STA HealthLo ;Starting health is LDA #$03 ;set to 30 units. STA HealthHi ;Checked by claude-agent, 2026-10-22 — read SamusInit to its end (the zeroing and the 99 sit under gSubGameMode3 == 0 and !gIsLoadingFile; a loaded file takes gEquipment from the save, save_file.c's `gEquipment = pFile->equipment`), the Equipment struct, and Metroid's SamusInit lines already cited by metroid/start-health

sStartingHealthAmmo in src/data/block_data.c holds the same starting values (99 energy, 0 of each ammunition) for the tank caps and the pause screen's debug menu. The game counts energy in whole units, where Metroid's health is binary-coded decimal in tenths (metroid/health-format).

Cited by: Health upgrade, Metroid: Zero Mission

On Easy and Normal an energy tank adds 100 to Samus's maximum energy, and on Hard 50, and sets her energy to the new maximum. A tank adds nothing if the maximum plus one more tank would pass 12 tanks plus the starting 99, so the maximum is 1299, or 699 on Hard (computed). In Metroid each tank holds 100 units, up to 6 tanks and 699.9 units, with the same refill. mzm/energy-tank

About: Metroid: Zero Mission Health upgrade

Value
{
 "easy": 100,
 "normal": 100,
 "hard": 50
}
Codemzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · src/bg_clip.c#L531-L537else if (i == ITEM_TYPE_ENERGY) { if (sNumberOfTanksPerArea[MAX_AMOUNT_OF_AREAS - 1].energy * sTankIncreaseAmount[gDifficulty].energy + sStartingHealthAmmo.energy >= gEquipment.maxEnergy + sTankIncreaseAmount[gDifficulty].energy) { gEquipment.maxEnergy += sTankIncreaseAmount[gDifficulty].energy; gEquipment.currentEnergy = gEquipment.maxEnergy;mzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · src/data/block_data.c#L52-L53[MAX_AMOUNT_OF_AREAS - 1] = { .energy = 12,mzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · src/data/block_data.c#L60-L81const struct TankList sStartingHealthAmmo = { .energy = 99, … const struct TankList sTankIncreaseAmount[DIFF_COUNT] = { [DIFF_EASY] = { .energy = 100, … [DIFF_NORMAL] = { .energy = 100, … [DIFF_HARD] = { .energy = 50,metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L4354-L4363LDC00:* LDA TankCount ; LDC03: CMP #$06 ;Has Samus got 6 energy tanks? LDC05: BEQ + ;If so, she can't have any more. LDC07: INC TankCount ;Otherwise give her a new tank. LDC0A:* LDA TankCount ; LDC0D: JSR Amul16 ;Get tank count and shift into upper nibble. LDC10: ORA #$09 ; LDC12: STA HealthHi ;Set new tank count. Upper health digit set to 9. LDC15: LDA #$99 ;Max out low health digit. LDC17: STA HealthLo ;Health is now FULL!Checked by claude-agent, 2026-10-22 — read the tank branch of the block-touch code in bg_clip.c and the three tables in block_data.c. Row MAX_AMOUNT_OF_AREAS - 1 is index 7 (MAX_AMOUNT_OF_AREAS is 8, Chozodia is 6), and its 12 equals the sum of the seven area rows (3, 2, 1, 3, 0, 0, 3). With maxEnergy starting at 99 and rising by whole tanks, the test fails first for a 13th tank: 12 x 100 + 99 = 1299, 12 x 50 + 99 = 699. Metroid's side is metroid/energy-tank and metroid/max-health

The atlas reads row 7 of sNumberOfTanksPerArea as the game's totals, since the code uses it only as a cap and it sums the area rows. The pause screen's debug menu writes the maximum directly and skips this test.

Cited by: Health upgrade, Metroid: Zero Mission

Missiles, super missiles, and power bombs each have their own maximum and count, and each tank adds to both: 5 missiles, 2 super missiles, or 2 power bombs on Easy and Normal, and 2, 1, or 1 on Hard, from a start of 0 (mzm/start-energy). Missile tanks stop adding past 50 tanks' worth, 250 missiles, or 100 on Hard (computed). Metroid has missiles only, and its tank adds 5 to both the count and the capacity. mzm/ammo-tanks

About: Metroid: Zero Mission Ammunition

Value
{
 "missile": [
  5,
  2
 ],
 "superMissile": [
  2,
  1
 ],
 "powerBomb": [
  2,
  1
 ]
}
Codemzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · src/bg_clip.c#L520-L528if (i == ITEM_TYPE_MISSILE) { if (sNumberOfTanksPerArea[MAX_AMOUNT_OF_AREAS - 1].missile * sTankIncreaseAmount[gDifficulty].missile + sStartingHealthAmmo.missile >= gEquipment.maxMissiles + sTankIncreaseAmount[gDifficulty].missile) { if (gEquipment.maxMissiles == 0) isFirstTank = TRUE; … gEquipment.maxMissiles += sTankIncreaseAmount[gDifficulty].missile; gEquipment.currentMissiles += sTankIncreaseAmount[gDifficulty].missile;mzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · src/bg_clip.c#L539-L558else if (i == ITEM_TYPE_SUPER_MISSILE) … gEquipment.maxSuperMissiles += sTankIncreaseAmount[gDifficulty].superMissile; gEquipment.currentSuperMissiles += sTankIncreaseAmount[gDifficulty].superMissile; … else if (i == ITEM_TYPE_POWER_BOMB) … gEquipment.maxPowerBombs += sTankIncreaseAmount[gDifficulty].powerBomb; gEquipment.currentPowerBombs += sTankIncreaseAmount[gDifficulty].powerBomb;mzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · src/data/block_data.c#L52-L54[MAX_AMOUNT_OF_AREAS - 1] = { .energy = 12, .missile = 50,mzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · src/data/block_data.c#L67-L84const struct TankList sTankIncreaseAmount[DIFF_COUNT] = { [DIFF_EASY] = { .energy = 100, .missile = 5, .superMissile = 2, .powerBomb = 2 }, [DIFF_NORMAL] = { .energy = 100, .missile = 5, .superMissile = 2, .powerBomb = 2 …metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L4349-L4351LDBF7:* BEQ + ;Branch if item is an energy tank. LDBF9: LDA #$05 ; LDBFB: JSR AddToMaxMissiles ;($DD97)Increase missile capacity by 5.metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L4635-L4650; Adds A to both MissileCount & MaxMissiles, storing the new count … ADC MissileCount … * STA MissileCount … ADC MaxMissiles … * STA MaxMissilesChecked by claude-agent, 2026-10-22 — read the four tank branches in bg_clip.c and sTankIncreaseAmount; the missile cap is 50 x 5 + 0 = 250 and 50 x 2 + 0 = 100. Row 7's 50 equals the sum of the area rows (10, 9, 13, 13, 1, 3, 1). Metroid's side is metroid/missile-tank, plus AddToMaxMissiles, which adds the same 5 to MissileCount and MaxMissiles (each capped at 255)

The first tank of each ammunition (a maximum of 0 before it) sets isFirstTank, which adds 1 to the banner's message id, from MESSAGE_MISSILE_TANK_ACQUIRED to MESSAGE_FIRST_MISSILE_TANK and likewise for the other two (bg_clip.c line 563; the names are the decompilers').

Cited by: Ammunition, Metroid: Zero Mission

A jump sets Samus's upward yVelocity to 192 (SAMUS_LOW_JUMP_VELOCITY), 232 with the High Jump active, or 212 without the suit, which is checked first. The velocity counts eighths of a subpixel and a pixel is 4 subpixels, so these are 6, 7.25, and 6.625 px/frame (computed). Movement caps the velocity at 192 (24 subpixels, 6 px), so the High Jump's first five frames each rise 6 px (computed). Metroid's jump always takes off at 4 px/frame, and its High Jump Boots lower the gravity instead of raising the speed. mzm/jump-speed

About: Metroid: Zero Mission Jump

Value
[
 6,
 7.25
]
Codemzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · src/samus.c#L1863-L1877if (pCopy->forcedMovement == FORCED_MOVEMENT_MID_AIR_JUMP) { // Set mid air pose, spinning if holding a sideways direction if (gButtonInput & (KEY_RIGHT | KEY_LEFT)) pData->pose = SPOSE_STARTING_SPIN_JUMP; else pData->pose = SPOSE_MIDAIR; … // Set Y velocity if (pEquipment->suitType == SUIT_SUITLESS) pData->yVelocity = SAMUS_SUITLESS_JUMP_VELOCITY; else if (pEquipment->suitMiscActivation & SMF_HIGH_JUMP) …mzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · src/samus.c#L1700-L1709// Starting a jump, always a spin jump because running implies a direction was held pData->pose = SPOSE_STARTING_SPIN_JUMP; … // Set jump velocity if (pEquipment->suitType == SUIT_SUITLESS) pData->yVelocity = SAMUS_SUITLESS_JUMP_VELOCITY; else if (pEquipment->suitMiscActivation & SMF_HIGH_JUMP) pData->yVelocity = SAMUS_HIGH_JUMP_VELOCITY; else pData->yVelocity = SAMUS_LOW_JUMP_VELOCITY;mzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · include/constants/samus.h#L336-L338#define SAMUS_HIGH_JUMP_VELOCITY (SUB_PIXEL_TO_VELOCITY(QUARTER_BLOCK_SIZE + PIXEL_SIZE * 3 + ONE_SUB_PIXEL)) #define SAMUS_LOW_JUMP_VELOCITY (SUB_PIXEL_TO_VELOCITY(QUARTER_BLOCK_SIZE + EIGHTH_BLOCK_SIZE)) #define SAMUS_SUITLESS_JUMP_VELOCITY (SUB_PIXEL_TO_VELOCITY(QUARTER_BLOCK_SIZE + EIGHTH_BLOCK_SIZE + PIXEL_SIZE / 2 + ONE_SUB_PIXEL / 2.f))mzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · include/constants/samus.h#L314-L315#define VELOCITY_TO_SUB_PIXEL(velocity) (DIV_SHIFT((velocity), 8)) #define SUB_PIXEL_TO_VELOCITY(velocity) ((s16)((velocity) * 8))mzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · include/types.h#L47-L65// The amount of sub pixels a single visible pixel contains #define SUB_PIXEL_RATIO 4 // The amount of visible pixels a block contains #define PIXEL_PER_BLOCK 16 … #define BLOCK_SIZE (PIXEL_PER_BLOCK * SUB_PIXEL_RATIO) … #define QUARTER_BLOCK_SIZE (BLOCK_SIZE / 4) … #define EIGHTH_BLOCK_SIZE (BLOCK_SIZE / 8) … #define PIXEL_SIZE (BLOCK_SIZE / PIXEL_PER_BLOCK) …mzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · src/samus.c#L6758-L6776if (pData->yVelocity > gSamusPhysics.positiveYVelocityCap) { velocity = DIV_SHIFT(gSamusPhysics.positiveYVelocityCap, 8); } … else { velocity = DIV_SHIFT(pData->yVelocity, 8); } … pData->yPosition -= velocity;mzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · include/constants/samus.h#L325#define SAMUS_Y_POSITIVE_VELOCITY_CAP 192metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2672-L2698SetSamusJump: … LDA #$FC STA ObjVertSpeed … LCFF3: LDY #$18 ; gravity (high value -> low jump) LDA SamusGear AND #gr_HIGHJUMP BEQ + ; branch if Samus doesn't have High Jump LDY #$12 ; lower gravity value -> high jump! * STY SamusGravityChecked by claude-agent, 2026-10-22 — read SamusSetMidAir's running-jump and default (standing) cases and the constants. BLOCK_SIZE is 64 subpixels, so the low jump is (16 + 8) x 8 = 192, the High Jump (16 + 12 + 1) x 8 = 232, and the suitless jump (16 + 8 + 2 + 0.5) x 8 = 212; dividing by 8 x 4 = 32 gives px/frame. SamusUpdateVelocityPosition moves Samus by the capped value shifted right 3 (in subpixels) and only then lowers yVelocity by 10, so 232, 222, 212, 202, and 192 each move 24 subpixels. positiveYVelocityCap is 192 out of liquid (SamusUpdatePhysics; mzm/gravity). Metroid's side is metroid-samus/jump-speed

The wall jump also takes the low or High Jump speed (src/samus.c lines 1742-1747, with no suitless case). Samus in the Morph Ball jumps at SAMUS_MORPH_BALL_JUMP_VELOCITY, the same 212. SamusUpdate runs once per frame of play, unless an item pickup's gPreventMovementTimer is running (src/in_game.c).

Cited by: Jump, Metroid: Zero Mission

Out of liquid (or in it with the Gravity Suit) and not held by a Metroid, SamusUpdatePhysics sets the vertical acceleration to 10 each frame, and SamusUpdateVelocityPosition takes it from yVelocity on every frame of the airborne poses while the velocity is at least -231, whether A is held or not: 0.3125 px/frame² (computed). A fall moves at most 128, 4 px/frame. In water, lava, or acid without the Gravity Suit, or out of liquid in a Metroid's grip, the acceleration halves to 5 and both caps drop to 40, 1.25 px/frame. Metroid's jump gravity is 0.09375 px/frame² (0.0703 with the High Jump Boots), and its falls reach 5 px/frame. mzm/gravity

About: Metroid: Zero Mission Gravity

Value: 0.3125 px/frame²

Codemzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · include/constants/samus.h#L324-L327#define SAMUS_Y_ACCELERATION 10 #define SAMUS_Y_POSITIVE_VELOCITY_CAP 192 #define SAMUS_Y_NEGATIVE_VELOCITY_CAP 128 #define SAMUS_Y_SLOWED_VELOCITY_CAP 40mzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · src/samus.c#L2649-L2697case HAZARD_TYPE_WATER: case HAZARD_TYPE_LAVA: case HAZARD_TYPE_WEAK_ACID: case HAZARD_TYPE_STRONG_ACID: // In liquid, check has gravity to see if slowed if (!(pEquipment->suitMiscActivation & SMF_GRAVITY_SUIT)) slowed++; #ifndef BUGFIX break; #endif … default: …mzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · src/samus.c#L6762-L6776else if (pData->yVelocity < -gSamusPhysics.negativeYVelocityCap) { velocity = DIV_SHIFT(-gSamusPhysics.negativeYVelocityCap, 8); } … if (pData->yVelocity >= -231) { pData->yVelocity -= gSamusPhysics.yAcceleration; } … pData->yPosition -= velocity;metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2693-L2698LCFF3: LDY #$18 ; gravity (high value -> low jump) LDA SamusGear AND #gr_HIGHJUMP BEQ + ; branch if Samus doesn't have High Jump LDY #$12 ; lower gravity value -> high jump! * STY SamusGravitymetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L5582-L5587;gravity used in the acceleration calculation. The higher the number, the more intense the gravity. ;The possible values for gravity are as follows: ;#$38-When Samus has been hit by an enemy. ;#$1A-When Samus is falling. ;#$18-Jump without high jump boots. ;#$12-Jump with high jump boots.metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L5628-L5629LE3C9:* cmp #$05 ;Has maximum downward speed been reached? LE3CB:* bcc + ;If not, branch.Checked by claude, 2026-10-25 — read SamusUpdatePhysics, which SamusUpdate calls first every frame, and the airborne poses' branch of SamusUpdateVelocityPosition; 10 / 32 = 0.3125, 128 / 32 = 4, and 40 / 32 = 1.25. Nothing in SamusMidAir or SamusSpinning changes yAcceleration. Metroid's side is metroid-samus/gravity: the jump stores $18, or $12 with the High Jump Boots, at LCFF3, and VertAccelerate caps a fall at 5

The liquid cases end in a break that only a BUGFIX build drops, so in the US build a Metroid's grip slows Samus only out of liquid, where the default case checks grabbedByMetroid. A shinespark or ballspark moves her by its own yVelocity with no gravity, and SamusGettingHurt can set the acceleration to 0.

Cited by: Gravity, Metroid: Zero Mission

Stepping the code's arithmetic with A held, out of liquid, a jump from the ground peaks about 59 px up (235 subpixels) on its 19th frame, and a High Jump about 83 px (331 subpixels) on its 23rd (computed: each frame moves yVelocity capped at 192 and shifted right 3, then takes 10 from it). mzm/jump-height

About: Metroid: Zero Mission Jump

Value
[
 58.75,
 82.75
]
Codemzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · include/constants/samus.h#L324-L337#define SAMUS_Y_ACCELERATION 10 #define SAMUS_Y_POSITIVE_VELOCITY_CAP 192 … #define SAMUS_HIGH_JUMP_VELOCITY (SUB_PIXEL_TO_VELOCITY(QUARTER_BLOCK_SIZE + PIXEL_SIZE * 3 + ONE_SUB_PIXEL)) #define SAMUS_LOW_JUMP_VELOCITY (SUB_PIXEL_TO_VELOCITY(QUARTER_BLOCK_SIZE + EIGHTH_BLOCK_SIZE))mzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · src/samus.c#L6758-L6776if (pData->yVelocity > gSamusPhysics.positiveYVelocityCap) { velocity = DIV_SHIFT(gSamusPhysics.positiveYVelocityCap, 8); } … else { velocity = DIV_SHIFT(pData->yVelocity, 8); } … if (pData->yVelocity >= -231) { …Checked by claude-agent, 2026-10-22 — a Python loop over the frames from take-off, velocity v from 192 (or 232): move by min(v, 192) >> 3 subpixels, then v -= 10, until the move is 0 or less; the rise sums to 235 and 331 subpixels, divided by 4 for pixels. It assumes nothing else touches yVelocity on the way up (no release, ceiling, or liquid)

Not yet measured in the ROM. The shift drops the fraction each frame, so the rise is a little less than v²/2g.

Cited by: Metroid: Zero Mission

On any frame Samus rises (yVelocity above 0) without A held, the mid-air handlers set yVelocity to 0, at any height: SamusMidAir, SamusTurningAroundMidAir, and SamusSpinning, which runs the spin jump, the Space Jump, and the Screw Attack. The check is each handler's last step, so a frame whose earlier branch returns, such as a Space Jump or wall jump press, skips it. Metroid lets a release stop the rise only after 32 px. mzm/release-cap

About: Metroid: Zero Mission Variable jump height

Value: 0 velocity after release

Codemzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · src/samus.c#L4572-L4578// Check turning if (turning) return SPOSE_TURNING_AROUND_MIDAIR; … // Check terminate Y velocity if not pressing A and going up if (!(gButtonInput & KEY_A) && pData->yVelocity > 0) pData->yVelocity = 0;mzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · src/samus.c#L4645-L4647// Check terminate Y velocity if not pressing A and going up if (!(gButtonInput & KEY_A) && pData->yVelocity > 0) pData->yVelocity = 0;mzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · src/samus.c#L4774-L4776// Check terminate Y velocity if not pressing A and going up if (!(gButtonInput & KEY_A) && pData->yVelocity > 0) pData->yVelocity = 0;mzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · src/samus.c#L36-L43[SPOSE_MIDAIR] = SamusMidAir, [SPOSE_TURNING_AROUND_MIDAIR] = SamusTurningAroundMidAir, … [SPOSE_STARTING_SPIN_JUMP] = SamusSpinning, [SPOSE_SPINNING] = SamusSpinning, … [SPOSE_SPACE_JUMPING] = SamusSpinning, [SPOSE_SCREW_ATTACKING] = SamusSpinning,mzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · src/samus.c#L4716-L4726if (gEquipment.suitMiscActivation & SMF_SPACE_JUMP && !gSamusPhysics.slowedByLiquid) { // Check can space jump if (gChangedInput & KEY_A && pData->yVelocity <= -SUB_PIXEL_TO_VELOCITY(EIGHTH_BLOCK_SIZE)) { … return SPOSE_NONE;metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2701-L2709SamusJump: LDA SamusJmpDsplcmnt BIT ObjVertSpeed BPL + ; branch if falling down CMP #$20 BCC + ; branch if jumped less than 32 pixels upwards BIT Joy1Status BMI + ; branch if JUMP button still pressed JSR StopVertMovement ;($D147)Stop jump (start falling).Checked by claude-agent, 2026-10-22 — read the three handlers' ends and the pose-handler table; the handler runs before SamusUpdateVelocityPosition in SamusUpdate, so a zeroed velocity moves Samus 0 that frame. The button is KEY_A in the code, not a reassignable one. Metroid's side is metroid-samus/release-cap

The Morph Ball's mid-air handler, SamusMorphballMidAir, has the same test inside one of its branches (src/samus.c line 5231), not read here in full.

Cited by: Metroid: Zero Mission, Variable jump height

When a spin jump or Screw Attack touches a wall, SamusCheckCollisions sets walljumpTimer to 8 and stores the direction away from the wall. Each time SamusSpinning runs, 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. mzm/wall-jump

About: Metroid: Zero Mission Wall jump

Value: 8 frames of the spin handler after the last wall touch

Codemzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · src/samus.c#L1109-L1112case SPOSE_SPINNING: case SPOSE_SCREW_ATTACKING: pData->walljumpTimer = 8; pData->lastWallTouchedMidAir = pData->direction ^ (KEY_RIGHT | KEY_LEFT);mzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · src/samus.c#L4716-L4751if (gEquipment.suitMiscActivation & SMF_SPACE_JUMP && !gSamusPhysics.slowedByLiquid) … else { // Check can wall jump if (pData->walljumpTimer != 0) { pData->walljumpTimer--; … // Holding correct direction and pressed A if (pData->direction & pData->lastWallTouchedMidAir) { …mzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · src/samus.c#L4760-L4763// Check turn if (gButtonInput & (OPPOSITE_DIRECTION(pData->direction))) { pData->direction ^= KEY_RIGHT | KEY_LEFT;mzm: a decompilation of Metroid: Zero Mission (metroidret/mzm) · src/samus.c#L1739-L1747// Perform wall jump, set spinning pData->pose = SPOSE_SPINNING; … if (pCopy->forcedMovement == FORCED_MOVEMENT_MID_AIR_JUMP) { if (pEquipment->suitMiscActivation & SMF_HIGH_JUMP) pData->yVelocity = SAMUS_HIGH_JUMP_VELOCITY; else pData->yVelocity = SAMUS_LOW_JUMP_VELOCITY;Checked by claude-agent, 2026-10-22 — read the touchingSideBlock switch in SamusCheckCollisions, SamusSpinning from its Space Jump test to the turn, and SamusSetMidAir's SPOSE_STARTING_WALL_JUMP case. Facing is pData->direction, which the turn at the end of SamusSpinning flips when the opposite direction is held, so in play the player holds away from the wall. HALF_BLOCK_SIZE + EIGHTH_BLOCK_SIZE is 32 + 8 = 40 subpixels. slowedByLiquid is set in liquid without the Gravity Suit or in a Metroid's grip (mzm/gravity); the half-speed liquid jump is lines 1750-1753. The no-wall-jump side is metroid-samus/no-air-jump

SamusStartingWallJump drops Samus instead if she fires or holds up or down without a side direction; in liquid the wall jump takes off at half the High Jump speed. While the timer runs and she faces away, SamusSpinning cuts her mid-air acceleration to 1.

Cited by: Metroid: Zero Mission, Wall jump