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

Metroid, Samus's movement (nmikstas's disassembly of the US NES release)

Game: Metroid.

Every jump takes off with the whole part of Samus's vertical speed at $FC, 4 px/frame up. The High Jump Boots change the gravity, not the speed: SetSamusJump sets SamusGravity to $18, or $12 with the boots. metroid-samus/jump-speed

About: Metroid Jump

Value: -4 px/frame

Codemetroid-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, 2026-10-21 — read SetSamusJump, which both the standing and the running jump call (LD002's lava branch and SamusRun's LCD40)

Cited by: Jump, Metroid

Each frame VertAccelerate adds SamusGravity to the fraction byte of Samus's vertical speed and carries into its whole part, so gravity is SamusGravity/256 px/frame²: $18 (0.09375) in a jump, $12 with the High Jump Boots, $1A after walking off a ledge, and $38 after a hit (computed: 0.0703125, 0.1015625, 0.21875). A fall is capped at 5 px/frame and a rise at 6. metroid-samus/gravity

About: Metroid Gravity

Value
{
 "jump": 0.09375,
 "highJump": 0.0703125,
 "fall": 0.1015625,
 "hit": 0.21875,
 "maxFall": 5,
 "maxRise": 6
}
Codemetroid-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#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#L2440-L2443* lda #$FD sta ObjVertSpeed lda #$38 ;Samus is hit. Store Samus hit gravity. sta SamusGravity ;metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L5606-L5616LE3A0: lda #$1A ;Samus is falling. Store falling gravity value. LE3A2: sta SamusGravity ; … LE3A5:* ldx #$05 ;Load X with maximum downward speed. LE3A7: lda VertCntrLinear ; LE3AA: clc ;The higher the gravity, the faster this addition overflows LE3AB: adc SamusGravity ;and the faster ObjVertSpeed is incremented. LE3AE: sta VertCntrLinear ; LE3B1: lda ObjVertSpeed ;Every time above addition sets carry bit, ObjVertSpeed is LE3B4: adc #$00 ;incremented. This has the effect of speeding up a fallmetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L5620-L5633LE3BB: lda #$00 ; LE3BD: cmp VertCntrLinear ;Sets carry bit. LE3C0: sbc ObjVertSpeed ;Subtract ObjVertSpeed to see if maximum speed has LE3C3: cmp #$06 ;been exceeded. LE3C5: ldx #$FA ;Load X with maximum upward speed. … LE3C9:* cmp #$05 ;Has maximum downward speed been reached? LE3CB:* bcc + ;If not, branch. … LE3CD: jsr StopVertMovement ;($D147)Clear verticle movement data. LE3D0: stx ObjVertSpeed ;Set Samus vertical speed to max.Checked by claude, 2026-10-25 — read the jump's gravity store at LCFF3 ($18, or $12 with gr_HIGHJUMP) and the hit's ($38 after ObjVertSpeed $FD), then VertAccelerate to its end. Rising (L5617-L5633), 0 − speed ≥ 6 loads $FA and stores it as the whole speed with the fraction cleared, so a rise is capped at 6 px/frame; falling, the cap is 5. The $1A store runs only when Samus is grounded and nothing is below her. Neither SamusJump nor SamusRun writes SamusGravity while she is airborne, so the jump button doesn't change it

Cited by: Metroid

Once a jump has carried Samus 32 px up (SamusJmpDsplcmnt at $20), letting go of jump while she still rises calls StopVertMovement, which sets her vertical speed to 0. The running-jump handler does the same past 32 px. metroid-samus/release-cap

About: Metroid Variable jump height

Value: 32 px risen before a release counts

Codemetroid-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).metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2271-L2280* cpy #$20 bcc ++ … * bit Joy1Status bmi + jsr StopVertMovement ;($D147)metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2867-L2870StopVertMovement: LD147: ldy #$00 sty ObjVertSpeed sty VertCntrLinearChecked by claude, 2026-10-21 — read SamusJump and SamusRun's airborne branch, which reaches the cpy #$20 test only while Samus rises (bit ObjVertSpeed / bmi)

Cited by: Metroid, Variable jump height

On the ground Samus accelerates at $30/256 (0.1875) px/frame² toward SamusHorzSpdMax/16 px/frame, which VertAccelerate sets to $18 (1.5 px/frame) while she is grounded. With no direction held, StopHorzMovement clears her horizontal speed at once. metroid-samus/run

About: Metroid Running

Value
{
 "accel": 0.1875,
 "max": 1.5
}
Codemetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2245-L2247RunAccelerationTbl: LCCC0: .byte $30 ;Accelerate right. .byte $D0 ;Accelerate left.metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L5590-L5593LE37A: lda SamusGravity ;Is Samus rising or falling? LE37D: bne ++ ;Branch if yes. LE37F: lda #$18 ; LE381: sta SamusHorzSpdMax ;Set Samus maximum running speed.metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L5648-L5690HorzAccelerate: LE3E5: lda SamusHorzSpdMax jsr Amul16 ; * 16 … jsr Adiv16 ; / 16 … lda HorzCntrLinear clc adc SamusHorzAccel … lda $00 sta HorzCntrLinear …metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2316-L2319* lda Joy1Status and #$03 bne + jsr LCF55metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2600-L2666ClearHorzMvmntData: LCF4C: LDY #$00 ; STY ObjHorzSpeed ;Set Samus Horizontal speed and horizontal STY HorzCntrLinear ;linear counter to #$00. … StopHorzMovement: … LCF5D: JSR NoHorzMoveNoDelay ;($CF81)Clear horizontal movement and animation delay data. … LCF81: JSR ClearHorzData ;($CFB7)Clear all horizontal movement data. … ClearHorzData: …Checked by claude, 2026-10-21 — read SetSamusRun, SamusRun's grounded branch, and HorzAccelerate, which clamps the speed to $01.$80 (whole.fraction) for a maximum of $18: 1.5 px/frame

The accelerations store whole.fraction in two bytes, ObjHorzSpeed and HorzCntrLinear, as the vertical speed does.

Cited by: Metroid

A running jump sets the top speed to $12 (1.125 px/frame). In the air a held direction sets the acceleration toward it; with neither held, a jump still in the plain jump animation loses its horizontal speed, and a somersault keeps its speed and acceleration. metroid-samus/air-run

About: Metroid Air control

Value: 1.125 px/frame

Codemetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2305-L2309lda Joy1Change bpl + ; branch if JUMP not pressed LCD40: jsr LCFC3 lda #$12 sta SamusHorzSpdMaxmetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2286-L2290* lda SamusInLava … * jsr LCF88metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2642-L2667LCF88: LDA Joy1Status AND #$03 BEQ + JSR BitScan ;($E1E1) TAX JSR LCCB7 … * LDA SamusGravity BMI + BEQ + LDA AnimResetIndex CMP #an_SamusJump …Checked by claude, 2026-10-21 — read SamusRun's airborne branch, LCF88, and LCCB7, which stores RunAccelerationTbl's entry in SamusHorzAccel

Cited by: Metroid

In a jump from a standstill, LD055 sets the whole part of Samus's horizontal speed outright every frame, 1 px/frame toward a held direction and 0 with neither held. metroid-samus/air-stand

About: Metroid Air control

Value: 1 px/frame

Codemetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2738-L2767LD055: ldx #$01 ldy #$00 lda Joy1Status lsr bcs + ; branch if RIGHT pressed dex lsr bcc ++++ ; branch if LEFT not pressed dex … * stx ObjHorzSpeedmetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2710-L2711* JSR LD055 JSR LCF2EChecked by claude, 2026-10-21 — read SamusJump and LD055; the fourth anonymous label after `bcc ++++` is the `stx ObjHorzSpeed`, with X decremented to 0

X is $FF, 1 px/frame left, with left held.

Cited by: Metroid

Once 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: VertAccelerate sets the falling gravity on the first frame with nothing below her. metroid-samus/no-air-jump

About: Metroid Coyote time

Codemetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2252-L2255SamusRun: LCCC2: ldx SamusDir lda SamusGravity beq +++++++metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2286-L2289* lda SamusInLava beq + lda Joy1Change bmi LCD40 ; branch if JUMP pressedmetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2719-L2724LDA SamusInLava BEQ + LDA Joy1Change BPL + ; branch if JUMP not pressed JSR LCFC3metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L5590-L5607LE37A: lda SamusGravity ;Is Samus rising or falling? … LE38F: jsr CheckMoveDown ;($E7AD)Is Samus obstructed downwards? … LE3A0: lda #$1A ;Samus is falling. Store falling gravity value. LE3A2: sta SamusGravity ;Checked by claude, 2026-10-21 — read SamusRun's airborne branch (SamusGravity nonzero) to its end at `bne SetSamusData`, and SamusJump; the grounded jump read (`lda Joy1Change / bpl +` before LCD40) is reached only through the `beq` taken when SamusGravity is 0

The atlas hasn't read the pointing-up and morph-ball handlers for jump reads in the air; the ball's jump press unrolls it (metroid-samus/morph-ball).

Cited by: Coyote time, Metroid, Metroid: Zero Mission, Wall jump

Samus is a box around her center: each animation frame's data sets ObjRadY and ObjRadX, the distances from her center to her top or bottom and to her sides. The level checks add these radii to her position, and so does the distance check between her and an enemy. metroid-samus/hitbox

About: Metroid Hitbox

Codemetroid-disassembly: Metroid software disassembly · Source_Files/Metroid_Defines.asm#L287-L288.alias ObjRadY $0301 ;Distance in pixels from object center to top or bottom. .alias ObjRadX $0302 ;Distance in pixels from object center to left or right side.metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L4810-L4816LDEC1: sta ObjRadY,x ;Get verticle radius in pixles of object. … LDEC7: lda ($00),y ;Get horizontal radius in pixels of object. LDEC9: sta ObjRadX,x ;metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L5594-L5597LE384: lda ObjectY ; LE387: clc ; LE388: adc ObjRadY ;Check is Samus is obstructed downwards on y roommetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L5981-L5987MoveSamusLeft: LE626: lda ObjectX sec sbc ObjRadX and #$07 bne + ; only call crash detection every 8th pixel jsr CheckMoveLeft ; check if player is obstructed to the LEFTmetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L7802-L7806DistFromObj0ToEn1: LF1B3: lda ObjRadY,x jsr LF1E7 lda ObjRadX,xChecked by claude, 2026-10-21 — read the frame-data reader, VertAccelerate's ground test, MoveSamusLeft, and the distance helpers, which add the enemy's EnRadY and EnRadX to Samus's radii

Cited by: Hitbox

Samus rolls into the ball only with the Maru Mari (gr_MARUMARI) and only on the ground. In the ball, Up or a jump press unrolls her unless Down is held, and only if she has room to stand. metroid-samus/morph-ball

About: Metroid Morph ball

Codemetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2794-L2799SetSamusRoll: LD0B5: lda SamusGear and #gr_MARUMARI beq + ; branch if Samus doesn't have Maru Mari lda SamusGravity bne +metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2820-L2834SamusRoll: lda Joy1Change and #$08 ; UP pressed? bne + ; branch if yes bit Joy1Change ; JUMP pressed? bpl ++ ; branch if no * lda Joy1Status and #$04 ; DOWN pressed? bne + ; branch if yes ;break out of "ball mode" … jsr CheckMoveUpChecked by claude, 2026-10-21 — read SetSamusRoll and SamusRoll; CheckMoveUp's failure branch keeps the ball

Cited by: Morph ball

IsScrewAttackActive counts the Screw Attack as on only in the running state with the item: in a somersault, or in the plain jump animation while Samus still rises. The Samus-enemy crash code at LF282 calls it. metroid-samus/screw-attack

About: Metroid Screw Attack

Codemetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2362-L2379IsScrewAttackActive: LCD9C: SEC ;Assume screw attack is not active. LCD9D: LDY ObjAction ; LCDA0: DEY ;Is Samus running? LCDA1: BNE ++ ;If not, branch to exit. LCDA3: LDA SamusGear ; LCDA6: AND #gr_SCREWATTACK ;Does Samus have screw attack? LCDA8: BEQ ++ ;If not, branch to exit. LCDAA: LDA AnimResetIndex ; LCDAD: CMP #an_SamusSalto ;Is Samus summersaulting? LCDAF: BEQ + ;If so, branch to clear carry(screw attack active). LCDB1: CMP #an_SamusJump ; …metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L7935-L7937LF282: bcs Exit17 jsr LF2E8 jsr IsScrewAttackActive ;($CD9C)Check if screw attack active.metroid-disassembly: Metroid software disassembly · Source_Files/Metroid_Defines.asm#L865-L866.alias sa_Run 1 ;Also run and jump. .alias sa_Jump 2Checked by claude, 2026-10-21 — read IsScrewAttackActive; a running jump keeps ObjAction at sa_Run (1), and a standing jump uses sa_Jump (2)

What LF282 does with the result is uncommented in the disassembly, and the atlas hasn't traced it.

Cited by: Screw Attack

Samus's gear byte, SamusGear, has one bit each for the bombs, High Jump, Long Beam, Screw Attack, Maru Mari, Varia, Wave Beam, and Ice Beam: all eight bits, none for a Space Jump. metroid-samus/gear-bits

About: Metroid Space Jump

Codemetroid-disassembly: Metroid software disassembly · Source_Files/Metroid_Defines.asm#L853-L861;Bitmask defs used for SamusGear. .alias gr_BOMBS $01 .alias gr_HIGHJUMP $02 .alias gr_LONGBEAM $04 .alias gr_SCREWATTACK $08 .alias gr_MARUMARI $10 .alias gr_VARIA $20 .alias gr_WAVEBEAM $40 .alias gr_ICEBEAM $80metroid-disassembly: Metroid software disassembly · Source_Files/Metroid_Defines.asm#L584.alias SamusGear $6878 ;Stores power-up items Samus has.Checked by claude, 2026-10-21 — read the gear bitmask definitions; missiles and energy tanks are counts kept elsewhere (MaxMissiles, TankCount)

Cited by: Space Jump

Each frame, the handler for Samus's state (standing, running, jumping) reads the pad first and then calls SetSamusData, which reaches LavaAndMoveCheck. That routine accelerates and moves her vertically (VertAccelerate, then one pixel at a time), and then horizontally (HorzAccelerate, then one pixel at a time). metroid-samus/frame-order

Codemetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2142-L2151GoSamusHandler: LCC1A: LDA ObjAction ; LCC1D: BMI SamusStand ;Branch if Samus is standing. LCC1F: JSR ChooseRoutine ;($C27C)Goto proper Samus handler routine. … LCC22: .word SamusStand ;($CC36)Standing. LCC24: .word SamusRun ;($CCC2)Running. LCC26: .word SamusJump ;($D002)Jumping.metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2333-L2343SetSamusData: LCD6D: JSR UpdateObjAnim ;($DC8F)Update animation if needed. … LCD81: JSR LavaAndMoveCheck ;($E269)Check if Samus is in lava or moving.metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L5452-L5456LE2A6:* iny ;Set Samus lava status. LE2A7: sty SamusInLava ; SamusMoveVertically: LE2A9: jsr VertAccelerate ;($E37A)Calculate vertical acceleration.metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L5471-L5472LE2C2:* sta ObjectCounter ;Store number of pixels to move Samus this frame. LE2C4:* jsr MoveSamusUp ;($E457)Attempt to move Samus up 1 pixel.metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L5518-L5521LE318: bne ---- ;Branch if Samus needs to be moved another pixel. SamusMoveHorizontally: LE31A: jsr HorzAccelerate ;($E3E5)Horizontally accelerate Samus.Checked by claude, 2026-10-25 — read GoSamusHandler, the ends of SamusStand, SamusRun, and SamusJump (each jumps to SetSamusData), SetSamusData, and LavaAndMoveCheck, which falls through into SamusMoveVertically and then SamusMoveHorizontally

Cited by: Metroid

Samus's speeds are 8.8 fixed point: a whole byte, ObjVertSpeed or ObjHorzSpeed, and a fraction, VertCntrLinear or HorzCntrLinear. Her position's fraction is one more byte per axis, VertCntrNonLinr or HorzCntrNonLinr. Each frame the speed's fraction is added to it, and she moves the speed's whole part plus the carry, in pixels. The comments call that byte a counter that grows exponentially; in the code it is the fraction of her position. metroid-samus/subpixels

Value: 256 steps per px

Codemetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L5637-L5643LE3D3:* lda VertCntrNonLinr ; LE3D6: clc ;This function adds itself plus the linear verticle counter LE3D7: adc VertCntrLinear ;onto itself every frame. This causes the non-linear LE3DA: sta VertCntrNonLinr ;counter to increase exponentially. This function will LE3DD: lda #$00 ;cause Samus to reach maximum speed first in most LE3DF: adc ObjVertSpeed ;situations before the linear counter. LE3E2: sta $00 ;$00 stores temp copy of current verticle speed.The atlas reads this differently: The byte is the fraction of Samus's vertical position: each frame the speed's fraction is added to it, and the carry adds a pixel to the move. Nothing here grows exponentially.metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L5691-L5697* lda HorzCntrNonLinr clc adc HorzCntrLinear sta HorzCntrNonLinr lda #$00 adc ObjHorzSpeed sta $00 ;$00 stores temp copy of current horizontal speed.metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L5471-L5472LE2C2:* sta ObjectCounter ;Store number of pixels to move Samus this frame. LE2C4:* jsr MoveSamusUp ;($E457)Attempt to move Samus up 1 pixel.Checked by claude, 2026-10-25 — read the ends of VertAccelerate and HorzAccelerate and the move loops, which take $00 as the pixel count (its two's complement when negative); VertCntrNonLinr and HorzCntrNonLinr are written nowhere else in the disassembly

Cited by: Metroid

From a standstill, the first frame with Left or Right held doesn't move Samus. SamusStand picks the running state, calls SetSamusData, which moves her at her speed of 0, and only then calls SetSamusRun, which sets her acceleration. Her speed rises from the next frame. metroid-samus/run-start

About: Metroid Running

Codemetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2162-L2199SamusStand: LCC36: LDA Joy1Status ;Status of joypad 1. LCC38: AND #$CF ;Remove SELECT & START status bits. LCC3A: BEQ + ;Branch if no buttons pressed. LCC3C: JSR ClearHrztAnimData ;($CF5D)Set no horiontal movement and single frame animation. … LCC4B:* JSR BitScan ;($E1E1)Find which directional button is pressed. … LCC52: STA SamusDir ;1=left, 0=right. LCC54:* TAX ; LCC55: LDA ActionTable,x ;Load proper Samus status from table below. LCC58: STA ObjAction ;Save Samus status. …metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2236-L2238ldx SamusDir LCCB7: lda RunAccelerationTbl,x sta SamusHorzAccelChecked by claude, 2026-10-25 — read SamusStand and SetSamusRun; ClearHrztAnimData, run for any button held, zeroes the speed and the acceleration first

Cited by: Metroid

Running on the ground, Left or Right against Samus's facing turns her and sets the acceleration toward the new side on that frame, through SetSamusRun, but leaves her speed as it is. She slows by 0.1875 px/frame each frame, passes 0, and speeds up the other way: from 1.5 px/frame, 16 frames to 1.5 px/frame the other way (computed). metroid-samus/turn

About: Metroid Running

Value: 16 frames

Codemetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2316-L2326* lda Joy1Status and #$03 bne + jsr LCF55 jmp LCD6B * jsr BitScan ;($E1E1) cmp SamusDir beq LCD6B sta SamusDir jsr LCC98metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2236-L2247ldx SamusDir LCCB7: lda RunAccelerationTbl,x sta SamusHorzAccel … LCCC0: .byte $30 ;Accelerate right. .byte $D0 ;Accelerate left.metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L5658-L5661lda HorzCntrLinear clc adc SamusHorzAccel sta HorzCntrLinearChecked by claude, 2026-10-25 — read SamusRun's grounded branch and SetSamusRun (LCC98), which writes the acceleration and the animation but not ObjHorzSpeed or HorzCntrLinear; HorzAccelerate adds the signed acceleration to the speed

Cited by: Metroid

On the ground, the running handler checks Samus's animation before it reads A or the d-pad (LCDBF). Unless it is the running animation (or, with Up held, running and aiming up), it sets that animation and skips the rest of the handler for the frame. A jump press or a released d-pad on that frame is ignored, and she accelerates toward her facing. That happens on her first frame on the ground after a running jump or a fall, and on the frame after a turn: SetSamusRun gives Samus the running animation only if her animation was standing (an_SamusStand), and otherwise the running-and-aiming-up animation (an_SamusRunPntUp). metroid-samus/run-pose

About: Metroid Running

Codemetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2295-L2298* lda SamusOnElevator bne + jsr LCCB7 * jsr LCDBFmetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2383-L2395LCDBF: lda Joy1Status and #$08 lsr lsr lsr tax lda LCCBE,x cmp AnimResetIndex beq - jsr SetSamusAnim pla pla …metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2225-L2243ldx #$00 lda AnimResetIndex cmp #an_SamusStand beq + inx cmp #$27 beq + lda #$04 jsr SetSamusNextAnim * lda RunAnimationTbl,x sta AnimResetIndex … …Checked by claude, 2026-10-25 — read SamusRun's grounded branch, LCDBF (its `beq -` reaches the `rts` that ends IsScrewAttackActive, and its two `pla` drop the return to SamusRun), and SetSamusRun, where only an_SamusStand keeps X at 0 (an_SamusRun); $27, an_SamusPntUp in Metroid_Defines.asm, branches after the `inx`, so it gets X = 1 (an_SamusRunPntUp) like every other animation. The jump press, the fire press, and the d-pad are read after the call

The conformance probe (probes/lab/conformance.mjs) plays turns and landings in the ROM and matches the model, which skips those frames' reads.

Cited by: Metroid

A jump from a standstill starts after the press frame's move: SamusStand calls SetSamusData, which moves her, and then SetSamusJump, so she first rises on the next frame. A running jump's handler calls SetSamusJump (LCD40) before SetSamusData, so she rises on the press frame, and there it sets her top speed for the jump, SamusHorzSpdMax, to $12. metroid-samus/jump-start

About: Metroid Jump

Codemetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2185-L2200LCC65:* BIT Joy1Change ;Check if jump was just pressed. LCC67: BPL + ;Branch if JUMP not pressed. LCC69: LDA #sa_Jump ; LCC6B: STA ObjAction ;Set Samus status as jumping. LCC6E:* LDA #$04 ;Prepare to set animation delay to 4 frames. LCC70: JSR SetSamusData ;($CD6D)Set Samus control data and animation. … LCC7A: JSR ChooseRoutine ;Select routine below. … LCC81: .word SetSamusJump ;($CFC3)Samus is jumping.metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2304-L2310* jsr LCF2E lda Joy1Change bpl + ; branch if JUMP not pressed LCD40: jsr LCFC3 lda #$12 sta SamusHorzSpdMax jmp LCD6BChecked by claude, 2026-10-25 — read SamusStand and SamusRun's grounded branch; LCD6B loads the animation delay and falls into SetSamusData

Cited by: Metroid

In a running jump, the air branch of the running handler poses Samus by SamusJmpDsplcmnt, which a jump sets to 0 and each pixel up adds 1 to and each pixel down takes 1 from. Rising at 24 or more (cpy #$18), she somersaults (an_SamusSalto) unless she is firing; falling at less than 24, she takes the plain jump pose (an_SamusJump), as she does from the running pose. The pose decides whether letting go of the d-pad stops her (metroid-samus/air-run). metroid-samus/somersault

About: Metroid Air control

Value: 24 px

Codemetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2253-L2270LCCC2: ldx SamusDir lda SamusGravity beq +++++++ ldy SamusJmpDsplcmnt bit ObjVertSpeed bmi + cpy #$18 bcs ++++ lda #an_SamusJump sta AnimResetIndex bcc ++++ ; branch always * cpy #$18 …metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2281-L2285* lda #an_SamusRun cmp AnimResetIndex bne + lda #an_SamusJump sta AnimResetIndexmetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L5744-L5745* dec ObjectY inc SamusJmpDsplcmntmetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L5783-L5784* inc ObjectY dec SamusJmpDsplcmntChecked by claude, 2026-10-25 — read SamusRun's airborne branch with its anonymous labels counted, SetSamusJump (which stores 0 in SamusJmpDsplcmnt), and the ends of MoveSamusUp and MoveSamusDown; the compares are unsigned

Cited by: Metroid

Moving down, and not in the ball, Samus stops when MoveSamusDown finds a solid tile under her: StopVertMovement clears her vertical speed, SamusGravity is set to 0, and the frame goes on to her horizontal move. A jump from a standstill ends on the next frame: SamusJump finds SamusGravity at 0 and calls StopHorzMovement, which stops her and makes her stand, so she doesn't move that frame, and a jump press then does nothing, since the jumping handler starts a jump only in lava. In the ball (sa_Roll), a landing halves her downward speed and turns it upward, a bounce, until the halved whole speed is 0 and she stops. metroid-samus/landing

About: Metroid Jump

Codemetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L5491-L5493LE2E1:* sta ObjectCounter ;Store number of pixels to move Samus this frame. LE2E3:* jsr MoveSamusDown ;($E4A3)Attempt to move Samus 1 pixel down. LE2E6: bcs +++ ;Branch if Samus successfully moved down 1 pixel.metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L5511-L5515;Samus has hit the ground after moving downwards. LE30B:* jsr SFXSamusWalk ;($CB96)Play walk SFX. LE30E:* jsr StopVertMovement ;($D147)Clear vertical movement data. LE311: sty SamusGravity ;Clear Samus gravity value. LE314: beq SamusMoveHorizontally ;($E31A)Attempt to move Samus left/right.metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L5496-L5500LE2E8: lda ObjAction ; LE2EB: cmp #sa_Roll ;Is Samus rolled into a ball? LE2ED: bne + ;If not, branch. LE2EF: lsr ObjVertSpeed ;Divide verticle speed by 2. LE2F2: beq ++ ;Speed not fast enough to bounce. branch to skip.metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2719-L2736LDA SamusInLava BEQ + LDA Joy1Change BPL + ; branch if JUMP not pressed JSR LCFC3 JMP LCD6B * LDA SamusGravity BNE ++ … * JSR LCF55 * LDA #$03 JMP SetSamusData ;($CD6D)Set Samus control data and animation.Checked by claude, 2026-10-25 — read the downward move loop, its ball branch (L5496-L5509: a halved speed of 0 skips to StopVertMovement, any other is negated, a bounce), and SamusJump's end; LCF55 falls into ClearHrztAnimData, which zeroes the horizontal speed and acceleration and stores 0 (sa_Stand) in ObjAction before SetSamusData moves her

In Brinstar's bank, the frames of Samus's running, standing, jumping, and somersault animations all give the radii $0F and $04: 15 px from her center to her top or bottom and 4 px to either side, so her box is 30 px tall and 8 wide (computed). metroid-samus/terrain-box

About: Metroid Hitbox

Value
{
 "x": 4,
 "y": 15
}
Codemetroid-disassembly: Metroid software disassembly · Source_Files/Bank01.asm#L679-L701;Samus run animation. L8572: .byte $03, $04, $05, $FF … ;Samus Stand animation. L8579: .byte $08, $FF … ;Samus Jump animation. L857E: .byte $10, $FF … ;Samus summersault animation. L8580: .byte $17, $18, $19, $1A, $FFmetroid-disassembly: Metroid software disassembly · Source_Files/Bank01.asm#L789-L793FramePtrTable: L860B: .word $87CB, $87CB, $87CB, $87CB, $87DD, $87F0, $8802, $8802 L861B: .word $8818, $882C, $882C, $882C, $882C, $883E, $8851, $8863 L862B: .word $8863, $8874, $8874, $8885, $8885, $8885, $8885, $8885 L863B: .word $888F, $8899, $88A3, $88AD, $88B8, $88C3, $88CE, $88D9metroid-disassembly: Metroid software disassembly · Source_Files/Bank01.asm#L1157-L1161;current frame. The second byte is saved as the object's y radius and the third byte is saved ;as the object's x radius. … ;Samus run. L87CB: .byte $40, $0F, $04, $00, $01, $FD, $20, $FE, $41, $40, $FD, $60, $20, $21, $FE, $FEmetroid-disassembly: Metroid software disassembly · Source_Files/Bank01.asm#L1176-L1177;Samus stand. L8818: .byte $40, $0F, $04, $FD, $20, $0E, $0D, $FE, $1E, $1D, $2E, $2D, $FE, $FD, $60, $3Bmetroid-disassembly: Metroid software disassembly · Source_Files/Bank01.asm#L1192-L1210;Samus stand and jump. L8863: .byte $40, $0F, $04, $00, $01, $FD, $20, $FE, $41, $40, $FD, $60, $22, $07, $08, $32 … ;Samus summersault. L8885: .byte $41, $0F, $04, $52, $53, $62, $63, $72, $73, $FF … ;Samus summersault. L888F: .byte $42, $0F, $04, $54, $55, $56, $64, $65, $66, $FF … ;Samus summersault. L8899: .byte $81, $0F, $04, $52, $53, $62, $63, $72, $73, $FF … …Checked by claude, 2026-10-25 — followed an_SamusRun ($00), an_SamusStand ($07), an_SamusJump ($0C), and an_SamusSalto ($0E) into ObjectAnimIdxTbl, their frames ($03-$05, $08, $10, $17-$1A) into FramePtrTable, and read each frame's second and third bytes; the frame reader at LDEBC stores them in ObjRadY and ObjRadX (metroid-samus/hitbox)

The other area banks carry their own copies of these tables; the atlas has read only Brinstar's.

Cited by: Metroid

Samus moves one pixel at a time, and a step tests the room's 8 px tiles only when the edge she moves toward lies on a tile boundary: MoveSamusUp, MoveSamusDown, MoveSamusLeft, and MoveSamusRight call the crash check only when her center less or plus her radius is a multiple of 8. The check tests the row of tiles above her top or below her bottom, or the column beside her side, across every tile her box spans. On the ground, VertAccelerate makes the same test under her each frame. metroid-samus/tile-checks

Value: 8 px per tile

Codemetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L5713-L5720MoveSamusUp: LE457: lda ObjectY ;Get Samus' y position in room. sec ; sbc ObjRadY ;Subtract Samus' vertical radius. LE45E: and #$07 ;Check if result is a multiple of 8. If so, branch to LE460: bne + ;Only call crash detection every 8th pixel. LE462: jsr CheckMoveUp ;($E7A2)Check if Samus obstructed UPWARDS.metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L5751-L5757MoveSamusDown: lda ObjectY clc adc ObjRadY and #$07 bne + ; only call crash detection every 8th pixel jsr CheckMoveDown ; check if Samus obstructed DOWNWARDSmetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L6215-L6229CheckMoveUp: LE7A2: ldx PageIndex lda ObjRadY,x clc adc #$08 jmp + CheckMoveDown: ldx PageIndex lda #$00 sec sbc ObjRadY,x * sta $02 …metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L6234-L6245* sta $03 tay ldx #$00 lda $09 sec sbc $03 and #$07 beq + inx * jsr LE8CE sta $04 jsr LE90Fmetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L6280-L6283* dex beq + jsr LE98E jmp LE7E6metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L6341-L6352CheckMoveLeft: ldx PageIndex lda ObjRadX,x clc adc #$08 jmp + CheckMoveRight: ldx PageIndex lda #$00 sec sbc ObjRadX,xmetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L5594-L5600LE384: lda ObjectY ; LE387: clc ; LE388: adc ObjRadY ;Check is Samus is obstructed downwards on y room LE38B: and #$07 ;positions divisible by 8(every 8th pixel). LE38D: bne + ; LE38F: jsr CheckMoveDown ;($E7AD)Is Samus obstructed downwards? LE392: bcc ++ ;Branch if yes.Checked by claude, 2026-10-25 — read the four one-pixel moves, the four checks, LE8CE (the count of 8 px tiles the box spans from its first edge, one more when that edge is mid-tile), LE90F (the row or column: center less the offset), and the loop at LE7E6, which steps 8 px along the row or column per tile; MakeCartRAMPtr drops each coordinate's low 3 bits

Up tests the row 8 px above her top edge (the offset ObjRadY+8), down the row at her center plus ObjRadY, left the column 8 px past ObjRadX, right the column at her center plus ObjRadX; with an 8 px tile, each is the tile next to her edge when that edge is on a boundary.

Cited by: Metroid

On the ground, VertAccelerate sets SamusHorzSpdMax to $18 and tests the tiles under Samus before she moves. With none solid, and no elevator or frozen enemy under her, it sets the falling gravity, $1A, and adds it at once, so she is airborne from that frame. The running handler's air branch then turns her running pose into the plain jump pose, so letting go of the d-pad stops her (metroid-samus/air-run), and her top speed stays 1.5 px/frame. metroid-samus/walk-off

About: Metroid Coyote time

Codemetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L5589-L5609VertAccelerate: LE37A: lda SamusGravity ;Is Samus rising or falling? LE37D: bne ++ ;Branch if yes. LE37F: lda #$18 ; LE381: sta SamusHorzSpdMax ;Set Samus maximum running speed. … LE38F: jsr CheckMoveDown ;($E7AD)Is Samus obstructed downwards? LE392: bcc ++ ;Branch if yes. LE394:* jsr SamusOnElevatorOrEnemy ;($D976)Calculate if Samus standing on elevator or enemy. … LE3A0: lda #$1A ;Samus is falling. Store falling gravity value. LE3A2: sta SamusGravity ; …metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2281-L2285* lda #an_SamusRun cmp AnimResetIndex bne + lda #an_SamusJump sta AnimResetIndexChecked by claude, 2026-10-25 — read VertAccelerate's grounded path into the gravity add at LE3A5, and SamusRun's airborne branch; SamusHorzSpdMax is written only here and at LCD40, so it stays $18 through a fall

Cited by: Metroid

A solid tile beside Samus stops her sideways move for the rest of the frame (CheckStopHorzMvmt). On the ground (SamusGravity 0), and not in the ball, it also calls StopHorzMovement, which clears her speed and acceleration and makes her stand. In the air her speed is kept. metroid-samus/wall-stop

Codemetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L5536-L5540LE333:* sta ObjectCounter ;Store number of pixels to move Samus this frame. LE335:* jsr MoveSamusLeft ;($E626)Attempt to move Samus 1 pixel to the left. LE338: jsr CheckStopHorzMvmt ;($E365)Check if horizontal movement needs to be stopped. LE33B: dec ObjectCounter ;1 pixel movement is complete. LE33D: bne - ;Branch if Samus needs to be moved another pixel.metroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L5568-L5577CheckStopHorzMvmt: LE365: bcs Exit10 ;Samus moved successfully. Branch to exit. LE367: lda #$01 ;Load counter with #$01 so this function will not be LE369: sta ObjectCounter ;called again. LE36C: lda SamusGravity ;Is Samus on the ground? LE36E: bne Exit10 ;If not, branch to exit. LE370: lda ObjAction ; LE373: cmp #sa_Roll ;Is Samus rolled into a ball? LE375: beq Exit10 ;If so, branch to exit.Checked by claude, 2026-10-25 — read the left and right move loops and CheckStopHorzMvmt, which jumps to StopHorzMovement (LCF55, into ClearHrztAnimData)

Cited by: Metroid

Blocked moving up, Samus's vertical speed, whole byte and fraction, is shifted right one bit with the sign bit set (sec, ror ObjVertSpeed, ror VertCntrLinear). An upward speed is halved and stays upward, though the comment says the shift reverses her direction. The rest of that frame's rise is dropped. Each later frame that would still move her up is blocked and halved again, until gravity turns her speed downward. metroid-samus/ceiling-hit

About: Metroid Jump

Codemetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L5471-L5478LE2C2:* sta ObjectCounter ;Store number of pixels to move Samus this frame. LE2C4:* jsr MoveSamusUp ;($E457)Attempt to move Samus up 1 pixel. LE2C7: bcs + ;Branch if Samus successfully moved up 1 pixel. LE2C9: sec ;Samus blocked upwards. Divide her speed by 2 and set the LE2CA: ror ObjVertSpeed ;MSB to reverse her direction of travel. LE2CD: ror VertCntrLinear ; LE2D0: jmp SamusMoveHorizontally ;($E31A)Attempt to move Samus left/right.The atlas reads this differently: An upward speed already has its sign bit set, so sec and the two rors are a signed shift: the speed halves and stays upward. Gravity, not this shift, turns her around.Checked by claude, 2026-10-25 — read the upward move loop; an upward speed already has bit 7 of ObjVertSpeed set, so the sec/ror pair is an arithmetic shift right of the 16-bit speed. A blocked Samus stays with her top on the tile boundary, where MoveSamusUp tests again

Not measured in the ROM; the conformance probe's start area has no ceiling within a jump.

Cited by: Metroid

Measured in the game, Samus's jump from a standstill peaks at 32 px on frame 10 when A is tapped or held up to 10 frames, and at 84 px on frame 41 when A is held to the top, landing on frames 36 and 86. A running jump, which rises on its press frame, peaks and lands a frame sooner at the same heights. metroid-samus/apex-by-hold

About: Metroid Variable jump height

Value
{
 "tap": {
  "apex": 32,
  "apexAt": 10,
  "airtime": 36
 },
 "full": {
  "apex": 84,
  "apexAt": 41,
  "airtime": 86
 },
 "byHold": {
  "1": {
   "apex": 32,
   "apexAt": 10,
   "airtime": 36
  },
  "2": {
   "apex": 32,
   "apexAt": 10,
   "airtime": 36
  },
  "4": {
   "apex": 32,
   "apexAt": 10,
   "airtime": 36
  },
  "6": {
   "apex": 32,
   "apexAt": 10,
   "airtime": 36
  },
  "8": {
   "apex": 32,
   "apexAt": 10,
   "airtime": 36
  },
  "10": {
   "apex": 32,
   "apexAt": 10,
   "airtime": 36
  },
  "12": {
   "apex": 38,
   "apexAt": 12,
   "airtime": 41
  },
  "16": {
   "apex": 49,
   "apexAt": 16,
   "airtime": 49
  },
  "20": {
   "apex": 59,
   "apexAt": 20,
   "airtime": 56
  },
  "30": {
   "apex": 76,
   "apexAt": 30,
   "airtime": 70
  },
  "50": {
   "apex": 84,
   "apexAt": 41,
   "airtime": 86
  }
 },
 "running": {
  "tap": {
   "apex": 32,
   "apexAt": 9,
   "airtime": 35
  },
  "full": {
   "apex": 84,
   "apexAt": 40,
   "airtime": 85
  }
 }
}
Verifiedmetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L2701-L2709 — the release test in SamusJumpLDA SamusJmpDsplcmnt BIT ObjVertSpeed BPL + CMP #$20 BCC + BIT Joy1Status BMI + JSR StopVertMovementmetroid-disassembly: Metroid software disassembly · Source_Files/Bank07.asm#L5589-L5643 — VertAccelerate, gravity and the move's pixel countlda VertCntrLinear clc adc SamusGravity sta VertCntrLinear lda ObjVertSpeed adc #$00 sta ObjVertSpeedThe atlas reads this differently: The byte is the fraction of Samus's vertical position: each frame the speed's fraction is added to it, and the carry adds a pixel to the move. Nothing here grows exponentially. (metroid-samus/subpixels)Checked by claude-agent, 2026-10-25 — Read SamusJump's release test (Bank07.asm L2701-2709: letting go stops the rise only once she has risen $20 px) and VertAccelerate (L5589-5643: SamusGravity added to a counter whose carry steps ObjVertSpeed) at the pinned commit; the heights and frames are the probe's run in the US ROM.Probe: probes/lab/metroid-jumps.mjs

The start state is set by RAM writes in probes/lab/metroid-movement.lua, so the enemies never touch her and her position fractions start at 0; neither changes the jump's arc. A tap and a hold of up to 10 frames give the same jump, because the release counts only once she has risen 32 px (metroid-samus/release-cap), which takes 10 frames.

Cited by: Metroid