Slope physics
A platformer rule that adds or takes away ground speed on a slope, by how steep it is and which way the character moves.
On this page
Slope physics adds the slope’s pull to the ground speed each frame: a gain downhill, a loss uphill. In Sonic the Hedgehog the pull is the sine of the angle times a factor, larger while rolling, and a standing Sonic feels none1. Sonic 2 keeps the code2. Sonic 3 & Knuckles pushes a standing player on a steep enough slope3 and lets a slow one slip rather than fall4.
- Moving onlySonic the Hedgehog (1991). Slopes push a running or rolling Sonic, a rolling one harder downhill and softer uphill, and leave a standing one alone.1Sonic the Hedgehog 2 (1992). Slopes push a running or rolling Sonic and leave a standing one alone; too slow on a wall or ceiling, he drops off.2,5
- Even standingSonic 3 & Knuckles (1994). A steep slope pushes even a standing player, and a slow climber slips back down.3,4
Games
| Game | Year | How | Note |
|---|---|---|---|
| Sonic the Hedgehog | 1991 | Moving only | slopes push a running or rolling Sonic, a rolling one harder downhill and softer uphill, and leave a standing one alone |
| Sonic the Hedgehog 2 | 1992 | Moving only | slopes push a running or rolling Sonic and leave a standing one alone; too slow on a wall or ceiling, he drops off |
| Sonic 3 & Knuckles | 1994 | Even standing | a steep slope pushes even a standing player, and a slow climber slips back down |
Every claim about this mechanic, by game (6)
References
- ^ abIn the running game, on a 45° ramp built from Green Hill's
$E0ramp block, every ground frame's ground speed matched the flat-ground rules after a slope term of the sine of his angle times$20while he ran,$50while he rolled downhill and a quarter of that uphill; standing still on the ramp for 60 frames, he didn't move.Verifiedsonicretro/s1disasmHow we know
1330 jsr (CalcSine).l ; get sine and cosine values for angle 1331 muls.w #$20,d0 ; multiply by resist force while walking 1332 asr.l #8,d0 ; shift down a byte ⋮ 1334 tst.w obInertia(a0) ; check Sonic's ground speed 1335 beq.s .return ; if he's standing still, branch
_incObj/01 Sonic.asm lines 1329–1339 at 15dfa3a · upstream ↗ 1369 muls.w #$50,d0 ; multiply by resist force while rolling (2.5x larger than walking) ⋮ 1376 asr.l #2,d0 ; reduce resist force while ascending a slope
_incObj/01 Sonic.asm lines 1369–1376 at 15dfa3a · upstream ↗ 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-21.
Checked by a second AI model, 2026-10-22.
Checked by a second AI model, 2026-10-25.
- ^ abOn a slope Sonic's ground speed gains the sine of the angle times
$20a frame while he runs and$50while he rolls downhill (a quarter of that uphill), with nothing while he stands; the code matches Sonic 1's.Codesonicretro/s2disasm · sonicretro/s1disasmHow we know
37755 move.b angle(a0),d0 ⋮ 37759 move.b angle(a0),d0 37760 jsr (CalcSine).l 37761 muls.w #$20,d0 37762 asr.l #8,d0 37763 tst.w inertia(a0) 37764 beq.s return_1ADCA
s2.asm lines 37754–37768 at 4ef457c · upstream ↗ 37794 muls.w #$50,d0 37795 asr.l #8,d0 37796 tst.w inertia(a0) 37797 bmi.s loc_1ADFC 37798 tst.w d0 37799 bpl.s loc_1ADF6 37800 asr.l #2,d0
s2.asm lines 37787–37803 at 4ef457c · upstream ↗ 1331 muls.w #$20,d0 ; multiply by resist force while walking ⋮ 1335 beq.s .return ; if he's standing still, branch ⋮ 1369 muls.w #$50,d0 ; multiply by resist force while rolling (2.5x larger than walking)
_incObj/01 Sonic.asm lines 1323–1392 at 15dfa3a · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^ abUnlike Sonic 1 and Sonic 2, a standing player slides on a slope whose push, sine ×
$20, is at least$D; the walking and rolling factors stay$20and$50.Codesonicretro/skdisasm · sonicretro/s2disasm · sonicretro/s1disasmrevisedHow we know
23868 muls.w #$20,d0 23869 asr.l #8,d0 23870 tst.w ground_vel(a0) 23871 beq.s loc_11DDC ⋮ 23875 add.w d0,ground_vel(a0) ⋮ 23882 add.w d0,ground_vel(a0) ⋮ 23888loc_11DDC: 23889 move.w d0,d1 23890 bpl.s loc_11DE2 23891 neg.w d1 ⋮ 23893loc_11DE2: 23894 cmpi.w #$D,d1 ⋮
sonic3k.asm lines 23866–23896 at 73de97c · upstream ↗ 23914 muls.w #$50,d0sonic3k.asm line 23914 at 73de97c · upstream ↗ 37763 tst.w inertia(a0) 37764 beq.s return_1ADCA
s2.asm lines 37763–37764 at 4ef457c · upstream ↗ 1334 tst.w obInertia(a0) ; check Sonic's ground speed 1335 beq.s .return ; if he's standing still, branch
_incObj/01 Sonic.asm lines 1334–1335 at 15dfa3a · 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.
- ^ abBelow
$280ground speed on a steep slope the player now slips, a$80push along the slope and a 30-frame d-pad lock, and falls off only near walls and ceilings; Sonic 1 and 2 dropped him from any slope past 45°.Codesonicretro/skdisasm · sonicretro/s2disasm · sonicretro/s1disasmrevisedHow we know
23953 move.b angle(a0),d0 23954 addi.b #$18,d0 23955 cmpi.b #$30,d0 23956 blo.s locret_11E6E ⋮ 23962 cmpi.w #$280,d0 23963 bhs.s locret_11E6E 23964 move.w #30,move_lock(a0) 23965 move.b angle(a0),d0 23966 addi.b #$30,d0 23967 cmpi.b #$60,d0 23968 blo.s loc_11E70 23969 bset #Status_InAir,status(a0) ⋮
sonic3k.asm lines 23953–23983 at 73de97c · upstream ↗ 37833 addi.b #$20,d0 37834 andi.b #$C0,d0 ⋮ 37839 clr.w inertia(a0) 37840 bset #status.player.in_air,status(a0)
s2.asm lines 37832–37841 at 4ef457c · upstream ↗ 1413 addi.b #$20,d0 ; rotate it by 45 degrees 1414 andi.b #$C0,d0 ; snap to nearest multiple of 90 degrees ⋮ 1425 clr.w obInertia(a0) ; clear ground speed 1426 bset #status_in_air_bit,obStatus(a0) ; set in-air flag to detach Sonic from wall
_incObj/01 Sonic.asm lines 1412–1427 at 15dfa3a · 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.
- ^On a wall or ceiling below
$280(2.5 px/frame) ground speed,Sonic_SlopeRepelzeroes the speed, drops Sonic off, and locks the d-pad for 30 frames, as in Sonic 1.Codesonicretro/s2disasm · sonicretro/s1disasmHow we know
37833 addi.b #$20,d0 37834 andi.b #$C0,d0 ⋮ 37837 cmpi.w #$280,d0 ⋮ 37839 clr.w inertia(a0) 37840 bset #status.player.in_air,status(a0) 37841 move.w #$1E,move_lock(a0)
s2.asm lines 37832–37841 at 4ef457c · upstream ↗ 1423 cmpi.w #$280,d0 ; is Sonic's ground speed high enough?_incObj/01 Sonic.asm lines 1412–1427 at 15dfa3a · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
Sources
Code
- Sonic Retro contributors. 2026. “s1disasm: Sonic the Hedgehog (16-bit) disassembly (sonicretro/s1disasm).” Commit 15dfa3a. sonicretro/s1disasm @ 15dfa3a · licence, all uses
- Sonic Retro contributors. 2026. “s2disasm: Sonic the Hedgehog 2 (16-bit) disassembly (sonicretro/s2disasm).” Commit 4ef457c. sonicretro/s2disasm @ 4ef457c · licence, all uses
- Sonic Retro contributors. 2026. “skdisasm: Sonic 3 & Knuckles disassembly (sonicretro/skdisasm).” Commit 73de97c. sonicretro/skdisasm @ 73de97c · licence, all uses