# SPG:Running

### From Sonic Retro

Notes:

• The research applies to all four of the Sega Mega Drive games and Sonic CD.
• The following describes physics that only apply when the Player has no special power-up and is not Underwater.

## Constants

``` acceleration_speed: 0.046875
deceleration_speed: 0.5
friction_speed: 0.046875
top_speed: 6
```

## Movement

All the characters - Sonic, Tails, and Knuckles - have the same acceleration, deceleration, top speed, running and braking values. They handle identically, with no difference at all besides their special moves and their sprites (and the fact that Knuckles jumps lower than the other two).

### Acceleration

If you're holding , Sonic's Ground Speed decreases by acceleration_speed every step. If you're holding (Also applies if you're holding , which you may not want in your engine), his Ground Speed increases by acceleration_speed every step.

### Deceleration

If Sonic is already moving when you press or , rather than at a standstill, it's checked whether you are holding the direction he's already moving. If so, acceleration_speed is added to his Ground Speed as normal. However if you are pressing in the opposite direction than he's already moving, deceleration_speed is added instead. Thus Sonic can turn around quickly. If no distinction is made between acceleration_speed and deceleration_speed, Sonic takes too long to overcome his current velocity, frustrating the player. A good engine must not make such a day one mistake.

One might think that if Ground Speed happened to equal 0.1, and you pressed , deceleration_speed would be subtracted, resulting in an Ground Speed value of -0.4. Oddly, this is not the case in any of the original games. Instead, at any time an addition or subtraction of deceleration_speed results in Ground Speed changing sign, Ground Speed is set to 0.5 in the opposite direction. For example, in the instance above, Ground Speed would become -0.5. The bizarre result of this is that you can press for one step, and then press (or vice versa), and start running faster than if you had just pressed alone! Now, the resulting speed is still lower than one pixel per step, so it isn't very noticeable, but nonetheless it is true.

### Friction

If you are not pressing or , friction (friction_speed) kicks in. In any step in which the game receives no horizontal input, friction_speed is subtracted from Ground Speed (depending on the sign of Ground Speed), where if it then passes over 0, it's set back to 0.

### Top Speed

Sonic can only accelerate up to a certain point. At some point, he reaches top speed and can no longer move any faster under his own power. So, after acceleration_speed is added to Ground Speed, if Ground Speed exceeds top_speed it's set to top_speed.

In Sonic 1, while Sonic is already running at a higher speed than he can possibly achieve on his own (such as having been impelled by a spring), if you press in the direction he's moving, acceleration_speed will be added to Ground Speed as usual. However, notice that Ground Speed now exceeds top_speed, which means Ground Speed will be set to top_speed. Thus it is possible to curtail your forward momentum by pressing in the very direction of your motion. This can be solved in your engine (and was fixed in Sonic 2 and beyond) by checking to see if Ground Speed is less than top_speed before adding acceleration_speed. Only if Ground Speed is already less than top will it check if Ground Speed exceeds top_speed.

Sonic CD and Sonic 2 actually has a fix like this, where the top_speed check won't happen if Ground Speed is already above top_speed, because in Sonic CD can perform the "Super Peel Out", which launches him above his typical top_speed, and in Sonic 2 because it's supposed to be a much faster game. The issue is, in both games, it doesn't fix this error when Sonic is in mid-air, causing him to usually lose his speed when running off of a ledge.

Here's some code logic that can accurately emulate movement and friction:

```if (the player is pressing left)
{
if (Ground Speed > 0) //if moving to the right
{
Ground Speed -= deceleration_speed;  //decelerate
if (Ground Speed <= 0)
Ground Speed = -0.5;  //emulate deceleration quirk
}
else if (Ground Speed > -top_speed) //if moving to the left
{
Ground Speed -= acceleration_speed;  //accelerate
if (Ground Speed <= -top_speed)
Ground Speed = -top_speed; //impose top speed limit
}
}

if (the player is pressing right)
{
if (Ground Speed < 0) //if moving to the left
{
Ground Speed += deceleration_speed; //decelerate
if (Ground Speed >= 0)
Ground Speed = 0.5; //emulate deceleration quirk
}
else if (Ground Speed < top_speed) //if moving to the right
{
Ground Speed += acceleration_speed; //accelerate
if (Ground Speed >= top_speed)
Ground Speed = top_speed; //impose top speed limit
}
}

if (the player is not pressing left or right)
Ground Speed -= minimum(absolute(Ground Speed), friction_speed) * sign(Ground Speed); //decelerate

```

## Control Lock

The control lock timer is used to prevent left and right input from affecting the Player while they are on the ground. It is used (set to specific durations) when the Player slips or falls down a slope, and also when they bounce on a horizontal spring.

While this timer is non-zero and the Player is on the ground, it prevents directional input from adjusting the Player's speed with the left or right buttons.

When set, the control lock ticks down only when it is currently non-zero and while Sonic is on the ground, otherwise the timer remains paused. It does not affect air movement.

## Notes

Note: In the original games, holding and at the same time will run both direction's code in one step, if you want in your engine, you can disable + input (Emulators like Fusion will just cancel the right input if left is also held).