Claim set · data/claims/metroid-ii.yaml

Metroid II - Return of Samus (alex-west's M2RoS disassembly)

Game: Metroid II: Return of Samus.

alex-west's M2RoS disassembly of Metroid II, assembled with rgbds, equals Metroid II - Return of Samus (World) byte for byte. metroid-ii/build

CodeMetroid II - Return of Samus (World) · 0x184A-0x1898 — bank 0 $184A, jumpArcTable, the bytes the jump claims below readM2RoS: Return of Samus Disassembly · readme.md#L13The resultant file should have this hash: `md5: 9639948ad274fa15281f549e5f9c4d87`Checked by claude, 2026-10-21 — ran extract.py on the ROM and built with rgbds v1.0.1 (make all); out/M2RoS.gb has MD5 9639948ad274fa15281f549e5f9c4d87, and the ROM file has the same MD5 (SHA-1 74a2fad86b9a4c013149b1e214bc4600efb1066d)

Cited by: Metroid II: Return of Samus

A jump sets samus_jumpArcCounter to $31, or $21 with the Hi-Jump Boots. While A is held and the counter is below $40, poseFunc_jump lifts Samus 2 px each frame, 3 with the boots, and adds 1 to the counter: up to 15 frames, or 31. Letting go sets the counter to $56, which the comment calls the start of the arc's falling portion. Before this, poseFunc_jumpStart lifts her 2 to 3 px a frame for up to 6 frames while A is held. metroid-ii/jump-ascent

About: Metroid II: Return of Samus Variable jump height

Value
[
 15,
 31
]
CodeM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L3328-L3339; High jump parameters ld a, samus_jumpArrayBaseOffset - $1F ;$21 … ; Normal jump parameters ld a, samus_jumpArrayBaseOffset - $0F ;$31 ld [samus_jumpArcCounter], aM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L3884-L3903; Check if in linear portion of ascent ld a, [samus_jumpArcCounter] cp samus_jumpArrayBaseOffset … ; Set speed, subtracting an extra 1 from it if we have high jump … ; If A is not pressed, start falling portion of arc ld a, samus_jumpArrayBaseOffset + $16 ;56 ld [samus_jumpArcCounter], aM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L3937-L3940; Increment jump counter ld a, [samus_jumpArcCounter] inc a ld [samus_jumpArcCounter], aM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L4206-L4229poseFunc_jumpStart: ;{ 00:19E2 - $09 and $0A - Starting to jump ; Check if A is pressed … ; Move up 2 pixel/frame, with an extra pixel 2 out of 4 frames … ; Increment jump-start counter … ; Branch ahead if counter has expired cp $06M2RoS: Return of Samus Disassembly · SRC/constants.asm#L26def samus_jumpArrayBaseOffset = $40Checked by claude, 2026-10-21 — read the ground jump in poseFunc_standing, poseFunc_jumpStart (its counter stops the start pose at 6), and poseFunc_jump, which increments the counter after each move; $40 - $31 = 15 and $40 - $21 = 31

In water the jump adds $10 to the starting counter, so the held ascent is 16 frames shorter.

Cited by: Metroid II: Return of Samus

Past the held ascent, a jump follows a table: each frame poseFunc_jump moves Samus by the next entry of jumpArcTable, a signed whole number of pixels from 2 up to 3 down, and the $80 that ends the table starts a fall. metroid-ii/jump-arc

About: Metroid II: Return of Samus Jump

Value
[
 -2,
 3
]
CodeM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L3906-L3915; Get vertical speed from jumpArcTable sub samus_jumpArrayBaseOffset ld hl, jumpArcTable … ; Start falling pose if at the end of the table cp samus_jumpArrayBaseOffset + $40 ;$80 jr z, .startFallingM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L3927-L3928.moveVertical: call samus_moveVerticalM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L4857-L4860samus_moveVertical: ;{ 00:1D4E - move down ; Move up if negative bit 7, a jr nz, .moveUpM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L3991-L3999; Jump arc table ; - This starts being referenced when the jump counter is $40 … jumpArcTable: ;{ 00:184A - Jump arc table db $fe, $fe, $fe, $fe, $ff, $fe, $ff, $fe, $ff, $ff, $ff, $ff, $ff, $ff, $00, $ff … db $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $80Checked by claude, 2026-10-21 — read poseFunc_jump to samus_moveVertical, which moves by the signed value in A, and the 79-byte table

Cited by: Metroid II: Return of Samus

Walking has no speed variable to build up: samus_walkRight adds 1 or 2 px to Samus's X position on alternate frames (1.5 px/frame), 2 px/frame with the Varia Suit, and 1 px/frame in water. metroid-ii/walk

About: Metroid II: Return of Samus Running

Value: 1.5 px/frame

CodeM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L4596-L4618ld b, $01 ; Check if touching water … ; Varia walking speed ld b, $02 … ; Normal walking speed (1.5 px/f) ldh a, [frameCounter] and $01 add $01 ld b, a … …Checked by claude, 2026-10-21 — read samus_walkRight and samus_walkLeft, which add B to the X position directly

Cited by: Metroid II: Return of Samus

In a plain jump, poseFunc_jump moves Samus 1 px each frame toward a held direction, and not at all when neither is held. metroid-ii/air-control

About: Metroid II: Return of Samus Air control

Value: 1 px/frame

CodeM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L3953-L3967;moveHorizontal ; Move right if right is pressed ldh a, [hInputPressed] bit PADB_RIGHT, a jr z, .endIf_F call samus_moveRightInAir.turn .endIf_F: … ; Move left if left is pressed ldh a, [hInputPressed] bit PADB_LEFT, a jr z, .endIf_G …M2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L4780-L4788samus_moveRightInAir: ;{ 00:1CF5 … ; Set speed ld a, $01 ld b, aChecked by claude, 2026-10-21 — read the end of poseFunc_jump and both air movers

Running off a ledge puts Samus straight into the falling pose, and in that pose a jump press starts a jump only while samus_unmorphJumpTimer runs, the 16-frame window after she unmorphs in the air. metroid-ii/no-coyote-time

About: Metroid II: Return of Samus Coyote time

CodeM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L3362-L3367poseFunc_running: ;{ 00:14D6 - $03: Running ; Fall if ground is missing call collision_samusBottom jr c, .endIf_A ld a, pose_fallM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L3048-L3066poseFunc_fall: ;{ 00:12F5 - $07 - Falling ; Check if A was just pressed … ; Check if unmorph jump timer is non-zero ld a, [samus_unmorphJumpTimer] and a jr z, .endIf_AM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L3946-L3950call samus_unmorphInAir ld a, $10 ld [samus_unmorphJumpTimer], aM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L744-L749; Decrement unmorph jump timer ld a, [samus_unmorphJumpTimer] and a jr z, .endIf_B dec a ld [samus_unmorphJumpTimer], aChecked by claude, 2026-10-21 — read poseFunc_running's ground check and poseFunc_fall; the acid branch before the timer check is never taken, as the disassembly notes; the timer counts down once per main-loop frame

Cited by: Coyote time

Against the background, Samus is tested at points, one x for the side she moves toward and a list of up to five y offsets for her pose. Against enemies, collision_samusEnemies runs first and compares each enemy's hitbox with Samus's, whose top is set per pose. metroid-ii/hitbox

About: Metroid II: Return of Samus Hitbox

CodeM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L4981-L4996; Get offset for right side ldh a, [hSamusXPixel] add OAM_X_OFS + samusOriginX_toRight … ; Do sprite collision call collision_samusEnemies.horizontal … ; Get base address to the first entry for the pose's y offset listM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L5543-L5545collision_samusHorizontalYOffsetLists: ;{ 00:20FF - Y-Offset collision lists per pose ($80 terminated) ; Note: Due to limitations of the function that read this ; despite each row being 8 bytes long, only 5 offsets are supportedM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L9481collision_samusSpriteHitboxTopTable: ;{ 00:369B - Offset for the top of Samus's hitbox per pose (for sprite collisions)M2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L8708-L8714; Get hitbox pointer of enemy … ld hl, enemyHitboxPointersChecked by claude, 2026-10-21 — read collision_samusHorizontal and collision_samusOneEnemy, which loads each enemy's top, bottom, left, and right from its hitbox

Cited by: Hitbox

An enemy hit sets samusInvulnerableTimer to $33 (51), and while it is above 0 the hit code returns before any damage. drawSamus takes 1 from it each time it draws her, once per frame of play, and blinks her 4 frames on, 4 off. metroid-ii/i-frames

About: Metroid II: Return of Samus Invincibility frames

Value: 51 frames

CodeM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L7802-L7812; Exit if i-frames are active ld a, [samusInvulnerableTimer] and a ret nz … ; Give Samus i-frames ld a, $33 ld [samusInvulnerableTimer], aM2RoS: Return of Samus Disassembly · SRC/bank_001.asm#L560-L568drawSamus: ;{ 01:4BD9 Draw Samus … ; Check if damage frames are active ld a, [samusInvulnerableTimer] and a jr z, .endIf_A dec a ld [samusInvulnerableTimer], a ; 4 frames on, 4 frames offM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L740call drawSamus_longJump ; Draw SamusChecked by claude, 2026-10-21 — read the enemy-hit routine, drawSamus, and the main game loop, which calls drawSamus_longJump once per frame

Cited by: Metroid II: Return of Samus

A hit sends Samus away from the side of the enemy she touched along a fixed arc from .bombArcTable, 3 px a frame up at first, and 1 px a frame sideways. She can't change direction until the arc's counter reaches $56, which the comment calls the end of the rising portion. metroid-ii/knockback

About: Metroid II: Return of Samus Knockback

Value: -3 px/frame (first rise)

CodeM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L7824-L7836; Set travel direction to damage boost direction ld a, [samus_damageBoostDirection] ld [samusAirDirection], a … ; Set jump arc counter to base ld a, samus_jumpArrayBaseOffsetM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L8840-L8847; If Samus was on the left side of the enemy … ; If so, change the damage boost value to the left ld a, $ff ld [samus_damageBoostDirection], aM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L2439-L2442poseFunc_bombed: ;{ 00:0F6C - $11: Bombed (standing) ; Load y speed from bombArcTableM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L2469-L2470; Don't let Samus change aerial direction during the rising portion of the knockback cp samus_jumpArrayBaseOffset + $16 ; $56M2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L2525-L2529.bombArcTable: ; 00:0FF6 db $fd, $fd, $fd, $fd, $fe, $fd, $fe, $fd, $fe, $fe, $fe, $fe, $fe, $fe, $ff, $feM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L2491-L2495; Move right if applicable ld a, [samusAirDirection] cp $01 jr nz, .endIf_F call samus_moveRightInAir.noTurnM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L4785-L4788.noTurn: ; 00:1CFA Alternate entry ; Set speed ld a, $01 ld b, aChecked by claude, 2026-10-21 — read the hit routine, poseFunc_hurt (which falls through to poseFunc_bombed without a jump press), and poseFunc_bombed, which calls the no-turn air movers for 1 px/frame

Cited by: Metroid II: Return of Samus

During knockback a jump press clears samusInvulnerableTimer and starts a jump in the air with a ground jump's counter, $31 or $21. metroid-ii/knockback-jump

About: Metroid II: Return of Samus Knockback

CodeM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L2350-L2376poseFunc_hurt: ;{ 00:0EF7 - $0F - Knockback ; Go to "bombed" pose handler if jump is not pressed … ; Do a mid-air jump … ; Clear i-frames xor a ld [samusInvulnerableTimer], a … ld a, samus_jumpArrayBaseOffset - $1F ;$21 … ld a, samus_jumpArrayBaseOffset - $0F ;$31Checked by claude, 2026-10-21 — read poseFunc_hurt to its end, which then sets the jump-start pose (L2391)

Cited by: Metroid II: Return of Samus

A new game starts with 99 units of energy, no energy tanks, and 30 of 30 missiles. metroid-ii/start-health

About: Metroid II: Return of Samus Health upgrade

Value: 99 units

CodeM2RoS: Return of Samus Disassembly · SRC/data/initialSave.asm#L20-L25db $00 ; Samus' equipment … dw $0099 ; Samus' health dw $0030 ; Samus' max missiles dw $0030 ; Samus' missilesM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L9942-L9946pickup_missileTank: ;{ ; Add 10 to max missiles ld a, [samusMaxMissilesLow] add $10 daaChecked by claude, 2026-10-21 — read initialSave; health and missiles are binary-coded decimal, as the decimal adjust after adding $10 for 10 missiles shows

Cited by: Ammunition, Health upgrade

An energy tank adds a tank, up to 5, and fills Samus's energy, setting its high byte to the tank count and its low byte to 99. metroid-ii/energy-tank

About: Metroid II: Return of Samus Health upgrade

Value: 5 tanks at most

CodeM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L9895-L9907pickup_energyTank: ;{ ; Check if energy tanks are at max ld a, [samusEnergyTanks] cp $05 ; Max Energy tanks … ; Set current health to max ld [samusCurHealthHigh], a ld a, $99 ld [samusCurHealthLow], aChecked by claude, 2026-10-21 — read pickup_energyTank and pickup_energyRefill

Cited by: Health upgrade

A missile tank adds 10 to Samus's missile capacity and 10 to her missiles, each capped at 999. metroid-ii/missile-tank

About: Metroid II: Return of Samus Ammunition

Value: 10 missiles

CodeM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L9942-L9976pickup_missileTank: ;{ ; Add 10 to max missiles ld a, [samusMaxMissilesLow] add $10 daa … ; Clamp max missiles at 999 … ; Add 10 to current missiles … ; Clamp current missiles to 999Checked by claude, 2026-10-21 — read pickup_missileTank to its end

Cited by: Ammunition

The morph ball needs no item: a Down press while crouching calls samus_morphOnGround, and the item bits list bombs, Hi-Jump, Screw Attack, Space Jump, Spring Ball, Spider Ball, and Varia, with no bit for the ball. A new game starts with no item bits set. metroid-ii/morph-ball

About: Metroid II: Return of Samus Morph ball

CodeM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L3705-L3710; Handle down input ; Rising edge ldh a, [hInputRisingEdge] bit PADB_DOWN, a jr z, .endIf_L call samus_morphOnGroundM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L4524-L4527samus_morphOnGround: ;{ 00:1BA4 ; Set pose ld a, pose_morph ld [samusPose], aM2RoS: Return of Samus Disassembly · SRC/constants.asm#L49-L56def itemMask_bomb = %00000001 ; 01: Bombs … def itemMask_spring = %00010000 ; 10: Spring ball def itemMask_spider = %00100000 ; 20: Spider ball def itemMask_varia = %01000000 ; 40: Varia suit def itemMask_UNUSED = %10000000 ; 80: UnusedM2RoS: Return of Samus Disassembly · SRC/data/initialSave.asm#L20db $00 ; Samus' equipmentChecked by claude, 2026-10-21 — read poseFunc_crouch's down handling and samus_morphOnGround, which sets the pose with no item test

Cited by: Metroid II: Return of Samus, Morph ball

In the morph ball, A starts a jump only with the Spring Ball, from a counter of $2E. metroid-ii/spring-ball

About: Metroid II: Return of Samus Morph ball

CodeM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L3780-L3793; Handle spring ball ; Check if A is pressed ldh a, [hInputPressed] bit PADB_A, a jr z, .endIf_C ; Check if we have spring ball ld a, [samusItems] bit itemBit_spring, a jr z, .endIf_C ; Set jump parameter ld a, samus_jumpArrayBaseOffset - $12 ;$2eChecked by claude, 2026-10-21 — read poseFunc_morphBall; without the item, the ball only bounces after a fast landing

Cited by: Metroid II: Return of Samus, Morph ball

In a spin jump with the Space Jump, a new A press restarts the jump only on frames whose spaceJumpTable entry is nonzero: entries 44 to 63, where jumpArcTable falls 1 to 3 px a frame. The restart sets the counter to $28, or $18 with the Hi-Jump Boots, below $40, so a held A gives a new linear ascent. metroid-ii/space-jump

About: Metroid II: Return of Samus Space Jump

Value
[
 44,
 63
]
CodeM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L4002-L4011; Space Jump Table ; - $00 means no space jumping on that frame ; - Non-zero values mean that you can space jump on that frame … spaceJumpTable: ;{ 00:1899 … db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $02, $01, $02, $02 db $02, $02, $03, $02, $02, $03, $02, $02, $03, $02, $03, $02, $03, $02, $03, $02 db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $80M2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L3997-L3998db $00, $01, $01, $00, $01, $01, $01, $01, $01, $01, $02, $01, $02, $01, $02, $02 db $02, $02, $03, $02, $02, $03, $02, $02, $03, $02, $03, $02, $03, $02, $03, $02M2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L4014-L4078poseFunc_spinJump: ;{ 00:18E8 - $02: Spin jumping … ; If jump timer is > $40, then jump ahead ld a, [samus_jumpArcCounter] cp samus_jumpArrayBaseOffset jr nc, .endIf_B ; Handle linear ascent of the jump … ; Skip ahead if not holding jump ldh a, [hInputRisingEdge] bit PADB_A, a … …The atlas reads this differently: hInputRisingEdge holds only the buttons pressed this frame, so the code skips unless A was just pressed; holding A never restarts the jump.Checked by claude, 2026-10-21 — read poseFunc_spinJump; the comment says "if holding jump" but the code reads hInputRisingEdge, a new press. Entries 44-63 of jumpArcTable are steps of 1 to 3 px down

Only poseFunc_spinJump reads the table; a plain jump can't space jump.

Cited by: Metroid II: Return of Samus, Space Jump

With the Screw Attack, an enemy Samus touches in a spin jump or its start pose takes a Screw Attack weapon hit, and the contact doesn't hurt her. Solid enemies, whose damage entry is $FF, are exempt. metroid-ii/screw-attack

About: Metroid II: Return of Samus Screw Attack

CodeM2RoS: Return of Samus Disassembly · SRC/bank_000.asm#L8850-L8892; Check if screw attack is active ld a, [samusItems] bit itemBit_screw, a jr z, .iceCase ld a, [samusPose] cp pose_spinJump jr z, .screwCase ld a, [samusPose] cp pose_spinStart … ; Don't screw if damage is $FF (enemy is solid) … …Checked by claude, 2026-10-21 — read collision_samusOneEnemy from the hit test through .screwCase; a frozen enemy with an even ice counter is also skipped

Cited by: Screw Attack