Actions

Difference between revisions of "SPG:Running"

From Sonic Retro

m (Text replacement - "</asm>" to "</syntaxhighlighter>")
m (Friction While Locked)
 
(22 intermediate revisions by 7 users not shown)
Line 1: Line 1:
''Notes:''
+
{{SPGPages}}
 +
'''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 [[SPG:Underwater|Underwater]].''
  
Research applies to all four of the [[Sega Mega Drive|Genesis/Mega Drive]] games, and [[Sonic CD]].
+
==Constants==
 +
{| class="prettytable" style="width: auto;"
 +
!Constant
 +
!Value
 +
|-
 +
|'''acceleration_speed'''
 +
|''0.046875 (12 subpixels)''
 +
|-
 +
|'''deceleration_speed'''
 +
|''0.5 (128 subpixels)''
 +
|-
 +
|'''friction_speed'''
 +
|''0.046875 (12 subpixels)''
 +
|-
 +
|'''top_speed'''
 +
|''6''
 +
|}
  
The following only applies when [[Sonic]] is on flat, dry land with no special power-ups.  Curves, water physics, [[Super Sonic]], and [[Speed Shoes]] will be covered in separate guides.
+
==Movement==
 
+
All the [[SPG:Characters|characters]] - Sonic, Tails, and Knuckles - have the same '''acceleration_speed''', '''deceleration_speed''', '''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 [[SPG:Characters#Knuckles|Knuckles jumps lower]] than the other two).
==Variables==
 
 
 
The following variables/constants will be referenced frequently in this section.
 
   
 
<syntaxhighlighter lang="asm">
 
//variables
 
xsp: the speed in which sonic is moving horizontally
 
ysp: the speed in which sonic is moving vertically
 
 
//constants
 
acc: 0.046875
 
dec: 0.5
 
frc: 0.046875 (same as acc)
 
top: 6
 
</syntaxhighlighter>
 
 
 
==Movement Rules==
 
  
 
===Acceleration===
 
===Acceleration===
  
When you hold {{right}} from a standstill, his ''xsp'' increases by ''acc'' every step. When you hold {{left}} from a standstill, his xsp decreases by ''acc'' every step.
+
If you're holding {{left}}, Sonic's Ground Speed decreases by '''acceleration_speed''' every step. If you're holding {{right}} (Also applies if you're holding {{left}}, which you may not want in your engine), his Ground Speed increases by '''acceleration_speed''' every step.
  
 
===Deceleration===
 
===Deceleration===
  
If Sonic is already moving when you press {{left}} or {{right}}, rather than at a standstill, the computer checks whether you are pressing the joypad in the direction he's already moving. If so, ''acc'' is added to his ''xsp'' as normal.  However if you are pressing in the opposite direction than he's already moving, the deceleration constant (''dec'') is added instead.  Thus Sonic can turn around quickly.  If no distinction is made between ''acc'' and ''dec'', Sonic takes too long to overcome his current velocity, frustrating the player.  A good engine must not make such a day one mistake.
+
If Sonic is already moving when you press {{left}} or {{right}}, 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.   
  
One might think that if ''xsp'' happened to equal 0.1, and you pressed {{left}}, ''dec'' would be subtracted, resulting in an ''xsp'' value of -0.4. Oddly, this is not the case in any of the Mega Drive games.  Instead, at any time an addition or subtraction of ''dec'' results in xsp changing sign, ''xsp'' is set to ''dec''. For example, in the instance above, ''xsp'' would become -0.5. The bizarre result of this is that you can press {{left}} for one step, and then press {{right}} (or vice versa), and start running faster than if you had just pressed {{right}} alone! Now, the resulting speed is still lower than one pixel per step, so it isn't very noticeable, but nonetheless it is true.  You may not want to bother emulating this anomaly.
+
At any time an addition or subtraction of '''deceleration_speed''' results in '''''Ground Speed''''' changing sign, '''''Ground Speed''''' is set to ''0.5 (128 subpixels)'' in the opposite direction. For example, in the instance above, '''''Ground Speed''''' would become -''0.5 (-128 subpixels)''. The bizarre result of this is that you can press {{left}} for one step, and then press {{right}} (or vice versa), and start running faster than if you had just pressed {{right}} alone! Now, the resulting speed is still lower than 1 pixel per step, so it isn't very noticeable, but nonetheless it is true.
  
 
===Friction===
 
===Friction===
  
If you are not pressing {{left}} or {{right}}, friction (''frc'') kicks in.  In any step in which the game recieves no horizontal joypad input, ''frc'' times the sign of ''xsp'' is subtracted from ''xsp'', unless absolute ''xsp'' is less than ''frc'', in which case ''xsp'' is simply set to zero.
+
If you are not pressing {{left}} or {{right}}, friction kicks in.  In any step in which the game receives no horizontal input, '''friction_speed''' is subtracted from (or added to, depending on the sign of '''''Ground Speed''''') '''''Ground Speed''''', where if it then passes over ''0'', it's set back to ''0''.
  
 
===Top Speed===
 
===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 ''acc'' is added to ''xsp'', the computer checks to see if ''xsp'' exceeds ''top''.  If it does, it's set to ''top''.
+
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'''.
  
This means, of course, that if Sonic is somehow running at a higher speed than he can possibly achieve on his own (perhaps by way of having been impelled by a spring), if you press in the direction he's moving, the computer will add ''acc'', notice that ''xsp'' exceeds ''top'', and set ''xsp'' to ''top''. Thus it is possible to curtail your forward momentum by pressing in the very direction of your motion. That's just not right! This can be solved in your engine by checking to see if ''xsp'' is less than ''top'' before adding ''acc''. Only if ''xsp'' is less than ''top'' does the computer add ''acc'' to it and check if ''xsp'' exceeds ''top''.  Problem solved.
+
In Sonic 1, while Sonic is already running at a higher speed than he can possibly achieve on his own (such as having been bounced by a Spring on a wall), 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]] actually uses a fix like this because Sonic can perform the "[[Super Peel Out]]" (or "Dash", in Japan, which is what I'll call it here), which launches him forward at a speed of 12 pixels per step.  Sonic can't accelerate to this speed under normal conditions, but if he reaches it from a Dash, he can continue to run at such a speed without slowing down, as long as you continue to press in the direction of his motion.  If you should release the button, friction will take over.  If you press again, friction will cease, and ''xsp'' will remain constant, but it will not rebuild to 12 without another Dash.
 
  
However, the programmers of Sonic CD neglected to apply the fix while Sonic is in the air, so if Sonic were to Dash off of a cliff, while you held in the direction of his motion, ''xsp'' would cut to 6 as he leaves the ground, regardless of how much higher it was at the time. Again, that's just not right.
+
[[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:
 
Here's some code logic that can accurately emulate movement and friction:
  
<syntaxhighlighter lang="asm">
+
<syntaxhighlight>if (the player is pressing left)
if (the player is pressing left)
 
 
{
 
{
     if (xsp > 0)
+
     if (Ground Speed > 0) //if moving to the right
 
     {
 
     {
         xsp -= dec;
+
         Ground Speed -= deceleration_speed; //decelerate
 +
        if (Ground Speed <= 0)
 +
            Ground Speed = -0.5;  //emulate deceleration quirk
 
     }
 
     }
     else (if xsp > -top)
+
     else if (Ground Speed > -top_speed) //if moving to the left
 
     {
 
     {
         xsp = xsp-acc;
+
         Ground Speed -= acceleration_speed;  //accelerate
 +
        if (Ground Speed <= -top_speed)
 +
            Ground Speed = -top_speed; //impose top speed limit
 
     }
 
     }
 
}
 
}
else if (the player is pressing right)
+
 
 +
if (the player is pressing right)
 
{
 
{
     if (xsp < 0)
+
     if (Ground Speed < 0) //if moving to the left
 
     {
 
     {
         xsp += dec;
+
         Ground Speed += deceleration_speed; //decelerate
 +
        if (Ground Speed >= 0)
 +
            Ground Speed = 0.5; //emulate deceleration quirk
 
     }
 
     }
     else if (xsp < top)
+
     else if (Ground Speed < top_speed) //if moving to the right
 
     {
 
     {
         xsp = xsp+acc;
+
         Ground Speed += acceleration_speed; //accelerate
 +
        if (Ground Speed >= top_speed)
 +
            Ground Speed = top_speed; //impose top speed limit
 
     }
 
     }
 
}
 
}
else xsp = xsp-minimum(absolute(xsp), frc)*sign(xsp);
 
</syntaxhighlighter>
 
 
==Animation Rules==
 
 
===Running Animation===
 
 
If you include Sonic CD in the mix, Sonic has 3 different running animations. He is depicted as standing still only if ''xsp'' is exactly zero. If he has any ''xsp'' whatsoever, he enters his walking animation, the frame advences in relation to his ground speed.
 
  
Once his ''xsp'' equals (or exceeds) 6, he enters his running animation, with the whirling feet. Once his ''xsp'' equals (or exceeds) 10, he enters his Dashing animation, with the figure-eight feet. Of course, the Dashing animation is only in Sonic CD.
+
if (the player is not pressing left or right)
 +
    Ground Speed -= minimum(absolute(Ground Speed), friction_speed) * sign(Ground Speed); //decelerate
 +
</syntaxhighlight>
  
===Braking Animation===
+
==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 [[SPG:Slope_Physics#Falling_and_Slipping_Down_Slopes|slips or falls down a slope]], and also when they [[SPG:Game_Objects#Horizontal Springs|bounce on a horizontal spring]].
  
Sonic enters his braking animation when you turn around only if his absolute ''xsp'' is equal to or more than 4.5. In Sonic 1 and Sonic CD, he then stays in the braking animation until ''xsp'' reaches zero or changes sign. In the other 3 games, Sonic returns to his walking animation after the braking animation finishes displaying all of its frames.
+
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.
  
===Character Specific===
+
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.
  
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 annoying fact that Knuckles jumps lower than the other two).
+
===Friction While Locked===
 +
Because horizontal input is ignored during a control lock, it would make sense if friction was constantly applied no matter what you pressed, but that's not how it works. Instead, friction behaves the exact same even when the control lock timer is active. If you are not pressing {{left}} or {{right}}, friction is applied, but it's not applied if they aren't pressed even though the Player can't move. This means when the Player [[SPG:Slope_Physics#Falling_and_Slipping_Down_Slopes|slips]] down a slope they will actually slide down the slower if you ''don't'' hold {{left}} or {{right}}.
  
 +
==Notes==
 +
Note: ''In the original games, holding {{left}} and {{right}} at the same time will run both direction's code in one step, if you want in your engine, you can disable {{left}} + {{right}} input (Emulators like Fusion will just cancel the right input if left is also held).''
 
[[Category:Sonic Physics Guide|Running]]
 
[[Category:Sonic Physics Guide|Running]]

Latest revision as of 11:33, 19 February 2024

Sonic Physics Guide
Collision
Physics
Gameplay
Presentation
Special

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

Constant Value
acceleration_speed 0.046875 (12 subpixels)
deceleration_speed 0.5 (128 subpixels)
friction_speed 0.046875 (12 subpixels)
top_speed 6

Movement

All the characters - Sonic, Tails, and Knuckles - have the same acceleration_speed, deceleration_speed, 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 Left, Sonic's Ground Speed decreases by acceleration_speed every step. If you're holding Right (Also applies if you're holding Left, 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 Left or Right, 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.

At any time an addition or subtraction of deceleration_speed results in Ground Speed changing sign, Ground Speed is set to 0.5 (128 subpixels) in the opposite direction. For example, in the instance above, Ground Speed would become -0.5 (-128 subpixels). The bizarre result of this is that you can press Left for one step, and then press Right (or vice versa), and start running faster than if you had just pressed Right alone! Now, the resulting speed is still lower than 1 pixel per step, so it isn't very noticeable, but nonetheless it is true.

Friction

If you are not pressing Left or Right, friction kicks in. In any step in which the game receives no horizontal input, friction_speed is subtracted from (or added to, depending on the sign of Ground Speed) 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 bounced by a Spring on a wall), 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.

Friction While Locked

Because horizontal input is ignored during a control lock, it would make sense if friction was constantly applied no matter what you pressed, but that's not how it works. Instead, friction behaves the exact same even when the control lock timer is active. If you are not pressing Left or Right, friction is applied, but it's not applied if they aren't pressed even though the Player can't move. This means when the Player slips down a slope they will actually slide down the slower if you don't hold Left or Right.

Notes

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