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

Rolling curls the character into a ball that keeps the speed it had. In Sonic the Hedgehog Down at speed starts a roll1, which can’t accelerate and slows by a small friction whatever is held2. Sonic 2 and Sonic 3 & Knuckles keep the numbers3,4. Slopes push a roll harder than a run5.

Interactive: movement-lab (needs JavaScript)

A roll against a run
  • Slopes onlySonic the Hedgehog (1991). Down at speed curls Sonic up; on flat ground a roll never speeds up, only slows.1,2,6Sonic the Hedgehog 2 (1992). Down while moving curls Sonic up; on flat ground a roll only slows.7,3Sonic 3 & Knuckles (1994). Down curls him only at twice Sonic 2's speed, and a slowing roll stands him up before it stops.4,8,9

Games

GameYearHowNote
Sonic the Hedgehog1991Slopes onlyDown at speed curls Sonic up; on flat ground a roll never speeds up, only slows
Sonic the Hedgehog 21992Slopes onlyDown while moving curls Sonic up; on flat ground a roll only slows
Sonic 3 & Knuckles1994Slopes onlyDown curls him only at twice Sonic 2's speed, and a slowing roll stands him up before it stops
Every claim about this mechanic, by game (7)
Sonic the Hedgehog 2 1992Rolling, Sonic slows by half his acceleration ($6) a frame, by $20 more against the d-pad, and his X speed is clamped to $1000 (16 px/frame).Code
Sonic curls into a roll when Down is held without Left or Right and his ground speed is at least $80 either way, as in Sonic 1.Code
A frame-by-frame model of Obj01_MdNormal_Checks, Obj01_MdNormal, Obj01_MdRoll, and the air modes, with Sonic_Animate's timing for the standing and blinking animations, matches Sonic the Hedgehog 2 itself, run in MAME with Sonic alone on a floor built of Emerald Hill Act 1's blocks, on every frame of the movement lab's flat-ground presets, eleven scripts of Sonic 2's own moves, and 100 random input scripts.Verified
Sonic 3 & Knuckles 1994Rolling keeps Sonic 2's numbers, friction of half the acceleration ($6), $20 more against the d-pad, and X speed clamped to $1000.Code
With Down held, neither Left nor Right, and no infinite-inertia flag (bit 7 of status_secondary), Sonic curls into a roll at a ground speed of $100 or more either way, twice Sonic 2's $80; slower than that, unless he stands on an object, he crouches, where Sonic 2 and Sonic 3 alone crouch only from Sonic_Move's standstill branch.Code
Outside pinball mode (spin_dash_flag set on a roll) and without the infinite-inertia flag, a roll ends once friction and the d-pad leave the ground speed under $80 either way, and the speed left is kept; Sonic 2 and Sonic 3 alone unroll only at 0. Standing up moves his center 5 px up with normal gravity. In pinball mode a positive flag sets the speed to $400 in his facing direction instead, and a negative one skips the d-pad, friction, and this check.Code
On flat ground, Sonic 3 & Knuckles changes when Sonic rolls and stands: Down curls him only from $100, not Sonic 2's $80, and, off objects, crouches him while he is still moving slower, where Sonic 2 crouched only from a standstill; a roll stands up under $80 with that speed kept, where Sonic 2's rolls on to 0 (both outside pinball mode). In the air he keeps a speed above the top while steering, where Sonic 2 pulled him down to it; a second press after a roll jump gives back steering, which Sonic 2's jump never did; a wall push moving sideways no longer ends the frame's checks; and a head 20 px into a ceiling moving left is pushed off a right wall instead, a check Sonic 2 lacks. Standing over a drop, not Super, he turns toward it at once, where Sonic 2 turned only if the floor 6 px the other way was also low.Code

References

  1. ^ abIn the running game, on flat ground, Down without Left or Right curls Sonic into a roll when his ground speed, after this frame's friction, is at least $80 either way: from $8C written in by the probe he rolls, from $8B he doesn't.Verifiedsonicretro/s1disasm · Sonic Retro, “Sonic Physics Guide: Rolling”
    How we know
    1150		move.w	obInertia(a0),d0			; get Sonic's current ground speed
    ⋮
    1155		cmpi.w	#$80,d0					; is Sonic moving at $80 speed or faster?
    1156		blo.s	.noroll					; if not, branch
    1157		move.b	(v_jpadhold2).w,d0			; get held buttons
    1158		andi.b	#btnL+btnR,d0				; is left/right being held?
    1159		bne.s	.noroll					; if yes, prevent rolling (some kind of fat-fingering convenience feature?)
    1160		btst	#bitDn,(v_jpadhold2).w			; is down being held?
    1161		bne.s	Sonic_ChkRoll				; if yes, branch
    
    _incObj/01 Sonic.asm lines 1150–1161 at 15dfa3a · upstream ↗
    1177		bset	#status_rolling_bit,obStatus(a0)	; set rolling flag
    1178		move.b	#sonic_roll_height,obHeight(a0)		; set Sonic's hitbox height to rolling size
    ⋮
    1187		addq.w	#sonic_height-sonic_roll_height,obY(a0)	; adjust Y-position to align Sonic to the floor
    
    _incObj/01 Sonic.asm lines 1176–1187 at 15dfa3a · upstream ↗
    320		bsr.w	Sonic_Move				; handle Sonic's left/right movement
    321		bsr.w	Sonic_Roll				; check if we need to roll
    
    _incObj/01 Sonic.asm lines 320–321 at 15dfa3a · upstream ↗
    In Sonic 1, 2, and 3, the Player can't begin to roll unless absolute Ground Speed is greater than or equal to 0.5 (128 subpixels)
    Criteria · 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

  2. ^ abIn the running game, on flat ground, a roll never speeds up: friction takes $6 a frame whatever is held, holding against the roll takes another $20, and a ground speed past $1000 written in by the probe gives an X speed of exactly ±$1000 (16 px/frame).Verifiedsonicretro/s1disasm · Sonic Retro, “Sonic Physics Guide: Rolling”
    How we know
    767Sonic_RollSpeed:
    768		move.w	(v_sonspeedmax).w,d6			; get Sonic's current max speed...
    769		asl.w	#1,d6					; ...doubled while rolling
    770		move.w	(v_sonspeedacc).w,d5			; get Sonic's current acceleration...
    771		asr.w	#1,d5					; ...halved while rolling
    772		move.w	(v_sonspeeddec).w,d4			; get Sonic's current deceleration...
    773		asr.w	#2,d4					; ...divided by 4 while rolling
    
    _incObj/01 Sonic.asm lines 767–773 at 15dfa3a · upstream ↗
    791.notright:
    792		move.w	obInertia(a0),d0			; get Sonic's current ground speed
    793		beq.s	Sonic_RollSlowdownDone			; is he standing still? if yes, branch
    794		bmi.s	.rollingleft				; is he moving to the left? if yes, branch
    795		sub.w	d5,d0					; slightly decrease Sonic's current roll speed
    796		bcc.s	.stillrollingright			; if still rolling, branch
    797		move.w	#0,d0					; reset speed to zero on sign change
    
    _incObj/01 Sonic.asm lines 791–797 at 15dfa3a · upstream ↗
    912Sonic_RollRight:
    913		move.w	obInertia(a0),d0			; get Sonic's current ground speed
    914		bmi.s	.changedirection			; has Sonic changed direction? if yes, branch
    915		bclr	#status_xflip_bit,obStatus(a0)		; clear X-flip flag (Sonic is facing right)
    916		move.b	#id_Roll,obAnim(a0)			; use "rolling" animation
    917		rts						; return
    
    _incObj/01 Sonic.asm lines 912–917 at 15dfa3a · upstream ↗
    863		cmpi.w	#$1000,d1				; is new X-velocity bigger than maximum screen shift speed? (rightward)
    ⋮
    873		move.w	d1,obVelX(a0)				; set new X-velocity
    
    _incObj/01 Sonic.asm lines 863–873 at 15dfa3a · upstream ↗
    roll_friction_speed 0.0234375 (6 subpixels) roll_deceleration_speed 0.125 (32 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

  3. ^ abRolling, Sonic slows by half his acceleration ($6) a frame, by $20 more against the d-pad, and his X speed is clamped to $1000 (16 px/frame).Codesonicretro/s2disasm · sonicretro/s1disasmrevised
    How we know
    37057	move.w	(Sonic_acceleration).w,d5
    37058	asr.w	#1,d5	; natural roll deceleration = 1/2 normal acceleration
    
    s2.asm lines 37057–37059 at 4ef457c · upstream ↗
    37137	cmpi.w	#$1000,d1
    ⋮
    37139	move.w	#$1000,d1	; limit Sonic's speed rolling right
    
    s2.asm lines 37137–37143 at 4ef457c · upstream ↗
    asr.w #1,d5 … move.w (v_sonspeeddec).w,d4 … asr.w #2,d4
    _incObj/01 Sonic.asm#L770-L773 · upstream ↗
    cmpi.w #$1000,d1 … move.w #$1000,d1
    _incObj/01 Sonic.asm#L863-L865 · 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

  4. ^ abRolling keeps Sonic 2's numbers, friction of half the acceleration ($6), $20 more against the d-pad, and X speed clamped to $1000.Codesonicretro/skdisasm · sonicretro/s2disasmrevised
    How we know
    22962		move.w	Acceleration-Max_speed(a4),d5
    22963		asr.w	#1,d5
    ⋮
    22969		move.w	#$20,d4
    
    sonic3k.asm lines 22962–22969 at 73de97c · upstream ↗
    23055		cmpi.w	#$1000,d1
    23056		ble.s	loc_115F6
    23057		move.w	#$1000,d1
    
    sonic3k.asm lines 23055–23057 at 73de97c · upstream ↗
    37058	asr.w	#1,d5	; natural roll deceleration = 1/2 normal acceleration
    
    s2.asm lines 37057–37059 at 4ef457c · upstream ↗
    37137	cmpi.w	#$1000,d1
    37138	ble.s	+
    37139	move.w	#$1000,d1	; limit Sonic's speed rolling right
    
    s2.asm lines 37137–37139 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

  5. ^In the running game, on a 45° ramp built from Green Hill's $E0 ramp block, every ground frame's ground speed matched the flat-ground rules after a slope term of the sine of his angle times $20 while he ran, $50 while he rolled downhill and a quarter of that uphill; standing still on the ramp for 60 frames, he didn't move.Verifiedsonicretro/s1disasm
    How 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.

    In the claim ledger

  6. ^In the running game, a roll started at top speed on flat ground stops on its 255th frame whether forward is held or not, and Sonic stands up on that frame.Verifiedsonicretro/s1disasm
    How we know
    795		sub.w	d5,d0					; slightly decrease Sonic's current roll speed
    ⋮
    818		tst.w	obInertia(a0)				; is Sonic standing still?
    819		bne.s	Sonic_AngledRollSpeed			; if not, branch
    ⋮
    821		bclr	#status_rolling_bit,obStatus(a0)	; clear rolling flag
    
    _incObj/01 Sonic.asm lines 791–825 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-25.

    In the claim ledger

  7. ^Sonic curls into a roll when Down is held without Left or Right and his ground speed is at least $80 either way, as in Sonic 1.Codesonicretro/s2disasm · sonicretro/s1disasmrevised
    How we know
    37345	mvabs.w	inertia(a0),d0
    37346	cmpi.w	#$80,d0		; is Sonic moving at $80 speed or faster?
    ⋮
    37349	andi.b	#button_left_mask|button_right_mask,d0 ; is left/right being pressed?
    ⋮
    37351	btst	#button_down,(Ctrl_1_Held_Logical).w ; is down being pressed?
    
    s2.asm lines 37345–37352 at 4ef457c · upstream ↗
    1155		cmpi.w	#$80,d0					; is Sonic moving at $80 speed or faster?
    ⋮
    1158		andi.b	#btnL+btnR,d0				; is left/right being held?
    ⋮
    1160		btst	#bitDn,(v_jpadhold2).w			; is down being held?
    
    _incObj/01 Sonic.asm lines 1155–1161 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.

    In the claim ledger

  8. ^With Down held, neither Left nor Right, and no infinite-inertia flag (bit 7 of status_secondary), Sonic curls into a roll at a ground speed of $100 or more either way, twice Sonic 2's $80; slower than that, unless he stands on an object, he crouches, where Sonic 2 and Sonic 3 alone crouch only from Sonic_Move's standstill branch.Codesonicretro/skdisasm · sonicretro/s2disasmrevised
    How we know
    23258SonicKnux_Roll:
    ⋮
    23262		andi.b	#button_left_mask|button_right_mask,d0	; is left/right being pressed?
    23263		bne.s	locret_1177E	; if yes, branch
    23264		btst	#button_down,(Ctrl_1_logical).w	; is down being pressed?
    ⋮
    23271		cmpi.w	#$100,d0		; is Sonic moving at $100 speed or faster?
    23272		bhs.s	Player_ChkRoll		; if so, branch
    23273		btst	#Status_OnObj,status(a0)
    23274		bne.s	locret_1177E
    23275		move.b	#8,anim(a0)	; enter ducking animation
    
    sonic3k.asm lines 23258–23278 at 73de97c · upstream ↗
    37345	mvabs.w	inertia(a0),d0
    37346	cmpi.w	#$80,d0		; is Sonic moving at $80 speed or faster?
    37347	blo.s	Obj01_NoRoll	; if not, branch
    
    s2.asm lines 37345–37352 at 4ef457c · upstream ↗
    20970		cmpi.w	#$80,d0		; is Sonic moving at $80 speed or faster?
    20971		blo.s	locret_127D0		; if so, branch
    
    s3.asm lines 20970–20976 at 73de97c · upstream ↗
    36788Sonic_Duck:
    36789	btst	#button_down,(Ctrl_1_Held_Logical).w	; is down being pressed?
    36790	beq.s	Obj01_ResetScr							; if not, branch
    36791	move.b	#AniIDSonAni_Duck,anim(a0)				; use "ducking" animation
    
    s2.asm lines 36788–36791 at 4ef457c · upstream ↗
    20420loc_12362:
    20421		btst	#button_down,(Ctrl_1_held_logical).w
    20422		beq.s	loc_1238C
    20423		move.b	#8,anim(a0)
    
    s3.asm lines 20420–20423 at 73de97c · upstream ↗

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

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

    In the claim ledger

  9. ^Outside pinball mode (spin_dash_flag set on a roll) and without the infinite-inertia flag, a roll ends once friction and the d-pad leave the ground speed under $80 either way, and the speed left is kept; Sonic 2 and Sonic 3 alone unroll only at 0. Standing up moves his center 5 px up with normal gravity. In pinball mode a positive flag sets the speed to $400 in his facing direction instead, and a negative one skips the d-pad, friction, and this check.Codesonicretro/skdisasm · sonicretro/s2disasmrevised
    How we know
    23007		move.w	ground_vel(a0),d0
    ⋮
    23012		cmpi.w	#$80,d0
    23013		bhs.s	loc_115C6
    ⋮
    23016		bclr	#Status_Roll,status(a0)
    23017		move.b	y_radius(a0),d0
    23018		move.b	default_y_radius(a0),y_radius(a0)
    ⋮
    23021		sub.b	default_y_radius(a0),d0
    ⋮
    23028		add.w	d0,y_pos(a0)
    
    sonic3k.asm lines 23007–23028 at 73de97c · upstream ↗
    37097Sonic_CheckRollStop:
    37098	tst.w	inertia(a0)
    37099	bne.s	Obj01_Roll_ResetScr
    ⋮
    37102	bclr	#status.player.rolling,status(a0)
    ⋮
    37106	subq.w	#5,y_pos(a0)
    
    s2.asm lines 37097–37106 at 4ef457c · upstream ↗
    20728		tst.w	ground_vel(a0)
    20729		bne.s	loc_12636
    ⋮
    20732		bclr	#Status_Roll,status(a0)
    
    s3.asm lines 20728–20739 at 73de97c · upstream ↗
    22970		tst.b	spin_dash_flag(a0)
    22971		bmi.w	loc_115C6
    22972		tst.b	status_secondary(a0)
    22973		bmi.w	loc_115C6
    
    sonic3k.asm lines 22970–22973 at 73de97c · upstream ↗
    23032loc_115B4:
    23033		move.w	#$400,ground_vel(a0)
    23034		btst	#Status_Facing,status(a0)
    23035		beq.s	loc_115C6
    23036		neg.w	ground_vel(a0)
    
    sonic3k.asm lines 23032–23036 at 73de97c · upstream ↗

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

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

    In the claim ledger

Sources

Code

Secondary