From Sonic Retro
|Sonic Physics Guide|
- 1 Introduction
- 2 Player 2 Control
- 3 Player 2 CPU
- 4 Respawning
Starting with Sonic 2, a second player can follow you around the stage. At first glance it may seem like they simply copy your inputs, but there is a lot more nuance to the following Player's (Player 2's) actions.
Player 2 Control
By default, Player 2 is CPU controlled; however every time the Player 2 controller detects input, CPU control will be disabled for 10 seconds.
Player 2 CPU
While the Player 2 is CPU controlled and is following Player 1, they access various bits of information about Player 1's state from 16 frames in the past. How does it do this? Well, Players keep lists of their actions and states each frame.
The information lists stored is as follows:
The X/Y Position of the Player.
The grounded state, pushing state, jumping state and direction the player is facing.
The complete controller inputs being used.
These lists are added to each frame by the Player. Each list is 32 entries long and therefore retains information from the last 32 frames.
Player 2 reads all the data from the entry 16 frames into the past. From this point on this guide, when Player 2 uses this information it will be labelled as target_inputs, target_x, target_y, or target_grounded, etc. These will be in reference to Player 1's state 16 frames in the past that was read from these lists.
Firstly, Player 2 will adopt the target_inputs found from Player 1's control list as their CPU inputs. Some of these will be modified up ahead, but if left unchanged, this means Player 2 will copy Player 1 exactly, with a 16 frame delay.
CPU Following State
Before anything else happens, if Player 2 currently has an active control lock and their Ground Speed is 0, they are most likely stuck on a slope and they will enter their CPU Spindash state. This state will be explained up ahead. Otherwise, Player 2 will continue onto CPU following.
In the CPU Following state, Player 2 will decide upon how to modify their CPU controller inputs to adequately follow Player 1.
Firstly, the game checks if Player 2 is stuck. If Player 2 is pushing and target_pushing is not true, this likely means Player 2 is stuck against a wall or object. If this is the case, Player 2 will skip normal movement entirely and move onto jumping. Otherwise, they will continue onto normal movement. Jumping will occur after normal movement if the game doesn't exit CPU following code.
In Sonic 2, normal movement is were Player 2 moves left or right to follow Player 1, and continues actions & performs checks. This will begin with walking towards Player 1.
Note: In Sonic 3 onwards, if Player 1's absolute Ground Speed is less than 4 and they are not standing on an object, 32 is subtracted from target_x. This allows Player 2 to stand a little behind Player 1.
Player 2 will then compare their X Position to target_x.
Next are the actions and checks.
Actions & Checks
Here the game will check various conditions and ensure Player 2 continues actions such as while jumping. If the CPU following code is exited for the current frame after any of these checks, this means that any further checks and jumping will not occur.
If the CPU following code has not been exited, it will move ahead onto the jumping.
Here the game will allow Player 2 to jump even when Player 1 hasn't.
Player 2 simply attempts to perform a jump once every 64 frames (checked on a global timer). When that occurs, if they aren't crouching, they will press and hold the jump buttons on their CPU controller inputs, and then exit the CPU following code for that frame.
CPU Spindash State
When in the CPU Spindash state, a few checks are performed.
Firstly, if control lock is active, the game will exit the CPU Spindash code for that frame, but will check again the next frame.
Before the Player 2 can Spindash, they'll try to crouch.
Firstly, they'll check if their Ground Speed is 0. If it isn't, the game will exit the CPU Spindashing code for that frame.
They'll turn to face Player 1.
Meanwhile, the game is checking if they are finally in their ducking sprite. If they are, they will tap the buttons on their CPU controller to initiate the Spindash. However, at the same time every 128 frames (checked on a global timer) the game will check if Player 2 isn't yet crouching. If they are not, the game will cancel the CPU Spindash state entirely and set Player 2's state to the CPU Following state.
Meanwhile, every 128 frames (checked on a global timer) the game will release the buttons and down button on their CPU controller, releasing the Spindash. This will also switch the state back to CPU Following.
Player 2 will Respawn if they are offscreen for 300 frames.
In the case of Tails, when they respawn they'll begin flying back in.
Upon respawning, Tails' X Position will be set to Player 1's X Position, and his Y Position will be set to
Player 1's Y Position - 192. Also, Tails' target_x and target_y will be set to Player 1's current positions (for that frame only, from here on it uses the delayed values).
When flying in, Tails will decide how much to move their X Position by based on the difference in X Position to target_x, and Player 1's X Speed.
x_difference = Player 2's X Position - target_x; x_to_move = minimum(12, absolute(x_difference) >> 4) + absolute(Player 1's X Speed); // ">> 4" here is equivalent to dividing by 16, floored
Tails will face whichever direction target_x is in, and will move towards target_x by a distance of
minimum(x_to_move, absolute(x_difference)) in that direction each frame.
Vertically, Tails will move up or down (modifying Y Position rather than using speeds) by 1 pixel per frame until they reach Player 1's Y Position.
Player 2 will land when close enough to Sonic, when their X Position is equal to target_x and their Y Position is equal totarget_y. In addition, target_grounded needs to be true.
In Sonic 3, the game also makes sure that Player 1 isn't in their dying state.