Cite as
metroidret/mzm
Original
https://github.com/metroidret/mzm
Pinned
metroidret/mzm @ 2aae2896c38438eac4edd772e9f1f7af499616ed
Accessed
2026-10-22
Licence
MIT (the repo's LICENSE file, "Copyright 2025 YohannDR", which GitHub's API also reports). The README says building needs a baserom per region; the game code it rebuilds is Nintendo's.
Credit
The metroidret community's C decompilation of Metroid: Zero Mission. GitHub lists 14 contributors (2026-10-22), led in commit count by YohannDR, biosp4rk, testyourmine, 0xb01u, and kiliwily. Function, variable, and constant names and the comments quoted in mzm claims are theirs, not Nintendo's.
Notes
At the pinned commit the README counts 2718 of 2721 functions decompiled, the other three listed in docs/non_matching_functions.md; asm/ holds ten small files. Samus's physics are src/samus.c with constants in include/constants/samus.h; tank pickups are src/bg_clip.c, with the tank tables in src/data/block_data.c. The README's default build is mzm_us.gba, the North American release, with SHA-1 5de8536afe1f0078ee6fe1089f890e8c7aa0a6e8, the SHA-1 of the No-Intro file "Metroid - Zero Mission (USA).gba" (hashed 2026-10-22). Regional differences compile under REGION_ flags; BUGFIX blocks hold the decompilers' optional fixes, and the Makefile doesn't define BUGFIX. The Makefile defaults to REGION us and checks the build with sha1sum against mzm_us.sha1.

Cited on

Claims (16)

When SamusInit runs with no file loading (gIsLoadingFile clear) and an unnamed flag, gUnk_3000be3, clear, it copies sEquipment_Empty into gEquipment: 99 energy of 99, 10 missiles of 10, 10 power bombs of 10, and no weapon flags (MBF_NONE). The atlas reads this as a new game's start. Zero Mission starts with the same 99 energy, but with every ammunition count at 0.src/samus.c L8071–8088Code
An energy tank adds 100 to Samus's maximum energy and sets her energy to the new maximum, unless the new maximum would pass MAX_ENERGY_AMOUNT, 20 tanks plus the starting 99, or 2099. The tank code reads no difficulty. Zero Mission's tank also adds 100 and refills, or 50 on Hard, and stops at 12 tanks: 1299 on Easy and Normal and 699 on Hard (computed).src/bg_clip.c L531–537src/data/block_data.c L52–53src/data/block_data.c L60–81Code
Samus has one missile count and one power bomb count, each with a maximum. A missile tank adds 5 to both the missile count and its maximum, unless the maximum would pass 255; a power bomb tank adds 2 to both, up to 254. The missile types the downloads add (super, ice, and diffusion missiles, flags in weaponsStatus) draw on that one count. Zero Mission keeps separate counts for missiles, super missiles, and power bombs, and its missile tank also adds 5, or 2 on Hard.include/structs/samus.h L16–24src/data/block_data.c L67–84Code
A jump sets Samus's upward yVelocity to 170 (SAMUS_LOW_JUMP_VELOCITY), or 220 with the High Jump, with no separate suitless speed. The velocity counts eighths of a subpixel and a pixel is 4 subpixels, so these are 5.3125 and 6.875 px/frame (computed). Movement caps the velocity at 128 (16 subpixels, 4 px), so a jump's first 8 frames each rise 4 px, and a High Jump's first 16 (computed). Zero Mission's jump takes off at 192, or 232 with the High Jump, under a cap of 192: 6 px/frame from the first frame.include/constants/samus.h L336–338include/constants/samus.h L325Code
Out of liquid, SamusUpdatePhysics sets the vertical acceleration to 6 and the vertical speed cap to 128, and SamusUpdateVelocityPosition takes 6 from yVelocity on every frame of the airborne poses while the velocity is above -220, whether A is held or not: 0.1875 px/frame², with rises and falls both capped at 4 px/frame (computed). In water, lava, or acid without the Gravity Suit or the flag the decompilers name SMF_SA_X_SUIT, the acceleration drops to 4 and the cap to 48, 0.125 px/frame² and 1.5 px/frame. Zero Mission's gravity is 10, 0.3125 px/frame², with the same 4 px/frame fall cap (computed).include/constants/samus.h L324–327Code
Stepping the code's arithmetic with A held, out of liquid, a jump from the ground peaks about 71 px up (283 subpixels) on its 28th frame, and a High Jump 104 px (416 subpixels) on its 36th (computed: each frame moves yVelocity capped at 128 and shifted right 3, then takes 6 from it). The same stepping gives Zero Mission about 59 px on the 19th frame and 83 px on the 23rd (mzm/jump-height), so Fusion's jump is higher and slower.include/constants/samus.h L324–337src/samus.c L6758–6776Code
On any frame Samus rises (yVelocity above 0) without A held, the mid-air handlers set yVelocity to 0, at any height: SamusMidAir, SamusTurningAroundMidAir, SamusSpinning (which runs the spin jump, the Space Jump, and the Screw Attack), and SamusWallJumping, which also drops a wall jump into a spin. The test is each handler's last step but the wall jump's, so a frame whose earlier branch returns skips it. Zero Mission's first three handlers end with the same test.src/samus.c L4572–4578src/samus.c L4645–4647src/samus.c L4774–4776Code
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.README.md L9–12README.md L21mzm_us.sha1 L1Code
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.src/samus.c L8071–8088include/structs/samus.h L16–24Code
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.src/bg_clip.c L531–537src/data/block_data.c L52–53src/data/block_data.c L60–81Code
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.src/bg_clip.c L520–528src/bg_clip.c L539–558src/data/block_data.c L52–54src/data/block_data.c L67–84Code
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.src/samus.c L1863–1877src/samus.c L1700–1709include/constants/samus.h L336–338include/constants/samus.h L314–315include/types.h L47–65src/samus.c L6758–6776include/constants/samus.h L325Code
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.include/constants/samus.h L324–327src/samus.c L2649–2697src/samus.c L6762–6776Code
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).include/constants/samus.h L324–337src/samus.c L6758–6776Code
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.src/samus.c L4572–4578src/samus.c L4645–4647src/samus.c L4774–4776src/samus.c L36–43src/samus.c L4716–4726Code
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.src/samus.c L1109–1112src/samus.c L4716–4751src/samus.c L4760–4763src/samus.c L1739–1747Code