On this page
  1. Across games
  2. Related
  3. Games
  4. References
  5. Sources

In a platformer, gravity is a constant added to the character’s downward speed on every update, usually with a cap on the fall. Super Mario Bros., Mega Man 2, Super Mario World, Sonic the Hedgehog, and Celeste all work this way. Castlevania’s jump has no gravity at all; a table moves Simon1.

Interactive: movement-lab (needs JavaScript)

Gravity, three ways

#Across games

Moving first means each frame’s step is the speed it began with. Super Mario Bros.17, Mega Man 27, Super Mario World18, and Sonic19 all do this. Celeste adds gravity before it moves Madeline20.

GravityFastest fallUnits
Super Mario Bros.0.117–0.156 px/frame² ($1E–$28)21 held, 0.375–0.5625 px/frame² ($60–$90)22 after the switch4 px/frame238.8 fixed point17
Castlevanianone in the arc18 px/frame2, past the tablewhole pixels1
Mega Man 20.25 px/frame² ($40)612 px/frame88.8 fixed point7
Super Mario World0.1875 px/frame² held, 0.375 released134.375 px/frame (4.1875 holding the button)14sixteenths of a pixel15
Sonic the Hedgehog0.21875 px/frame² ($38)24none258.8 speed, 16.16 position19
Celeste900 px/s²26160 px/s27float px/s, whole-pixel positions28

The caps aren’t always the plain minimum. Super Mario Bros. tests the speed’s fraction before clamping, so a fall can briefly run past the cap29. Super Mario World clamps first and adds gravity after, so its fastest fall is the cap plus a frame of gravity14.

Several games tie gravity to the jump button, which is how variable jump height works in the two Mario games30,13. Celeste halves gravity near the top of a held jump31.

Banjo-Kazooie halves its gravity through a held jump and restores it for the rest of the jump once A is up on the rise32. With A held, the lighter gravity lasts past the peak, as in Super Mario World13, where Super Mario Bros. swaps on release or at the peak30. Sonic Advance 2 adds 0.1640625 px/frame²33 on each frame of a jump, held or not, except a frame where Sonic’s forward thrust or a mid-air move starts33. The gravity is three quarters of what Sonic’s ObjectFall adds24. Metroid Fusion and Metroid: Zero Mission also ignore the button, at 0.1875 px/frame²34 and 0.3125 px/frame²35 out of liquid. Like Castlevania1, Prince of Persia has no gravity in its jumps; only a fall speeds up, by 3 px/cycle per cycle, from 15 up to 3336. In a decompilation that doesn’t yet match, Super Mario Sunshine’s jump gravity is 0.8 by default (data on the disc)37, a default the game’s own data can replace37.

Mega Man 3 keeps Mega Man 2’s gravity but caps a fall at 7 px/frame, where Mega Man 2 allows 129. Sonic the Hedgehog 2 adds 0.21875 px/frame² ($38)10 on each airborne frame, and Sonic 3 & Knuckles keeps that gravity from Sonic 1 and Sonic 211.

Castlevania II: Simon’s Quest adds the gravity Castlevania lacks: 0.21875 px/frame² on every airborne frame, with a fall capped at 3 px/frame4. Castlevania III: Dracula’s Curse keeps the table for every character but Grant, and a long fall holds at 6 px/frame where Castlevania’s reaches 83. Super Castlevania IV holds the take-off speed with no gravity for up to 4 frames while the button stays down, then adds 0.375 px/frame² each frame and caps a fall at 8 px/frame12. Castlevania: Symphony of the Night adds 0.171875 px/frame² on each jumping frame, a fifth of that near the top while Cross is held, and caps a fall at 7 px/frame16.

Games

GameYearHowNote
Felix the Cat199245/256 px a frame per frame, to 6 px a frame
Metroid1986One gravity0.09375 px/frame² in a jump, 0.0703 with the High Jump Boots, held or not
Castlevania II: Simon's Quest1987One gravityone gravity on every jump, with a capped fall
Contra1987One gravity0.137 px/frame² on every airborne frame
Mega Man1987One gravityone gravity, whatever the button does
Mega Man 21988One gravityone gravity, whatever the button does
Prince of Persia1989One gravitya fall adds 3 px per cycle to the speed, up to 33, or 1 up to 4 while weightless
Mega Man 31990One gravitythe same gravity as Mega Man 2, but a slower top falling speed
Super C1990One gravityContra's 0.137 px/frame², with falls capped at 5 px/frame
Sonic the Hedgehog1991One gravityone pull of gravity whether the button is held or not, and a jump's fall isn't capped
Sonic the Hedgehog 21992One gravityone pull of gravity whether the button is held or not, lighter underwater
Mega Man 61993One gravitythe same pull on every frame, lighter in one kind of tile
Sonic 3 & Knuckles1994One gravitythe pull of the first two games, the same whether the button is held or not
Super Metroid1994One gravity0.109375 px/frame² in air, held or not, with lighter values in water and lava
Pilotwings 641996One gravitythe gyrocopter adds a gravity of 9.8 on the world's vertical every update, scaled by the frame time
Quake1996One gravity800 units/s² every frame out of water, 100 on E1M8
Super Mario 641996One gravity4 units/frame² in most jumps and 2 in the long jump, down to −75
Pokémon Pinball1999One gravity11/256 px per frame² on the ball, 8.8 fixed point
Metroid Fusion2002One gravity0.1875 px/frame² in air, held or not, two-thirds of that in liquid without the Gravity Suit
Sonic Advance 22002One gravity42/256 px/frame² in a jump, held or not, three quarters of Sonic 1's
Super Mario Sunshine2002One gravitya parameter, 0.8 an update by default, down to −75, with a lighter one in a spin jump's descent
Metroid: Zero Mission2004One gravity0.3125 px/frame² in air, held or not, halved in liquid without the Gravity Suit
Super Mario Bros.1985Switch on releasea light pull while A is held on the way up, a heavier one after
Super Mario Bros.: The Lost Levels1986Switch on releaseSuper Mario Bros.'s light pull while A is held on the way up, lighter still for Luigi
Super Castlevania IV1991Switch on releasegravity waits a few frames while the button is held, then slows the rise
Banjo-Kazooie1998Switch on release−1350 units/s² through a held jump, −2700 once A is up on the rise, and past the peak only if A stays held
Super Mario Bros. 21988Lighter while heldeach character has a lighter gravity for any frame the button is held
Super Mario Bros. 31988Lighter while held1/16 px/frame² while A is held on a fast rise, 5/16 otherwise
Super Mario World1990Lighter while helda lighter gravity on any frame the button is held
Castlevania: Symphony of the Night1997Lighter while heldhold the button and he floats at the top of the jump
Celeste2018Lighter while heldone gravity, halved near the apex while jump is held
Every claim about this mechanic, by game (63)
Super Mario Bros. 1985Vertical motion is 8.8 fixed point; each frame, ImposeGravity adds speed to position, the fraction via the YMF_Dummy subpixel byte, then gravity to speed.Code
MovePlayerVertically gives ImposeGravity 4 px/frame as Mario's maximum fall speed; the clamp sets the speed back to 4 only when its whole part is at least 4 and its fraction byte at least $80.Code
ImposeGravity clamps a fall of 4 px/frame or more only when the fraction byte is at least $80.Code
A falling Mario's gravity is VerticalForceDown, which FallingSub copies in every frame. Each area's entrance sets it to $28 (40/256 px/frame²), and only a jump changes it, to its row's falling gravity, so a walk-off before any jump falls at $28 and one after a jump at that jump's falling gravity.Verified
Castlevania 1986Once the reversed table runs out, the arc routine moves Simon down 8 px every frame until he lands, so a jump that ends below its take-off point falls at 8 px per frame.Verified
Above screen Y 208 and off moving platforms, each falling frame tests the floor at Simon's position before he moves: with ground under either floor point he lands that frame without moving, his Y snapped up to a multiple of 16; otherwise he moves 1 px and drops 8 px. From Y 208 on, the floor test finds no ground.Verified
Simon dies when his Y reaches 224 ($E0) in the falling state, before its 8 px drop, or 224 to 239 in the jumping state, at the start of its frame.Code
Metroid 1986Each 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.Code
Super Mario Bros.: The Lost Levels 1986The movement and gravity routines (MoveObjectHorizontally through ImposeGravity) are Super Mario Bros.'s, instruction for instruction: ImposeGravity and MoveDropPlatform are byte for byte the same, and the other seven differ only in the addresses of their calls and jumps.Code
Mega Man 1987Each airborne frame takes $40/256 = 0.25 px/frame off Mega Man's upward speed, and a fall is capped at 12 px/frame ($F4).Code
_objects_vertical_moving first moves Mega Man by his 8.8 fixed-point vertical speed, positive up (his Y, which runs down the screen, subtracts it), and then, on a frame that meets no floor or ceiling, takes gravity off the speed.Code
Mega Man's fall is capped at 12 px/frame ($F4).Code
Mega Man 2 1988Gravity takes $40/256 = 0.25 px/frame from Mega Man's upward speed each frame out of water ($1E/256 in water).Code
_check_object_vertical_move first moves Mega Man by his 8.8 fixed-point speed, positive up, and then subtracts gravity.Code
Falling speed is capped at 12 px/frame ($F4).Code
Super Mario Bros. 2 1988Super Mario Bros. 2 keeps speeds as 4.4 fixed point; ApplyPlayerPhysics takes whole pixels from a speed's upper nibble.Code
PlayerGravity adds the character's lighter gravity on any frame the jump button is held and the heavier one otherwise, and adds none once a fall has reached $39 (3.5625 px/frame). The last add can carry the fall past that, up to $3F (3.9375 px/frame) under a gravity of $07. Two branches come first: sunk in quicksand (QuicksandDepth 2 or more), the routine adds GravityQuicksand, $08 for all four (quicksand), at any speed; and while the Princess floats, it sets her speed outright from FloatingYVelocity and adds nothing (float).Code
Super Mario Bros. 3 1988Super Mario Bros. 3 keeps Mario's speeds as 4.4 fixed point: the high nibble is whole pixels per frame, the low nibble sixteenths. Player_ApplyYVelocity caps the fall at FALLRATE_MAX, $40, before the frame's gravity is added, so the move never exceeds 4 px a frame. Measured in Mesen from power-on as Raccoon Mario at World 1-1's start, a jump's fall levels off at 4 px a frame.Verified
In the air Player_JumpFlyFlutter adds 5 to Mario's vertical speed each update, or 1 while A is held and he rises faster than $20; a Micro-Goomba stuck to him keeps the 5 even with A held. A tail wag can then overwrite the speed (flight-time, tail-wag), and a Tanooki statue skips this routine (tanooki-statue). Measured in Mesen from power-on as Raccoon Mario at World 1-1's start, a jump with A held gains 1 a frame until the rise slows to -$20, then 5 a frame; with A pressed for one frame it gains 5 a frame from the frame after the take-off.Verified
Prince of Persia 1989With the weightless flag clear, a fall (action 4) adds 3 px per cycle to the kid's downward speed, up to 33 px per cycle (AccelGravity, TermVelocity); with it set, gravity is 1 and the cap 4 (WtlessGravity, WtlessTermVel). The fall sequences that start it set the speed to 15 (setfall). In any other action, including the jumps' (action 1) and a fall's first frames (action 3), gravity does nothing.Code
Mega Man 3 1990Mega Man 3 raises the take-off speed from Mega Man 2's $04.$DF (4.87 px/frame) to $04.$E5 (4.89) and keeps gravity at $40, but caps a fall at 7 px/frame ($F9) where Mega Man 2 allows 12 ($F4).Code
Mega Man 3 moves Mega Man vertically before horizontally. Every frame on the ground or in the air first runs the airborne routine: a rise without A held is cut (release-cut), then move_vertical_gravity moves him by his vertical speed, takes gravity from it, and tests the floor under a fall or the ceiling over a rise. Only then does the frame's horizontal move run: the air move if he is still airborne, the ground state's move if he stood on a floor.Code
Gravity takes $40/256 = 0.25 px/frame from Mega Man's upward speed every frame out of water, after the frame's vertical move.Code
A fall is capped at 7 px/frame: when gravity takes the speed's whole byte below $F9, apply_gravity sets it to $F9.$00.Code
Both games move an object each frame by a speed with a fraction and change its Y speed by gravity, but Mega Man 3's movers are new code that Mega Man and the enemies share. Mega Man 2's enemy routine, left undecoded by its disassembly, checks the object's hits, moves it by its Y speed, subtracts gravity from that speed when a flag bit asks for it, moves it by its X speed in the way it faces, and removes it once it leaves the screen; walls and floors are a separate routine, and Mega Man moves with his own code. Mega Man 3's move_vertical_gravity and move_right_collide serve slot 0, the player, and every enemy alike, and run the tile check inside each move, snapping the object to the floor, ceiling, or wall it reaches.Code
Super C 1990The US NES Super C keeps Contra's outdoor jump: a take-off speed of $FB.$F0 (4.06 px/frame up) and gravity of $23 a frame. Super C caps a fall at 5 px/frame and jumps out of water at $FD.$00 (3 px/frame).Code
Super Mario World 1990Each frame CODE_00D928 adds 3/16 px/frame to Mario's vertical speed while A or B is held and 6/16 otherwise, rising or falling.Code
Gravity's routine cuts a downward speed above $40 (4 px/frame) back to $40 before adding gravity, so Mario falls at most 70/16 px/frame, or 67/16 holding the button.Verified
Each frame the player routine moves Mario by his current speed (CODE_00DC2D), then handles a jump press (CODE_00D5F2), then adds gravity (CODE_00D7E4), so the press frame doesn't lift him and his first step up is the take-off speed plus held gravity.Code
CODE_00DC4F adds a speed's low nybble to a subpixel byte and its high nybble, sign-extended, plus the carry to the 16-bit position, so Mario moves in sixteenths of a pixel.Code
When neither foot point finds a block and Mario isn't in the air, collision sets PlayerInAir to $24 (falling). Collision follows the move, so he counts as airborne on the frame whose move carries his trailing foot past the edge, already moved by the ground's vertical speed, 6/16 px/frame (3/16 with B held); gravity then adds 6/16 a frame (3/16 held) up to 70/16.Verified
Mega Man 4 1991Mega Man 4's routines that move an entity by its speed without checking tiles, and apply gravity, follow Mega Man 3's with the entity arrays moved, and with four changes. Mega Man 4 drops Mega Man 3's routine that sets a behind-the-background flag from the tile hit. Its gravity tests one flag at $43 first, where Mega Man 3 tests for the player and then a flag at $B9. It drops Mega Man 3's exemption, for one animation ($13), from the cap on falling speed. And when gravity resets, it sets one speed ($FF00) for every entity, where Mega Man 3 sets $FFC0 for the player and $FFAB for the rest.Code
Sonic the Hedgehog 1991In the running game, ObjectFall's gravity equate adds $38 (0.21875 px/frame²) to Sonic's Y speed on every airborne frame, rising or falling, after a jump or off a ledge, button held or not.Verified
In the running game, ObjectFall and SpeedToPos move Sonic's 32-bit position each frame by his speed shifted left 8 bits, X by this frame's X speed and Y, in the air, by the Y speed before gravity, so positions are 16.16 and speeds 8.8 fixed point.Verified
In the running game, a Y speed written into a jump, −$1100 rising or $FC0 falling, is neither capped nor clamped: gravity keeps adding $38, to −$10C8 a frame later and to $1068 before he lands, because Sonic_JumpHeight skips its −$FC0 cap after jumps (FixBugs = 0).Verified
Felix the Cat 1992Falling, with $0616 below 3 and $03B1 clear, Felix's y speed grows by 45 (in 1/256 px, down positive) each frame up to a cap of 1,536, 6 px a frame, as measured at the first stage's start.Verified
Mega Man 5 1992One routine, entity_gravity_collide, moves Mega Man vertically in the ground, air, and slide states, before their horizontal move. By the sign of his speed's whole byte (8.8 fixed point, positive up) it moves him down or up by the speed, takes gravity off the speed, and only then tests the floor points under a fall or the ceiling points over a rise. The ground state runs the whole air routine first and reads A and the d-pad only if that routine found him standing and he was already on the ground.Code
Gravity takes 0.25 px/frame ($40/256) off Mega Man's upward speed every frame, after the move: the reset code writes $40 to $A1, and the gravity routine subtracts $A1 from the speed's fraction byte with the borrow into its whole byte.Code
When gravity takes Mega Man's speed below −7 px/frame (its whole byte under $F9), the gravity routine sets it to exactly $F9.$00, so he falls at most 7 px a frame.Code
On the ground Mega Man's vertical speed rests at −1 px/frame ($FF.$00): a floor found under a fall snaps him onto it and entity_stop_y sets that speed. So each grounded frame moves him 1 px down, takes gravity, and tests his floor points; ground there puts him back with the same speed, and none leaves him in the air falling at 1.25 px/frame.Code
When a falling Mega Man's floor points find a solid tile, LEEF7 subtracts the tested row's depth into its 16 px tile from his Y pixel, which puts the points on the tile's top row and his feet on its top, and keeps the Y fraction. A fall of up to 7 px a frame always ends on the top of the tile it reaches.Code
Measured in Mesen from power-on, at the start of Stone Man's stage, Mega Man stood with his Y fraction at $80 once the teleport landed him. The floor snap keeps the fraction (floor-snap), so it stays with him on flat ground until a slide's end adds to it.Verified
Mega Man 5's routines that move an object by its speed without checking tiles, and apply gravity, follow Mega Man 4's, with the gravity amount at $A1 instead of $99 and these changes. Eight bytes before the left mover clear the facing bit and fall into it. The player's gravity is skipped whenever a flag at $52 is set, where Mega Man 4 skips it only while a timer at $43 counts down. And Mega Man 5 adds four routines after them, one of which adds gravity to the vertical speed instead of subtracting it, capped at 7 pixels a frame.Code
Sonic the Hedgehog 2 1992ObjectMoveAndFall adds $38 subpixels/frame to Sonic's downward speed each airborne frame, and underwater the air modes take $28 back, leaving $10.Code
Mega Man 6 1993Outside tile type $08, gravity adds $40 (0.25 px/frame) to Mega Man's vertical speed every frame before he moves. Measured in Mesen from power-on, at the start of Tomahawk Man's stage, his speed grew by 0.25 px/frame on each frame of a held jump.Verified
In tile type $08 gravity is $18 a frame (0.09 px/frame) instead of $40. Falling, the whole-pixel byte of his speed stops at 7 while the fraction keeps growing, so under the normal gravity his top falling speed steps between 7.05 and 7.80 px/frame (computed).Code
Sonic 3 & Knuckles 1994MoveSprite adds $38 subpixels/frame to a falling player's speed, Sonic 1's and Sonic 2's gravity, and underwater the air modes take $28 back.Code
Super Metroid 1994Gravity is one constant in air, $1C00 subpixels (0.109375 px/frame²) every frame of a jump or fall, held button or not; water uses $0800 and lava or acid $0900. A fall stops gaining speed at 5 px/frame.Code
Quake 1996Quake's gravity is the cvar sv_gravity, defaulting to 800, and each level's QuakeC worldspawn sets it to 800 again, or to 100 on E1M8; every frame a walking player is not in water (water level 2 or more) or a water jump, SV_AddGravity takes the entity's gravity field (1 when unset) × sv_gravity × frame time off its vertical velocity, on the ground as well as in the air.Code
Super Mario 64 1996Super Mario 64 keeps Mario's speeds as floats in world units per frame: perform_air_step moves him a quarter of his velocity in each of four quarter steps. A frame waits for two vertical blanks in display_and_vsync, so on an NTSC console the game runs at most 30 frames a second.Code
Mario's usual gravity subtracts 4 units/frame from his vertical speed each frame, down to a fastest fall of −75. The long jump and the slide kick use 2 instead, with the same cap.Code
Castlevania: Symphony of the Night 1997Each jumping frame adds 0.171875 px/frame² to Alucard's vertical speed, a fifth of that while Cross is held near the top (between 0.125 px/frame up and 0.375 down), and caps a fall at 7 px/frame.Code
Banjo-Kazooie 1998Banjo-Kazooie keeps Banjo's speeds in world units per second and his gravity in units per second squared, scaled by each frame's time: __baphysics_update_normal adds the gravity times time_getDelta() to his vertical speed, then moves him by his velocity times that same time. The frame's time is a count from the video manager over 60 (50 on a PAL build): viMgr_entry adds 1 to D_802808D8 for each message on its queue, and each buffer swap copies the count to D_80280724 and zeroes it; the atlas reads the messages as vertical blanks, so the count as the blanks the frame took. func_8033DC20 turns the count into seconds and the caller back into a whole count, clamped to 1 to 15, then capped at 0.05 s in US 1.0 (0.06 s on PAL), so at most three sixtieths (computed); that is multiplied by a multiplier that time_reset sets to 1.Code
Pokémon Pinball 1999Gravity adds 11/256 of a pixel per frame to the ball's downward speed every frame while gravity is on. The ball's position and velocity are both 8.8 fixed point: whole pixels in the high byte, 256ths in the low.Code
Metroid Fusion 2002Out 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).Code
Sonic Advance 2 2002Each frame of a jump, button held or not, Player_Jumping adds PLAYER_GRAVITY, 42/256 px/frame² (12/256 in water), to the vertical speed through PLAYERFN_UPDATE_AIR_FALL_SPEED, except on a frame where Sonic's forward thrust or a mid-air move starts (Player_Sonic_TryForwardThrust, Player_TryMidAirAction): Player_Jumping returns before the gravity then. That is three quarters of the gravity Sonic 1's airborne-rolling mode, Sonic_MdJump2, adds through ObjectFall, $38 (56/256) a frame (computed).Code
Super Mario Sunshine 2002In the doldecomp decompilation of Super Mario Sunshine, most of Mario's movement constants are named parameters (TParamRT), each built with a default in the code, in sets that each name a file, such as /Mario/Jump.prm. TParams::load, in a file configure.py marks as matching the game's code, reads the set's file from the scene's /map/params folder if it is there and from the params archive if not, and a record whose key and name match a parameter replaces that parameter's default; the rest keep theirs. The values the game plays with are data on the disc, which the atlas hasn't read, so the numbers in these claims are the code's defaults. The jump set's gravity, mGravity, defaults to 0.8. In the jumping states, jumpProcess in the decompilers' Player code, which doesn't yet match, moves Mario by a quarter of his velocity in one step per update. Then fallProcess subtracts mGravity from his vertical speed, except in a dive (the dive set's own gravity, with a cap of its own), in a spin jump's descent (mSpinJumpGravity, default 0.6), and when a release cuts the rise (sms/jump); in every case it then caps the fall at −75. Super Mario 64 also moves Mario a quarter of his velocity at a time, but in four steps a frame (sm64/units).Code notes
Metroid: Zero Mission 2004Out 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.Code
Celeste 2018Celeste's gravity is 900 px/s²; each airborne update moves vertical speed toward the fall limit by Gravity * mult * Engine.DeltaTime.Code
MaxFall, the normal limit on falling speed, is 160 px/s; NormalBegin starts maxFall there and gravity approaches it.Code
Holding down while falling at MaxFall or faster raises the limit toward FastMaxFall (240 px/s) at FastMaxAccel (300 px/s²); otherwise it eases back.Code
In the public Monocle source, Calc.Approach(val, target, maxMove) moves val toward target by at most maxMove without overshooting.Code
Celeste's actors sit on whole pixels; MoveV adds the float distance to a remainder, moves by its rounded value, and keeps the fraction.Dev blog

References

  1. ^ abcdeSimon's jump rises by a fixed table of per-frame steps, 5, 5, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 0, 1, 0, 0, 0, and 0 px, 36 px in all.Code“Castlevania (USA) (Rev 1)”
    How we know

    In the cartridge (“Castlevania (USA) (Rev 1)”): bank 6 $9B8D-$9BA4, the table's address, a $80 start marker, 20 signed steps ($FB = −5, up), and a $81 turn marker; bank 6 $9B1E-$9B8A, the routine that adds one step to Simon's Y each frame and moves the table pointer. We don't reproduce the bytes.

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  2. ^ abOnce the reversed table runs out, the arc routine moves Simon down 8 px every frame until he lands, so a jump that ends below its take-off point falls at 8 px per frame.Verified“Castlevania (USA) (Rev 1)”
    How we know

    In the cartridge (“Castlevania (USA) (Rev 1)”): bank 6 $9B43-$9B5E: on the $80 marker the step is $F8, negated while falling to +8, and the pointer stays put. We don't reproduce the bytes.

    Measured by a script in MesenCE 2.2.1 (build 4b8a196), on Castlevania (USA) (Rev 1) (SHA-1 4e3ef47de86a…). It fails if the result disagrees with the claim.

    The numbers come from the run; its author, an AI model, checked the script measures what the claim says, 2026-10-22.

    Checked by a second AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  3. ^ abDracula's Curse keeps Castlevania's jump for every character but Grant; the take-off starts the arc at entry 9 of a longer table whose entries from there are Castlevania's 20 rises, 5, 5, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 0, 1, 0, 0, 0, and 0 px, and the 8 entries before it, 6 then 5 px, carry a fall below the take-off height down to 6 px/frame, where Castlevania falls at 8 px/frame once its table runs out.Codevinheim3/castlevania3-disasm · “Castlevania III - Dracula's Curse (USA)” · “Castlevania (USA) (Rev 1)”revised
    How we know
    3740playerState06_jumpStart_exceptGrant:
    
    code/playerStateProcessing_b1c.s lines 3740–3751 at 3272648 · upstream ↗
    lda $9874, y … cmp #$81 … sta wEntityVertSpeed.w, x … inc $05d8, x … cmp #$80 … dec $05d8, x … eor #$ff … lda $9875, y
    code/playerStateProcessing_b1c.s#L4187-L4225 · upstream ↗
    3242processTrevorState:
    ⋮
    3249	.dw playerState06_jumpStart_exceptGrant
    3250	.dw playerState08_jumping_exceptGrant
    
    code/playerStateProcessing_b1c.s lines 3242–3250 at 3272648 · upstream ↗
    4751processSyphaState:
    ⋮
    4758	.dw playerState06_jumpStart_exceptGrant
    
    code/playerStateProcessing_b1c.s lines 4751–4759 at 3272648 · upstream ↗
    918processAlucardState:
    ⋮
    926	.dw playerState06_jumpStart_exceptGrant
    
    code/playerStateProcessing_b1d.s lines 918–927 at 3272648 · upstream ↗
    4784processGrantState:
    ⋮
    4791	.dw playerState06_jumpStart_grant
    4792	.dw playerState08_jumping_0c_grant
    
    code/playerStateProcessing_b1c.s lines 4784–4792 at 3272648 · upstream ↗

    In the cartridge (“Castlevania III - Dracula's Curse (USA)”): bank $1C $9874-$9891: $80, five $FA (−6), five $FB (−5), five $FD, three $FE, four $FF, $00, $FF, four $00, and $81; the disassembly lists these bytes partly as instructions. We don't reproduce the bytes.

    In the cartridge (“Castlevania (USA) (Rev 1)”): Castlevania's table of 20 steps (castlevania/jump-table); Castlevania's 8 px fall past the table (castlevania/table-end-fall). We don't reproduce the bytes.

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Revised after a check by a second AI model, 2026-10-21.

    In the claim ledger

  4. ^ abSimon's Quest replaces Castlevania's step table with a speed and gravity; a jump from the ground takes off at 4 px/frame up, every airborne frame adds 0.21875 px/frame² of gravity, and a fall is capped at 3 px/frame, where Castlevania steps a fixed 20-entry table and falls past its end at 8 px/frame.Code“Castlevania II - Simon's Quest (USA)” · “Castlevania (USA) (Rev 1)”
    How we know

    In the cartridge (“Castlevania II - Simon's Quest (USA)”): bank 3 $88D9-$892A, the take-off: Y speed $036C.$037E = −4.0 ($FC.$00), the action set to jumping, and the held d-pad read into the X speed and facing; bank 3 $89D6-$8A0D, each jumping frame: zero the speed on a ceiling, add $38 to the speed's fraction ($DFE4), and cap a fall at 3.0; bank 7 $DFE4-$DFF9, a 16-bit add of $0008 to object X's Y speed. We don't reproduce the bytes.

    In the cartridge (“Castlevania (USA) (Rev 1)”): Castlevania's jump table, 20 signed steps between a $80 and a $81 marker (castlevania/jump-table); Castlevania's fall past the table's end, 8 px per frame (castlevania/table-end-fall). We don't reproduce the bytes.

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  5. ^Each airborne frame takes $40/256 = 0.25 px/frame off Mega Man's upward speed, and a fall is capped at 12 px/frame ($F4).Codelsmmega/mm1
    How we know
    96@is_megaman_2:
    97	LDA aobject_ycoord_speed_fraction, X
    98	SBC #$40
    99	STA aobject_ycoord_speed_fraction, X
    100	LDA aobject_ycoord_speed, X
    101	SBC #$00
    102	BPL @normal_ycoord_speed
    103	CMP #$F4
    104	BCS @normal_ycoord_speed
    105	LDA #$00
    106	STA aobject_ycoord_speed_fraction, X
    107	LDA #$F4
    ⋮
    
    engine/objects_vertical.asm lines 96–110 at b606a84 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  6. ^ abcGravity takes $40/256 = 0.25 px/frame from Mega Man's upward speed each frame out of water ($1E/256 in water).Codelsmmega/mm2
    How we know
    175tsa_ycoord_speed_accelerate_fraction_table:
    176	.BYTE $40, $1E
    
    engine/check_object_horizontal_move.asm lines 175–176 at 94f0bf3 · upstream ↗
    73@air:
    74	SEC
    75	LDA aobject_ycoord_speed_fraction
    76	SBC z:zobject_ycoord_speed_accelerate_fraction
    77	STA aobject_ycoord_speed_fraction
    78	LDA aobject_ycoord_speed
    79	SBC z:zobject_ycoord_speed_accelerate
    80	STA aobject_ycoord_speed
    
    engine/check_object_vertical_move.asm lines 73–80 at 94f0bf3 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  7. ^ abc_check_object_vertical_move first moves Mega Man by his 8.8 fixed-point speed, positive up, and then subtracts gravity.Codelsmmega/mm2
    How we know
    13	SEC
    14	LDA aobject_ycoord_fraction
    15	SBC aobject_ycoord_speed_fraction
    16	STA aobject_ycoord_fraction
    17	LDA aobject_ycoord
    18	SBC aobject_ycoord_speed
    19	STA aobject_ycoord
    
    engine/check_object_vertical_move.asm lines 12–19 at 94f0bf3 · upstream ↗
    engine/check_object_vertical_move.asm#L73-L80 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  8. ^ abFalling speed is capped at 12 px/frame ($F4).Codelsmmega/mm2
    How we know
    81	BPL @skip
    82	CMP #$F4
    83	BCS @skip
    84	LDA #$00
    85	STA aobject_ycoord_speed_fraction
    86	LDA #$F4
    87	STA aobject_ycoord_speed
    
    engine/check_object_vertical_move.asm lines 81–87 at 94f0bf3 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  9. ^ abMega Man 3 raises the take-off speed from Mega Man 2's $04.$DF (4.87 px/frame) to $04.$E5 (4.89) and keeps gravity at $40, but caps a fall at 7 px/frame ($F9) where Mega Man 2 allows 12 ($F4).Codeplasticsmoke/megaman3-disassembly-ca65 · lsmmega/mm2
    How we know
    74        lda     #$E5                    ; normal jump: Y vel = $04.E5
    75        sta     ent_yvel_sub,x          ; store Y velocity sub-pixel
    76        lda     #$04                    ; Y velocity whole = $04
    77        sta     ent_yvel,x              ; store Y velocity whole
    
    src/fixed/player_ground.asm lines 74–77 at 58ca1c3 · upstream ↗
    648prelude_setup_per_frame:  lda     #$40  ; gravity = $40 for player physics
    649        sta     gravity                 ; (process_sprites sets $55 for entities)
    
    src/fixed/game_loop.asm lines 648–649 at 58ca1c3 · upstream ↗
    393apply_gravity_player_check:  lda     ent_yvel_sub,x ; Y sub velocity -= gravity
    394        sec                             ; prepare for subtraction
    395        sbc     gravity                 ; subtract gravity value
    396        sta     ent_yvel_sub,x          ; store new Y sub velocity
    397        lda     ent_yvel,x              ; Y velocity -= borrow
    398        sbc     #$00                    ; propagate borrow to whole byte
    399        sta     ent_yvel,x              ; store new Y velocity
    400        bpl     apply_gravity_exit      ; still positive (rising)? done
    401        cmp     #$F9                    ; check against terminal velocity $F9
    402        bcs     apply_gravity_exit      ; within limit (-7 to -1)? done
    
    src/fixed/movement.asm lines 393–402 at 58ca1c3 · upstream ↗
    175tsa_ycoord_speed_accelerate_fraction_table:
    176	.BYTE $40, $1E
    ⋮
    181tsa_regular_water_jump_speed_table:
    182	.BYTE $04, $05
    ⋮
    184tsa_regular_water_jump_speed_fraction_table:
    185	.BYTE $DF, $80
    
    engine/check_object_horizontal_move.asm lines 175–185 at 94f0bf3 · upstream ↗
    81	BPL @skip
    82	CMP #$F4
    83	BCS @skip
    84	LDA #$00
    85	STA aobject_ycoord_speed_fraction
    86	LDA #$F4
    87	STA aobject_ycoord_speed
    
    engine/check_object_vertical_move.asm lines 81–87 at 94f0bf3 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  10. ^ abObjectMoveAndFall adds $38 subpixels/frame to Sonic's downward speed each airborne frame, and underwater the air modes take $28 back, leaving $10.Codesonicretro/s2disasm
    How we know
    30216	move.w	y_vel(a0),d0	; load y speed
    30217	addi.w	#$38,y_vel(a0)	; increase vertical speed (apply gravity)
    
    s2.asm lines 30216–30217 at 4ef457c · upstream ↗
    36582	subi.w	#$28,y_vel(a0)			; reduce gravity by $28 ($38-$28=$10)
    
    s2.asm lines 36575–36582 at 4ef457c · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  11. ^ abMoveSprite adds $38 subpixels/frame to a falling player's speed, Sonic 1's and Sonic 2's gravity, and underwater the air modes take $28 back.Codesonicretro/skdisasm · sonicretro/s1disasm · sonicretro/s2disasmrevised
    How we know
    36077		move.w	y_vel(a0),d0	; load y speed
    36078		addi.w	#$38,y_vel(a0)	; increase vertical speed (apply gravity)
    
    sonic3k.asm lines 36077–36078 at 73de97c · upstream ↗
    22446		jsr	(MoveSprite_TestGravity).l
    ⋮
    22449		subi.w	#$28,y_vel(a0)			; reduce gravity by $28 ($38-$28=$10)
    
    sonic3k.asm lines 22442–22449 at 73de97c · upstream ↗
    gravity: equ $38
    _incObj/sub ObjectFall & SpeedToPos.asm#L5 · upstream ↗
    30217	addi.w	#$38,y_vel(a0)	; increase vertical speed (apply gravity)
    
    s2.asm line 30217 at 4ef457c · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Revised after a check by a second AI model, 2026-10-21.

    In the claim ledger

  12. ^ abSuper Castlevania IV's jump holds the take-off speed with no gravity while the jump button stays down, for up to 4 frames, then adds 0.375 px/frame² each frame until the rise stops, holds Simon still at the top for about 9 frames, and falls under the same gravity, capped at 8 px/frame.Code“Super Castlevania IV (USA)”
    How we know

    In the cartridge (“Super Castlevania IV (USA)”): $00:A3FA-$A409, state 4 each frame: animation, facing ($A792), air control ($A8DE), then the phase routine $A94D; $00:A94D-$A9CF: phases by $1F86. 0: while the button in $BE is held, count $0564 to 4, else go on; 1–2: gravity ($A739) until the speed is ≥ 0, then 0; 3–4: speed 0, count to 9; 5–6: gravity; $00:A739-$A769: Y speed + $0000.$6000 (0.375); a fall at or past 8.0 is set to 8.0. We don't reproduce the bytes.

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  13. ^ abcdEach frame CODE_00D928 adds 3/16 px/frame to Mario's vertical speed while A or B is held and 6/16 otherwise, rising or falling.CodeSMWDisX
    How we know
    10167DATA_00D7A5:                                  ;!
    10168    db $06,$03,$04,$10,$F4,$01,$03,$04        ;!
    
    bank_00.asm lines 10167–10169 at 30643c7 · upstream ↗
    10439CODE_00D928:
    10440    LDY.B #$01
    10441    LDA.B byetudlrHold
    10442    BMI +
    10443CODE_00D92E:
    10444    LDY.B #$00
    
    bank_00.asm lines 10439–10444 at 30643c7 · upstream ↗
    10457CODE_00D948:                                  ;!
    10458    CLC                                       ;!
    10459    ADC.W DATA_00D7A5,Y                       ;!
    
    bank_00.asm lines 10457–10459 at 30643c7 · upstream ↗
    821  + LDA.W axlr0000P1Hold,X                    ;\ 
    822    AND.B #!ButA|!ButX                        ;| Set up $15, sharing the top two bits of controller data 2 (for A/X).
    823    ORA.W byetudlrP1Hold,X                    ;|
    824    STA.B byetudlrHold                        ;/
    
    bank_00.asm lines 821–824 at 30643c7 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  14. ^ abcGravity's routine cuts a downward speed above $40 (4 px/frame) back to $40 before adding gravity, so Mario falls at most 70/16 px/frame, or 67/16 holding the button.VerifiedSMWDisX
    How we know
    10171DATA_00D7AF:                                  ;!
    10172    db $40,$40,$20,$40,$40,$40,$40,$40        ;!
    
    bank_00.asm lines 10171–10173 at 30643c7 · upstream ↗
    10446  + LDA.B PlayerYSpeed+1                      ;! \ If Mario's Y speed is negative (up),
    10447    BMI CODE_00D948                           ;! / branch to $D948
    10448    CMP.W DATA_00D7AF,Y                       ;!
    10449    BCC +                                     ;!
    10450    LDA.W DATA_00D7AF,Y                       ;!
    
    bank_00.asm lines 10446–10450 at 30643c7 · upstream ↗

    Measured by a script in MesenCE 2.2.1 (build 4b8a196), on . It fails if the result disagrees with the claim.

    The numbers come from the run; its author, an AI model, checked the script measures what the claim says, 2026-10-20.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  15. ^ abCODE_00DC4F adds a speed's low nybble to a subpixel byte and its high nybble, sign-extended, plus the carry to the 16-bit position, so Mario moves in sixteenths of a pixel.CodeSMWDisX
    How we know
    10909CODE_00DC4F:                                  ;!
    10910    LDA.B PlayerXSpeed+1,X                    ;!
    10911    ASL A                                     ;!
    10912    ASL A                                     ;!
    10913    ASL A                                     ;!
    10914    ASL A                                     ;!
    10915    CLC                                       ;!
    10916    ADC.W PlayerXPosSpx,X                     ;!
    ⋮
    10920    LDA.B PlayerXSpeed+1,X                    ;!
    ⋮
    10930    ADC.B PlayerXPosNext,X                    ;!
    
    bank_00.asm lines 10909–10933 at 30643c7 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  16. ^ abEach jumping frame adds 0.171875 px/frame² to Alucard's vertical speed, a fifth of that while Cross is held near the top (between 0.125 px/frame up and 0.375 down), and caps a fall at 7 px/frame.CodeXeeynamo/sotn-decomp
    How we know
    591        if (func_8010FDF8(0x11029)) {
    
    src/dra/71830.c line 591 at 2be55ee · upstream ↗
    17    if (branchFlags & 0x10000) {
    ⋮
    20            g_Player.padPressed & PAD_CROSS) {
    21            YAccel = FIX(22.0 / 128 / 5);
    22        } else {
    23            YAccel = FIX(22.0 / 128);
    ⋮
    31        } else {
    32            YAccel = FIX(22.0 / 128);
    ⋮
    40    PLAYER.velocityY += YAccel;
    ⋮
    42    if (PLAYER.velocityY > FIX(7)) {
    43        PLAYER.velocityY = FIX(7);
    
    src/dra/6FDF8.c lines 17–44 at 2be55ee · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  17. ^ abVertical motion is 8.8 fixed point; each frame, ImposeGravity adds speed to position, the fraction via the YMF_Dummy subpixel byte, then gravity to speed.CodeXkeeper0/smb1
    How we know
    6668	ADC SprObject_Y_MoveForce,x
    6669	STA SprObject_YMF_Dummy,x
    ⋮
    6676	ADC SprObject_Y_Position,x                   ; add vertical position to vertical speed plus carry
    ⋮
    6683	ADC $00                                      ; add downward movement amount to contents of $0433
    ⋮
    6685	LDA SprObject_Y_Speed,x                      ; add carry to vertical speed and store
    
    src/prg.asm lines 6666–6687 at 1cc3c92 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-27.

    In the claim ledger

  18. ^Each frame the player routine moves Mario by his current speed (CODE_00DC2D), then handles a jump press (CODE_00D5F2), then adds gravity (CODE_00D7E4), so the press frame doesn't lift him and his first step up is the take-off speed plus held gravity.CodeSMWDisX
    How we know
    8897CODE_00CD24:
    ⋮
    8904  + JSR CODE_00DC2D
    8905    JSR CODE_00E92B
    
    bank_00.asm lines 8897–8905 at 30643c7 · upstream ↗
    8946CODE_00CD82:
    8947    JSR CODE_00D5F2
    8948    JSR CODE_00D062
    8949    JSR CODE_00D7E4
    
    bank_00.asm lines 8946–8949 at 30643c7 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  19. ^ abIn the running game, ObjectFall and SpeedToPos move Sonic's 32-bit position each frame by his speed shifted left 8 bits, X by this frame's X speed and Y, in the air, by the Y speed before gravity, so positions are 16.16 and speeds 8.8 fixed point.Verifiedsonicretro/s1disasm · Sonic Retro, “Sonic Physics Guide: Calculations (Pixel and Subpixel)”
    How we know
    16		move.w	obVelY(a0),d0				; load vertical speed
    17		addi.w	#gravity,obVelY(a0)			; increase vertical speed (apply gravity)
    18		ext.l	d0					; extend speed to longword
    19		asl.l	#8,d0					; shift speed up a byte (16.16 fixed point)
    20		add.l	d0,d3					; add speed to Y-axis position
    
    _incObj/sub ObjectFall & SpeedToPos.asm lines 16–20 at 15dfa3a · upstream ↗
    Each pixel is effectively split into 256 slices along both axis and this means the finest fidelity available for movement is 1/256th of a pixel (aka 0.00390625).
    Pixel and Subpixel · archived copy ↗

    Measured by a script. It fails if the result disagrees with the claim.

    The numbers come from the run; its author, an AI model, checked the script measures what the claim says, 2026-10-25.

    Checked by a second AI model, 2026-10-25.

    In the claim ledger

  20. ^In each update, Player.Update ticks both jump timers, the state machine runs NormalUpdate (gravity, hold, and new jump), and then MoveV applies Speed.Y * Engine.DeltaTime.CodeNoelFB/Celeste · JamesMcMahon/monocle-engine
    How we know
    742                //Var Jump
    743                if (varJumpTimer > 0)
    744                    varJumpTimer -= Engine.DeltaTime;
    
    Source/Player/Player.cs lines 742–744 at 1b0ce45 · upstream ↗
    908            base.Update();
    
    Source/Player/Player.cs line 908 at 1b0ce45 · upstream ↗
    935                MoveV(Speed.Y * Engine.DeltaTime, onCollideV);
    
    Source/Player/Player.cs lines 934–935 at 1b0ce45 · upstream ↗
    323            StateMachine.SetCallbacks(StNormal, NormalUpdate, null, NormalBegin, NormalEnd);
    
    Source/Player/Player.cs lines 322–323 at 1b0ce45 · upstream ↗
    97            Components.Update();
    
    Monocle/Entity.cs lines 95–98 at 759c15a · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-27.

    In the claim ledger

  21. ^While a jump rises with A held, gravity is JumpMForceData's $20, $20, $1E, $28, $28 subpixels/frame² for rows 0–4.CodeXkeeper0/smb1 · Jdaster64 n.d.
    How we know
    4858JumpMForceData:
    4859	.db $20, $20, $1e, $28, $28, $0d, $04
    
    src/prg.asm lines 4858–4859 at 1cc3c92 · upstream ↗
    4966	LDA JumpMForceData,y                         ; store appropriate jump/swim
    4967	STA VerticalForce                            ; data here
    
    src/prg.asm lines 4966–4967 at 1cc3c92 · upstream ↗
    00200 | 001E0 | 00280
    JUMPING/VERTICAL PHYSICS, Mario table, Holding “A” Gravity (+Y) · archived copy ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-27.

    In the claim ledger

  22. ^After the switch, gravity is FallMForceData's $70, $70, $60, $90, $90 subpixels/frame² for rows 0–4.CodeXkeeper0/smb1 · Jdaster64 n.d.
    How we know
    4861FallMForceData:
    4862	.db $70, $70, $60, $90, $90, $0a, $09
    
    src/prg.asm lines 4861–4862 at 1cc3c92 · upstream ↗
    4968	LDA FallMForceData,y
    4969	STA VerticalForceDown
    
    src/prg.asm lines 4968–4969 at 1cc3c92 · upstream ↗
    00700 | 00600 | 00900
    JUMPING/VERTICAL PHYSICS, Mario table, Falling Gravity (+Y) · archived copy ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-27.

    In the claim ledger

  23. ^MovePlayerVertically gives ImposeGravity 4 px/frame as Mario's maximum fall speed; the clamp sets the speed back to 4 only when its whole part is at least 4 and its fraction byte at least $80.CodeXkeeper0/smb1 · Jdaster64 n.d.revised
    How we know
    6549	LDA #$04                                     ; set maximum vertical speed here
    6550	JMP ImposeGravitySprObj                      ; then jump to move player vertically
    
    src/prg.asm lines 6547–6550 at 1cc3c92 · upstream ↗
    6688	CMP $02                                      ; compare to maximum speed
    ⋮
    6691	CMP #$80                                     ; if less positively than preset maximum, skip this part
    ⋮
    6694	STA SprObject_Y_Speed,x                      ; keep vertical speed within maximum value
    ⋮
    6696	STA SprObject_Y_MoveForce,x                  ; clear fractional
    
    src/prg.asm lines 6688–6696 at 1cc3c92 · upstream ↗
    their vertical downward velocity caps at 04800 in most cases, wrapping back to 04000 when exceeded
    JUMPING/VERTICAL PHYSICS · archived copy ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Revised after a check by a second AI model, 2026-10-27: The clamp sets the speed back to 4 only when its whole part is at least 4 and its fraction at least $80, so 4 px/frame alone overstated it.

    In the claim ledger

  24. ^ abcIn the running game, ObjectFall's gravity equate adds $38 (0.21875 px/frame²) to Sonic's Y speed on every airborne frame, rising or falling, after a jump or off a ledge, button held or not.Verifiedsonicretro/s1disasm · Sonic Retro, “Sonic Physics Guide: Air State”
    How we know
    5gravity:	equ	$38				; gravity constant used by many objects
    
    _incObj/sub ObjectFall & SpeedToPos.asm line 5 at 15dfa3a · upstream ↗
    363		jsr	(ObjectFall).l				; apply gravity and update Sonic's position based on his current velocities
    
    _incObj/01 Sonic.asm line 363 at 15dfa3a · upstream ↗
    gravity_force 0.21875 (56 subpixels)
    Constants · archived copy ↗

    Measured by a script. It fails if the result disagrees with the claim.

    The numbers come from the run; its author, an AI model, checked the script measures what the claim says, 2026-10-25.

    Checked by a second AI model, 2026-10-25.

    In the claim ledger

  25. ^In the running game, a Y speed written into a jump, −$1100 rising or $FC0 falling, is neither capped nor clamped: gravity keeps adding $38, to −$10C8 a frame later and to $1068 before he lands, because Sonic_JumpHeight skips its −$FC0 cap after jumps (FixBugs = 0).Verifiedsonicretro/s1disasm · Sonic Retro, “Sonic Physics Guide: Air State”revised
    How we know
    1291.return:
    1292	if FixBugs=0
    1293		; This prevents the max Y-vel cap from running while jumping
    1294		rts						; return
    ⋮
    1300		cmpi.w	#-$FC0,obVelY(a0)			; is Sonic moving up just below the maximum screen scroll speed? (-$1000)
    
    _incObj/01 Sonic.asm lines 1291–1302 at 15dfa3a · upstream ↗
    In Sonic 1, the Player's Y Speed is not limited.
    Top Y Speed · archived copy ↗

    Measured by a script. It fails if the result disagrees with the claim.

    The numbers come from the run; its author, an AI model, checked the script measures what the claim says, 2026-10-25.

    Revised after a check by a second AI model, 2026-10-25.

    In the claim ledger

  26. ^Celeste's gravity is 900 px/s²; each airborne update moves vertical speed toward the fall limit by Gravity * mult * Engine.DeltaTime.CodeNoelFB/Celeste
    How we know
    24        private const float Gravity = 900f;
    
    Source/Player/Player.cs line 24 at 1b0ce45 · upstream ↗
    2957                    Speed.Y = Calc.Approach(Speed.Y, max, Gravity * mult * Engine.DeltaTime);
    
    Source/Player/Player.cs line 2957 at 1b0ce45 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-27.

    In the claim ledger

  27. ^MaxFall, the normal limit on falling speed, is 160 px/s; NormalBegin starts maxFall there and gravity approaches it.CodeNoelFB/Celeste
    How we know
    23        public const float MaxFall = 160f;
    
    Source/Player/Player.cs line 23 at 1b0ce45 · upstream ↗
    2762            maxFall = MaxFall;
    
    Source/Player/Player.cs lines 2760–2763 at 1b0ce45 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-27.

    In the claim ledger

  28. ^Celeste's actors sit on whole pixels; MoveV adds the float distance to a remainder, moves by its rounded value, and keeps the fraction.Dev blogThorson 2020 · NoelFB/Celeste
    How we know
    xRemainder += amount; int move = Round(xRemainder); if (move != 0) { xRemainder -= move;
    Actor Basics · archived copy ↗
    935                MoveV(Speed.Y * Engine.DeltaTime, onCollideV);
    
    Source/Player/Player.cs line 935 at 1b0ce45 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-27.

    In the claim ledger

  29. ^ImposeGravity clamps a fall of 4 px/frame or more only when the fraction byte is at least $80.CodeXkeeper0/smb1 · Jdaster64 n.d.
    How we know
    6688	CMP $02                                      ; compare to maximum speed
    6689	BMI ChkUpM                                   ; if less than preset value, skip this part
    6690	LDA SprObject_Y_MoveForce,x
    6691	CMP #$80                                     ; if less positively than preset maximum, skip this part
    6692	BCC ChkUpM
    
    src/prg.asm lines 6688–6696 at 1cc3c92 · upstream ↗
    their vertical downward velocity caps at 04800 in most cases, wrapping back to 04000 when exceeded
    JUMPING/VERTICAL PHYSICS · archived copy ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-27.

    In the claim ledger

  30. ^ abJumpSwimSub swaps in falling gravity, never back, once speed is zero or downward, or once the jump has risen at least DiffToHaltJump on a frame when A is not held, or was not held the frame before.CodeXkeeper0/smb1 · Jdaster64 n.d.revised
    How we know
    4757	BPL DumpFall                                 ; or moving downwards, branch to falling
    ⋮
    4760	AND PreviousA_B_Buttons                      ; and was pressed in previous frame
    4761	BNE ProcSwim                                 ; if so, branch elsewhere
    ⋮
    4765	CMP DiffToHaltJump                           ; compare to value set here to see if player is in mid-jump
    ⋮
    4768	LDA VerticalForceDown                        ; otherwise dump falling into main fractional
    4769	STA VerticalForce
    
    src/prg.asm lines 4756–4769 at 1cc3c92 · upstream ↗
    so long as they are moving upward in a jump, holding “A” will make them rise more slowly
    JUMPING/VERTICAL PHYSICS · archived copy ↗

    Checked against the evidence by its author, an AI model, 2026-10-27.

    Revised after a check by a second AI model, 2026-10-27: "Not held both this frame and last" read two ways; held gravity stays only while A is held on both frames.

    In the claim ledger

  31. ^Gravity halves while |Speed.Y| is under HalfGravThreshold and jump is held (or auto-jump is on), so a held jump hangs at the top.CodeNoelFB/Celeste
    How we know
    2952                    float mult = (Math.Abs(Speed.Y) < HalfGravThreshold && (Input.Jump.Check || AutoJump)) ? .5f : 1f;
    
    Source/Player/Player.cs line 2952 at 1b0ce45 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-27.

    In the claim ledger

  32. ^A jump sets Banjo's vertical speed to 710 units/s (610 from water) and his gravity to −1350 units/s², half the usual −2700, and sets his horizontal speed at once to the target speed the stick gives on the ground (banjo-kazooie/walking-speed). On a frame of the jump with A up while he still rises, bsjump_update resets the gravity to −2700 for the rest of the jump; nothing sets −1350 again, and with A held the lighter gravity lasts past the peak. Until Banjo has learned the ability the code names ABILITY_A_HOLD_A_JUMP_HIGHER, it resets the gravity every frame. A jump entered from a peck sets neither the speed nor the gravity. A take-off from a spring pad sets a flag that skips the reset; the first frame with A up clears it after the check, so the reset starts the frame after. While that flag is set, the jump's second phase turns into the Shock Spring Jump's charge (BS_21_BSHOCK_CHARGE). Leaving the jump state for anything but a peck restores −2700. Computed without the frame steps, a held jump rises about 187 units in 0.53 s, and one released at once about 93. Super Mario 64 instead adds a quarter of the forward speed to its take-off (sm64/jump-speed) and divides the rise by 4 on each frame A is up while Mario rises faster than 20 units/frame (sm64/jump-release).Codebanjo.decomp/banjo-kazooie · n64decomp/sm64revised
    How we know
    20f32 D_80364CD0 =   710.0f;
    21f32 D_80364CD4 = -1350.0f;
    
    src/core2/bs/jump.c lines 20–21 at e8d31fa · upstream ↗
    25f32 D_80364CE4 =   610.0f;
    
    src/core2/bs/jump.c line 25 at e8d31fa · upstream ↗
    41    D_8037D4C2 = baflag_isTrue(BA_FLAG_2_ON_SPRING_PAD);
    
    src/core2/bs/jump.c line 41 at e8d31fa · upstream ↗
    47    if(sp30 == BS_11_BPECK){
    ⋮
    52        D_8037D4C0 = 1;
    ⋮
    54    else {
    
    src/core2/bs/jump.c lines 47–54 at e8d31fa · upstream ↗
    55        D_8037D4C1 = (sp30 == BS_2D_SWIM_IDLE) || (sp30 == BS_2E_SWIM);
    
    src/core2/bs/jump.c line 55 at e8d31fa · upstream ↗
    69        func_802B6FA8();
    70        baphysics_set_horizontal_velocity(yaw_getIdeal(), baphysics_get_target_horizontal_velocity());
    71        if(D_8037D4C1){
    72            baphysics_set_vertical_velocity(D_80364CE4);
    73        } else {
    74            baphysics_set_vertical_velocity(D_80364CD0);
    ⋮
    76        baphysics_set_gravity(D_80364CD4);
    
    src/core2/bs/jump.c lines 69–76 at e8d31fa · upstream ↗
    101    baphysics_get_velocity(velocity);
    102    if((bakey_released(BUTTON_A) && 0.0f < velocity[1] && !D_8037D4C2) || !can_control_jump_height()){
    103        baphysics_reset_gravity();
    
    src/core2/bs/jump.c lines 101–104 at e8d31fa · upstream ↗
    121        case 1://L802B14B4
    122            if( 500.0f < (playerPosition_getY() - func_80294438())){
    123                sp34 = BS_2F_FALL;
    ⋮
    125            if(D_8037D4C2){
    126                D_8037D4C2 = 0;
    127                sp34 = BS_21_BSHOCK_CHARGE;
    
    src/core2/bs/jump.c lines 121–128 at e8d31fa · upstream ↗
    143    if(bakey_released(BUTTON_A))
    144        D_8037D4C2 = 0;
    
    src/core2/bs/jump.c lines 143–144 at e8d31fa · upstream ↗
    171    if (bs_getNextState() != BS_11_BPECK) {
    172        baphysics_reset_gravity();
    
    src/core2/bs/jump.c lines 171–173 at e8d31fa · upstream ↗
    50        bakey.released_count[i] = bakey.pressed_count[i]
    51            ? 0
    52            : bakey.released_count[i] + 1;
    
    src/core2/bakey.c lines 50–52 at e8d31fa · upstream ↗
    79int bakey_released(s32 button_indx){
    80    return bakey.released_count[button_indx];
    
    src/core2/bakey.c lines 79–81 at e8d31fa · upstream ↗
    10f32 baphysics_default_gravity = -2700.0f; //defaultGravity
    11f32 baphysics_default_terminal_velocity = -4000.0f;
    
    src/core2/ba/physics.c lines 10–11 at e8d31fa · upstream ↗
    397void baphysics_reset_gravity(void){
    398    baphysics_set_gravity(baphysics_default_gravity);
    
    src/core2/ba/physics.c lines 397–399 at e8d31fa · upstream ↗
    67s32 can_control_jump_height(void){
    68    return ability_hasLearned(ABILITY_A_HOLD_A_JUMP_HIGHER);
    
    src/core2/playerutils.c lines 67–68 at e8d31fa · upstream ↗
    821        case ACT_JUMP:
    822        case ACT_HOLD_JUMP:
    ⋮
    824            set_mario_y_vel_based_on_fspeed(m, 42.0f, 0.25f);
    825            m->forwardVel *= 0.8f;
    
    src/game/mario.c lines 821–826 at 9921382 · upstream ↗
    559    } else if (should_strengthen_gravity_for_jump_ascent(m)) {
    560        m->vel[1] /= 4.0f;
    
    src/game/mario_step.c lines 559–560 at 9921382 · upstream ↗
    528    if (!(m->input & INPUT_A_DOWN) && m->vel[1] > 20.0f) {
    529        return (m->action & ACT_FLAG_CONTROL_JUMP_HEIGHT) != 0;
    
    src/game/mario_step.c lines 528–529 at 9921382 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Revised after a check by a second AI model, 2026-10-22.

    In the claim ledger

  33. ^ abEach frame of a jump, button held or not, Player_Jumping adds PLAYER_GRAVITY, 42/256 px/frame² (12/256 in water), to the vertical speed through PLAYERFN_UPDATE_AIR_FALL_SPEED, except on a frame where Sonic's forward thrust or a mid-air move starts (Player_Sonic_TryForwardThrust, Player_TryMidAirAction): Player_Jumping returns before the gravity then. That is three quarters of the gravity Sonic 1's airborne-rolling mode, Sonic_MdJump2, adds through ObjectFall, $38 (56/256) a frame (computed).CodeSAT-R/sa2 · sonicretro/s1disasmrevised
    How we know
    18#define PLAYER_GRAVITY             (42.0 / 256.0)
    19#define PLAYER_GRAVITY_UNDER_WATER (12.0 / 256.0)
    
    include/game/shared/parameters/characters.h lines 18–19 at 393357f · upstream ↗
    200#elif (GAME == GAME_SA2)
    201#ifndef COLLECT_RINGS_ROM
    202#define PLAYERFN_UPDATE_AIR_FALL_SPEED(player)                                                                                             \
    203    if (player->moveState & MOVESTATE_IN_WATER) {                                                                                          \
    204        player->qSpeedAirY += Q(PLAYER_GRAVITY_UNDER_WATER);                                                                               \
    205    } else {                                                                                                                               \
    206        player->qSpeedAirY += Q(PLAYER_GRAVITY);                                                                                           \
    
    src/game/shared/stage/player.c lines 200–207 at 393357f · upstream ↗
    7017    if (p->moveState & MOVESTATE_100) {
    7018#ifndef COLLECT_RINGS_ROM
    7019        if (gGameMode != GAME_MODE_MULTI_PLAYER_COLLECT_RINGS)
    7020            if (Player_Sonic_TryForwardThrust(p) || Player_TryMidAirAction(p))
    7021                return;
    
    src/game/shared/stage/player.c lines 7017–7021 at 393357f · upstream ↗
    7039    SA2_LABEL(sub_80232D0)(p);
    ⋮
    7041    PLAYERFN_UPDATE_AIR_FALL_SPEED(p);
    7042    PLAYERFN_UPDATE_POSITION(p);
    
    src/game/shared/stage/player.c lines 7039–7042 at 393357f · upstream ↗
    5gravity:	equ	$38				; gravity constant used by many objects
    
    _incObj/sub ObjectFall & SpeedToPos.asm line 5 at 15dfa3a · upstream ↗
    359Sonic_MdJump2:	; While Sonic is in the air and rolling (usually, but not limited to, jumping)
    ⋮
    363		jsr	(ObjectFall).l				; apply gravity and update Sonic's position based on his current velocities
    
    _incObj/01 Sonic.asm lines 359–363 at 15dfa3a · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Revised after a check by a second AI model, 2026-10-22.

    In the claim ledger

  34. ^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).Codemetroidret/mf · metroidret/mzm
    How we know
    326#define SAMUS_Y_ACCELERATION (SUB_PIXEL_TO_VELOCITY(ONE_SUB_PIXEL * .75f))
    327#define SAMUS_Y_VELOCITY_CAP (SUB_PIXEL_TO_VELOCITY(QUARTER_BLOCK_SIZE))
    ⋮
    335#define SAMUS_TERMINAL_VELOCITY (SUB_PIXEL_TO_VELOCITY(HALF_BLOCK_SIZE - PIXEL_SIZE - ONE_SUB_PIXEL / 2.f))
    
    include/constants/samus.h lines 326–335 at a6d6187 · upstream ↗
    137    switch (currentHazard)
    ⋮
    139        case HAZARD_WATER:
    140            gSamusUnderwaterFlag++;
    ⋮
    142        case HAZARD_LAVA:
    143        case HAZARD_ACID:
    144            if (!(gEquipment.suitMiscStatus & (SMF_GRAVITY_SUIT | SMF_SA_X_SUIT)))
    145                slowed++;
    146            break;
    ⋮
    151                slowed++;
    ⋮
    160        gSamusPhysics.yAcceleration = SAMUS_Y_ACCELERATION * 2.f / 3;
    161        gSamusPhysics.yVelocityCap = SAMUS_Y_VELOCITY_CAP * 0.375f;
    ⋮
    174        gSamusPhysics.yAcceleration = SAMUS_Y_ACCELERATION;
    ⋮
    
    src/samus.c lines 137–175 at a6d6187 · upstream ↗
    5526            // Check is within the bounds
    5527            if (gSamusData.yVelocity > gSamusPhysics.yVelocityCap)
    ⋮
    5529            else if (gSamusData.yVelocity < -gSamusPhysics.yVelocityCap)
    5530                velocity = VELOCITY_TO_SUB_PIXEL(-gSamusPhysics.yVelocityCap);
    5531            else
    ⋮
    5534            // Apply acceleration
    5535            if (gSamusData.yVelocity > -SAMUS_TERMINAL_VELOCITY)
    5536                gSamusData.yVelocity -= gSamusPhysics.yAcceleration;
    ⋮
    5538            gSamusData.yPosition -= velocity;
    
    src/samus.c lines 5526–5538 at a6d6187 · upstream ↗
    324#define SAMUS_Y_ACCELERATION 10
    325#define SAMUS_Y_POSITIVE_VELOCITY_CAP 192
    326#define SAMUS_Y_NEGATIVE_VELOCITY_CAP 128
    327#define SAMUS_Y_SLOWED_VELOCITY_CAP 40
    
    include/constants/samus.h lines 324–327 at 2aae289 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  35. ^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.Codemetroidret/mzm · nmikstas/metroid-disassembly
    How we know
    324#define SAMUS_Y_ACCELERATION 10
    325#define SAMUS_Y_POSITIVE_VELOCITY_CAP 192
    326#define SAMUS_Y_NEGATIVE_VELOCITY_CAP 128
    327#define SAMUS_Y_SLOWED_VELOCITY_CAP 40
    
    include/constants/samus.h lines 324–327 at 2aae289 · upstream ↗
    2649        case HAZARD_TYPE_WATER:
    2650        case HAZARD_TYPE_LAVA:
    2651        case HAZARD_TYPE_WEAK_ACID:
    2652        case HAZARD_TYPE_STRONG_ACID:
    2653            // In liquid, check has gravity to see if slowed
    2654            if (!(pEquipment->suitMiscActivation & SMF_GRAVITY_SUIT))
    2655                slowed++;
    2656#ifndef BUGFIX
    2657            break;
    2658#endif
    ⋮
    2660        default:
    2661            // Check grabbed by metroid
    ⋮
    
    src/samus.c lines 2649–2697 at 2aae289 · upstream ↗
    6762            else if (pData->yVelocity < -gSamusPhysics.negativeYVelocityCap)
    ⋮
    6764                velocity = DIV_SHIFT(-gSamusPhysics.negativeYVelocityCap, 8);
    ⋮
    6766            else
    ⋮
    6771            if (pData->yVelocity >= -231)
    ⋮
    6773                pData->yVelocity -= gSamusPhysics.yAcceleration;
    ⋮
    6776            pData->yPosition -= velocity;
    
    src/samus.c lines 6762–6776 at 2aae289 · upstream ↗
    2693LCFF3:  LDY #$18                ; gravity (high value -> low jump)
    2694        LDA SamusGear
    2695        AND #gr_HIGHJUMP
    2696        BEQ +                   ; branch if Samus doesn't have High Jump
    2697        LDY #$12                ; lower gravity value -> high jump!
    2698*       STY SamusGravity
    
    Source_Files/Bank07.asm lines 2693–2698 at 4270d57 · upstream ↗
    5582;gravity used in the acceleration calculation. The higher the number, the more intense the gravity.
    5583;The possible values for gravity are as follows:
    5584;#$38-When Samus has been hit by an enemy.
    5585;#$1A-When Samus is falling.
    5586;#$18-Jump without high jump boots.
    5587;#$12-Jump with high jump boots.
    
    Source_Files/Bank07.asm lines 5582–5587 at 4270d57 · upstream ↗
    5628LE3C9:* cmp #$05            ;Has maximum downward speed been reached?
    5629LE3CB:* bcc +               ;If not, branch.
    
    Source_Files/Bank07.asm lines 5628–5629 at 4270d57 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-25.

    Checked by a second AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-25.

    In the claim ledger

  36. ^With the weightless flag clear, a fall (action 4) adds 3 px per cycle to the kid's downward speed, up to 33 px per cycle (AccelGravity, TermVelocity); with it set, gravity is 1 and the cap 4 (WtlessGravity, WtlessTermVel). The fall sequences that start it set the speed to 15 (setfall). In any other action, including the jumps' (action 1) and a fall's first frames (action 3), gravity does nothing.Codejmechner/Prince-of-Persia-Apple-IIrevised
    How we know
    1613TermVelocity = 33
    1614AccelGravity = 3
    1615WtlessTermVel = 4
    1616WtlessGravity = 1
    ⋮
    1618GRAVITY
    1619 lda CharAction
    1620 cmp #4
    1621 bne ]rts
    ⋮
    1626 lda CharYVel
    1627 clc
    1628 adc #AccelGravity
    ⋮
    1630 cmp #TermVelocity
    ⋮
    
    01 POP Source/Source/SUBS.S lines 1613–1644 at 2524355 · upstream ↗
    640stepfall ;from #8 (run-11)
    641 db act,3
    642 db chx,1,chy,3
    ⋮
    646fall1
    647 db 102,chx,2,chy,6
    648 db 103,chx,-1,chy,9
    649 db 104,chy,12
    650 db 105,chx,-2
    ⋮
    652 db setfall,1,15
    653 db goto
    654 dw freefall
    
    01 POP Source/Source/SEQTABLE.S lines 640–654 at 2524355 · upstream ↗
    882freefall
    883 db act,4
    884:loop db 106
    
    01 POP Source/Source/SEQTABLE.S lines 882–884 at 2524355 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Revised after a check by a second AI model, 2026-10-22.

    In the claim ledger

  37. ^ abIn the doldecomp decompilation of Super Mario Sunshine, most of Mario's movement constants are named parameters (TParamRT), each built with a default in the code, in sets that each name a file, such as /Mario/Jump.prm. TParams::load, in a file configure.py marks as matching the game's code, reads the set's file from the scene's /map/params folder if it is there and from the params archive if not, and a record whose key and name match a parameter replaces that parameter's default; the rest keep theirs. The values the game plays with are data on the disc, which the atlas hasn't read, so the numbers in these claims are the code's defaults. The jump set's gravity, mGravity, defaults to 0.8. In the jumping states, jumpProcess in the decompilers' Player code, which doesn't yet match, moves Mario by a quarter of his velocity in one step per update. Then fallProcess subtracts mGravity from his vertical speed, except in a dive (the dive set's own gravity, with a cap of its own), in a spin jump's descent (mSpinJumpGravity, default 0.6), and when a release cuts the rise (sms/jump); in every case it then caps the fall at −75. Super Mario 64 also moves Mario a quarter of his velocity at a time, but in four steps a frame (sm64/units).Code notesdoldecomp/sms · n64decomp/sm64revised
    How we know
    314Matching = True                   # Object matches and should be linked
    315NonMatching = False               # Object does not match and should not be linked
    
    configure.py lines 314–315 at d2cc8f5 · upstream ↗
    879            Object(Matching, "System/Params.cpp"),
    
    configure.py line 879 at d2cc8f5 · upstream ↗
    950            Object(NonMatching, "Player/MarioPhysics.cpp"),
    
    configure.py line 950 at d2cc8f5 · upstream ↗
    964            PCHObject(NonMatching, "Player/MarioInit.cpp"),
    
    configure.py line 964 at d2cc8f5 · upstream ↗
    8#define PARAM_INIT(member, defaultValue)                                       \
    9	member(this, defaultValue, JDrama::TNameRef::calcKeyCode(#member), #member)
    
    include/System/ParamInst.hpp lines 8–9 at d2cc8f5 · upstream ↗
    12	if (mHead != nullptr) {
    13		s32 length = stream.readS32();
    14		for (int i = 0; i < length; i++) {
    15			u16 keyCode = stream.read16b();
    ⋮
    21				if (keyCode == param->keyCode && !strcmp(buffer, param->name)) {
    22					param->load(stream);
    23					break;
    ⋮
    26			if (param == nullptr) {
    27				s32 end = stream.read32b();
    28				stream.skip(end);
    
    src/System/Params.cpp lines 12–29 at d2cc8f5 · upstream ↗
    54	if (mSceneArc != nullptr && mSceneArc->becomeCurrent(SceneParamsDir)) {
    55		resource = mSceneArc->getResource(filename);
    ⋮
    64		if (mArc != nullptr) {
    65			mArc->becomeCurrent("/");
    66			void* resource2 = mArc->getResource(filename);
    
    src/System/Params.cpp lines 54–66 at d2cc8f5 · upstream ↗
    5static const char SceneParamsDir[] = "/map/params";
    
    src/System/Params.cpp line 5 at d2cc8f5 · upstream ↗
    544TMario::TJumpParams::TJumpParams()
    545    : TParams("/Mario/Jump.prm")
    546    , PARAM_INIT(mGravity, 0.8f)
    547    , PARAM_INIT(mSpinJumpGravity, 0.6f)
    
    src/Player/MarioInit.cpp lines 544–547 at d2cc8f5 · upstream ↗
    498	Vec next;
    499	next.x  = mPosition.x + 0.25f * mVel.x;
    500	next.y  = mPosition.y + 0.25f * mVel.y;
    501	next.z  = mPosition.z + 0.25f * mVel.z;
    502	int ret = checkGroundAtJumping(next, param_1);
    ⋮
    509	fallProcess();
    
    src/Player/MarioPhysics.cpp lines 498–509 at d2cc8f5 · upstream ↗
    464void TMario::fallProcess()
    ⋮
    466	if (mStatus == MARIO_STATUS_DIVE) {
    467		mVel.y -= mDivingParams.mGravity.get();
    468		if (mVel.y < -75.0f)
    469			mVel.y = -75.0f;
    470	} else {
    471		if (isFallCancel()) {
    472			mVel.y *= 0.75f;
    473		} else if ((mStatus == MARIO_STATUS_LEFT_ROTATE_JUMP
    474		            || mStatus == MARIO_STATUS_RIGHT_ROTATE_JUMP)
    475		           && mVel.y < 0.0f) {
    476			mVel.y -= mJumpParams.mSpinJumpGravity.get();
    ⋮
    
    src/Player/MarioPhysics.cpp lines 464–485 at d2cc8f5 · upstream ↗
    618    for (i = 0; i < 4; i++) {
    619        intendedPos[0] = m->pos[0] + m->vel[0] / 4.0f;
    620        intendedPos[1] = m->pos[1] + m->vel[1] / 4.0f;
    621        intendedPos[2] = m->pos[2] + m->vel[2] / 4.0f;
    
    src/game/mario_step.c lines 618–621 at 9921382 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Revised after a check by a second AI model, 2026-10-22.

    In the claim ledger

Sources

Code

Primary

Secondary