SPG:Game Objects
From Sonic Retro
Notes: Research applies to all four of the Mega Drive games, and Sonic CD. If there are any varying differences between the games, this will be covered below.
Contents
- 1 Variables
- 2 Introduction
- 3 Hitboxes
- 4 General Objects
- 5 Sonic 1 Objects
- 6 Sonic 2 Objects
- 7 Sonic 3 Objects
- 8 Sonic and Knuckles Objects
- 9 Points
Variables
The following variables/constants will be referenced frequently in this section.
//Variables xpos: The X-coordinate of Sonic's center. ypos: The Y-coordinate of Sonic's center. xsp: The speed at which Sonic is moving horizontally. ysp: The speed at which Sonic is moving vertically. gsp: The speed at which Sonic is moving on the ground. slope: The current slope factor (slp) value being used. ang: Sonic's angle on the ground. //Constants acc: 0.046875 dec: 0.5 frc: 0.046875 (same as acc) top: 6 jmp: 6.5 (6 for Knuckles) slp: 0.125 slprollup: 0.078125 slprolldown: 0.3125 fall: 2.5
Introduction
Objects move in various ways, some simple and some rather complex. It may be enough to simply observe an object to know how it acts, but this isn't the case most of the time where greater depth is required.
Hitboxes
Hitboxes are the game's simplified way of giving an object a size. Each object has it's own size defined with a width radius and a height radius, and they aren't always obvious. Visual examples will be given for most objects in this guide.
Note: More detailed information about how hitboxes and solid objects work, as well as Sonic's hitbox, can be found at Solid Objects.
General Objects
General objects appear in many zones and games and the code should be the same between them.
Rings
Rings have a hitbox with a width radius of 6 and a height radius of 6, resulting in a 13 x 13 rectangle. (while their sprite is larger, at 16px), so Sonic can get quite close to a ring before a collision occurs and he collects it.
Springboards
Red springboards propel Sonic at a speed of 16, and yellow springboards at a speed of 10. If the springboard faces up or down, the value is either negative or positive, respectively, and ysp is set to it. If the springboard faces left or right, the value is either negative or positive, respectively, and xsp is set to it. Vertical springboards don't affect xsp and likewise horizontal springboards don't affect ysp.
In Sonic 1, springs were simple solid boxes which had the boundaries you'd expect, but after Sonic 2 added diagonal springs the activation area for normal springs changed, and now in Sonic 2 onwards if you walk into a sideways spring slowly you'll realise that it propels you far sooner than you'd expect. This might not be worthwhile emulating.
Diagonal Springboards
There are no diagonal springboards in Sonic the Hedgehog (16-bit). But there are in Sonic 2 (16-bit), 3, K, and CD. Sonic 2, 3, and K work the same way, but Sonic CD is different.
In Sonic 2, 3, and K, a diagonal spring sets both xsp and ysp to the springboard's value, with the appropriate sign. So a red springboard facing up and to the right sets ysp to -16 and xsp to 16. The trouble with this method is that Sonic is technically bounced faster diagonally than horizontally or vertically. This is because they didn't bother to calculate the sine functions.
In Sonic CD, they do however. Conveniently, the absolute sine and cosine of a 45 degree angle are the same, so you only need one value. It comes out to 11.3125 for Red springs and 7.0703125 for Yellow ones.
Horizontal Control Lock
When Sonic bounces away from a horizontal springboard (red or yellow), he cannot brake or otherwise affect his xsp for 16 steps. The engine achieves this by setting the same horizontal control lock as when sliding back down steep inclines (in S3&K, bytes $32-33 in the player object's status table). Why lock the horizontal controls? The player is likely to be pressing in the direction of the springboard as they run into it, and this would cause Sonic to bounce away in his braking animation. Temporarily ignoring input is a quick and elegant solution.
Item Monitors
When bumped from the bottom, Item monitors are given a Y speed of -1.5. They have a gravity of 0.21875 while falling.
Item Monitors have both a solid box and a hitbox, depending on if Sonic is curled up or not. Both of these have a width radius of 16 and a height radius of 16, resulting in a 33 x 33 rectangle.
Bumpers
Bumpers such as those in Spring Yard Zone set Sonic's xsp to 7*cosine(p), and ysp to 7*-sine(p), where p is the angle measured from the bumper's centre to Sonic's. This is regardless of Sonic's velocity when he hits the bumper.
Bumpers have a hitbox with a width radius of 8 and a height radius of 8, resulting in a 17 x 17 rectangle. Other than the hitbox speed repulsion, there is no solidity to bumpers.
Bridges
The bridges in Sonic 1, 2 and 3 are known for their dynamic movement as Sonic moves over them. Bridges are set up with a controller object and an array of log objects which the controller object creates, though this can just be an array of values to represent the segments in most engines now. The controller object contains a few variables: There's the length (in segments) of the bridge, which is usually 12, but it can be longer; there's the index of the segment Sonic is standing on, which starts at 0 for the leftmost segment and ends at length-1.
Depression Amount
The depression amount is the lowest the bridge can go at any given time. This changes depending on the log Sonic is standing on. To get the current maximum depression amount in pixels the bridge controller uses predetermined values for each log.
The values go up in 2's, starting at 2 and continuing to the middle, with the other side being a mirror of the first half. For example, a bridge with length 5 will have the values 2,4,6,4,2 and a bridge with length 6, the values would be 2,4,6,6,4,2. The bridges commonly found in Sonic (12 segments in length) would have the values 2,4,6,8,10,12,12,10,8,6,4,2.
To get the current maximum depression for the bridge, the game uses the value from the log currently being stood on. We'll call the current value MaxDepression.
Calculating Each Log Depression
The ypos of the segments in the bridge depend on the log that Sonic is currently standing on, as so:
Sonic is on the 5th segment, we'll call this the CurrentSegment and it's value is 5.
In this example, the depressions would look as follows: 2,4,6,8,10,12,12,10,8,6,4,2 So the current MaxDepression for the bridge will be the 5th log's value, which is 10.
To calculate the position of each log, we calculate how far it is from CurrentSegment relative to the edge it's near. We will call this value LogDistance.
Segment 0 is 1/5 of the way to CurrentSegment, so it's LogDistance is 1/5 or 0.2.
Segment 1 is 2/5 of the way to CurrentSegment, so it's LogDistance is 2/5 or 0.4.
Segment 4 is 5/5 of the way to CurrentSegment, so it's LogDistance is 5/5 or 1.
Working from the other side, we use the distance from the end to CurrentSegment, rather than from the start.
Segment 11 is 1/8 of the way to CurrentSegment, so it's LogDistance is 1/8 or 0.125.
Segment 6 is 6/8 of the way to CurrentSegment, so it's LogDistance is 6/8 or 0.75.
(Since we've already calculated segment 4 from one direction, there's no need to do it from the other).
We then use LogDistance to calculate it's position:
LogY = BridgeY + MaxDepression * sine(90 * LogDistance).
Some code to calculate these automatically may go as follows (assumes first segment index starts at 0 in loop for other purposes, but CurrentSegment would start at 1).
for (i = 0; i < SegmentAmount; i++) { //get difference of log var log_difference = abs((i+1)-CurrentSegment); //get opposite distance from current log to a side, depending if before or after CurrentSegment if (i < CurrentSegment) LogDistance = log_difference / CurrentSegment; else LogDistance = log_difference / ((SegmentAmount - CurrentSegment) + 1); //get y of log using max depression and log distance (reversed) LogY = BridgeY+((MaxDepression) * sine(90 * (1 - LogDistance))); }
Meanwhile, all these depression values are multiplied by the sine of the angle in the controller object that counts to 90 when Sonic is standing on top, and down to 0 when Sonic gets off, so the depression will smoothly increase with time when Sonic jumps on to the bridge, and then smoothly decrease when he leaves it.
Breaking Walls
In Sonic 1, 2, 3, & K, the character's absolute xsp must exceed 4.5 in order to break through destructible walls when rolling (except for Knuckles, who busts walls on contact, and doesn't need to be rolled up). xsp is unaffected by the collision, as well.
However, when Knuckles breaks walls in Sonic 3 & Knuckles, though his xsp is unaffected, he doesn't move during the frame in which he hits the wall. The same thing is true when Sonic spindashes through a wall in Sonic 3 & Knuckles.
In Sonic CD, the xsp threshold is removed. Sonic can break through destructible walls by simply jumping near them, or rolling into them at any speed.
Breakable Blocks and Rocks
When Sonic jumps on top of breakable objects, such as the rocks in Hill Top Zone, blocks in Marble Zone, or the tube caps in Chemical Plant Zone, he bounces away with a ysp of -3. xsp is unaffected.
The block produces 4 segments. These segments have a gravity of 0.21875. Their initial x and y speeds are (-2, -2) & (2, -2) for the top two, and (-1, -1) & (1, -1) for the bottom two.
Buttons
Buttons simply have a solid box (which Sonic can walk on & push against) which is lower than the top of the button when not depressed. When Sonic is standing on it, the subimage changes to depressed and the switch is activated.
End of Level Capsules
Sonic 1 Method
Explosion
For 60 steps, every 8 steps, spawn explosion at capsule position plus random x,y offset (Max horizontal offset of 31 pixels, and according to calculations, vertical is the same). At end of those 60 steps, start with the animals
Animals
Switch to exploded frame. Spawn 8 animals at capsule position -28x, +32y, horizontally separated by 7, with alarms starting from 154 and decreasing by 8 per animal (animals don't jump out until their alarm reaches zero).
For 150 steps, every 8 steps, spawn animal at random x position amongst the existing animal group (but tighter in, not near edges), with their alarm set to 12.
When all animal objects have disappeared, run Got Through message.
Sonic 2 Method
Explosion
An explosion spawns at lock's position, move lock at +8x, -4y. Wait 29 steps.
Animals
8 animals spawn at capsule position -28x, +32y, horizontally separated by 7, with alarms starting from 154 and decreasing by 8 per animal (the animals don't jump out until their alarm reaches zero).
For 180 steps, every 8 steps, an animal will spawn at random x position amongst the existing animal group (but tighter in, not near edges), with their alarm set to 12.
When all animal objects have disappeared, the game will run the 'Got Through' message.
Sonic 1 Objects
Badniks
Here the hitboxes and movments of enemies will be detailed.
A yellow box in this section refers to the box the enemy uses to collide, rather than something Sonic can collide with. Sonic will only care about with their main (cyan) hitbox or others (if they have any).
Motobugs
Motobugs move at a speed of 1. Once they touch a wall, they wait for 1 second before starting off in the other direction.
Motobugs have a hitbox with a width radius of 20 and a height radius of 16, resulting in a 41 x 33 rectangle.
Choppers
Choppers have a gravity of 0.09375 and bounce with a speed of -7 at the ypos where they spawned.
Choppers have a hitbox with a width radius of 12 and a height radius of 16, resulting in a 25 x 33 rectangle.
Buzz Bombers
Buzz Bombers move at a speed of 4 (or -4).
Buzz Bombers have a hitbox with a width radius of 24 and a height radius of 12, resulting in a 49 x 25 rectangle.
Crabmeats
Crabmeats move at a speed of 0.5 (or -0.5) while walking.
Crabmeats have a hitbox with a width radius of 16 and a height radius of 16, resulting in a 33 x 33 rectangle.
Projectiles
When shot, Crabmeat's projectiles are given a Y Speed of -4, and an X Speed of either positive or negative 1. They have a gravity of 0.21875.
Caterkillers
Caterkillers are comprised of 4 segments, the head, and 3 body segments. The head is the only vulnerable part, while the body segments have damage hitboxes (which also trigger the scattering).
Each segment has a hitbox with a width radius of 8 and a height radius of 8, resulting in a 17 x 17 rectangle.
The way they move is rather complex compared to other enemies. Firstly, let's go over timings.
Caterkillers scrunch up then flatten/stretch out, on a loop. They spend 16 frames moving, then 8 frames staying still. So this would be scrunching up for 16 frames, then not moving for 8, then stretching out for 16, then not moving for 8, and repeat.
Firstly I will go over how they work while on open ground, then what they do to track properly on slopes, then cover what they do when meeting a wall or a ledge.
For easier reference, we will number the segments like so:
When starting to scrunch, each body part will be spaced 12px apart. So if the head's X position was 50, the next body segment would have an X position of 62, or 38 if it is facing left, and so on.
Scrunching Up
When scrunching, the head won't proceed (its X speed is 0), instead this is where the back end catches up with the front end.
Segment 1 will proceed with the head's X speed plus -0.25 (0.25 when the segment is moving right). This results in a movement of 4 pixels within the 16 frames.
Segment 2 will move with Segment 1's X speed plus -0.25 (0.25 when the segment is moving right). This results in a movement of 8 pixels within the 16 frames.
Segment 3 will move with Segment 2's X speed plus -0.25 (0.25 when the segment is moving right). This results in a movement of 12 pixels within the 16 frames.
Both the head and Segment 2 will animate upwards 7 pixels within the 16 frames. The other segments remain flat to the floor.
Stretching Out
Stretching out is basically the opposite, where the head moves forward and the back end stays still.
The head will proceed with an X speed of -0.75 (0.75 when moving right). This results in a movement of 12 pixels within the 16 frames.
Segment 1 will proceed with the head's speed plus 0.25 (-0.25 when the segment is moving right). This results in a movement of 8 pixels within the 16 frames.
Segment 2 will proceed with Segment 1's X speed plus 0.25 (-0.25 when the segment is moving right). This results in a movement of 4 pixels within the 16 frames.
Segment 3 doesn't proceed, it has Segment 2's X speed plus 0.25 (-0.25 when the segment is moving right). This results in 0 X speed.
This time, both the head and Segment 2 will animate downwards 7 pixels within the 16 frames, back to being flat to the floor.
Slopes
The head segment is sticking to the floor using a downwards sensor much like Sonic does, as it moves.
Well, each body part needs to also stick to slopes as they move. This can be done by having the head record and remember all of its Y offsets in a small 16-byte array and having the next body part read from this as they move. This saves the game having to read data from tiles for each body segment. When the second body part reads this data, it copies it into its own array for the next body part in the chain to use.
Ledges And Walls
When the Caterkiller has to turn, it doesn't suddenly stop or even turn all at once. Each body part independently changes direction.
On the frames that the head meets a ledge, instead of a Y offset from the ground, instead a value of 128 is stored, which will signal the next body part to turn around also. The head segment will not align itself to the ground if nothing is found.
Important to note is it does not affect the timing of the segment movement at all, and the segment will continue to move in whichever direction it's now facing as if nothing happened. So, one by one, the segments will change direction as they each reach the point of turn.
Scattering
When you touch any part of the Caterkiller besides destroying its head, it will break apart and each segment will bounce away.
Segment Scatter Speed
Upon scattering, each segment first is given its own X speed. Here, starting at the head and ending with Segment 3.
-2.0, -1.5, 1.5, 2
This speed is negated if the segment is facing to the left.
These will fall with a gravity of (0.21875), and upon contact with the floor, their Y speed is set to -4.
Green Hill
S Tunnels
The S Tunnels in Green Hill Zone simply keep Sonic rolling at all times. If his speed reaches 0 and he stands up, the game acts as if you have pressed down and he rolls again instantly. Since the S tunnels have no flat ground, Sonic will always roll down it and should never just crouch. However, as part of the function making Sonic roll, if his gsp does happen to be 0, it will set his gsp to 2.
Marble
Pushable Blocks
Pushable blocks move 1 pixel at a time while being pushed (the mechanics of which can be found in Solid Objects). They are also constantly checking below themselves to ensure there is floor nearby. If there is no floor directly below their centre when they get pushed, they will change their behaviour. To avoid falling too soon and clipping the corner, they will begin to move at a speed of 4 in the direction of the push until they have moved 16 pixels. At this point they are completely over the ledge that they originally detected. They will then proceed to fall and land as normal.
Spike Traps
When Marble Zone Spike traps fall, their Y Speed increases by 0.4375 each frame. When they reach full length, they spend about 60 frames there. After this they begin to rise by 0.5px per frame, or 1 pixel every 2 frames. The length they can fall varies.
They have a solid box at the top (which Sonic can walk on & push against) however the spike area is a damage hit box which will simply hurt Sonic upon contact but doesn't have solidity.
Scrap Brain
Conveyor Belts
A Scrap Brain Zone conveyor belt will simply add the belt speed to Sonics xpos, Sonic's speeds are unaffected.
Sonic 2 Objects
Chemical Plant
Spring Ramps
Spring ramps aren't quite as simple as normal springs. Firstly, they have a specific region where they actuate.
The ramp will activate if his xpos is within the green region as he stands on it.
When a Spring ramp activates they don't bounce Sonic instantly, instead, Sonic moves down a bit as the animation plays. There are 2 subimages, normal and down, and these both have different collision height arrays as shown below.
On the left is how the solidity appears in-game, on the right is the height array as it is stored, it simply gets scaled by 2 horizontally. The ramps only use this collision data and no hitboxes, and it would be confined to the sprite size (even though it appears to go past it here).
Once activated it plays the down subimage for 4 frames, and Sonic will lower with it but is otherwise unaffected and will keep walking. On the next frame it's back up and Sonic is raised again but still unaffected, on the frame after this Sonic will actually be in the air.
So how fast do they bounce Sonic? Well, that's not perfectly simple either. It will bounce Sonic up with a ysp of -4, and depending on Sonic's xpos position along the ramp it will subtract a second modifier from his ysp. This is all dependant on the positions where Sonic's xpos is right now as he is bounced, not where he was when activated it.
From left to right this modifier can be 0, 1, 2, 3 or 4.
So if Sonic happened to be in section 3, his ysp would become -4, minus the modifier of 2, resulting in -6.
His xsp is also affected, if it's absolute value happens to be larger than or equal to 4, the modifier will be added to (or subtracted from) xsp. If Sonic is in section 3, and he has a speed of 5, his speed would become 5+2. This gets capped at 6 in Sonic 2 due to the speed cap still being present in the air.
Spring Caps
The red spring caps that cover the tubes in Chemical Plant Zone work like springboards, but are slightly stronger than a Yellow springboard. They set Sonic's ysp to -10.5 upon collision.
Spinners
The black spinners that impel you forward in Chemical Plant Zone set xsp to 16. They don't seem to slow you down if you're already moving faster than that, though.
Hill Top
Ski Lifts
The ski lifts in Hill Top Zone move with an xsp of 2, and a ysp of 1.
Sonic 3 Objects
Carnival Night
Balloons
The balloons in Carnival Night Zone set ysp to -7 when Sonic collides with them, no matter what his angle of collision. xsp is not affected.
Balloons have a hitbox with a width radius of 8 and a height radius of 8, resulting in a 17 x 17 rectangle.
Cannons
The cannons in Carnival Night Zone set Sonic's xsp to 16*cosine(p), and ysp to 16*-sine(p), where p is the angle of the cannon.
Sonic and Knuckles Objects
Mushroom Hill
Mushrooms
The mushrooms in Mushroom Hill Zone work just like springboards, only each successive bounce is higher than the last, up to three bounces. The first bounce sets ysp to -6.5, the second, -7.5, and the third, -8.5.
Points
When you hit a Badnik or other point-bearing item (such as Bumpers), a small score notification will fly up out of it. After it spawns at the object's X and Y position, it begins with a Y Speed of -3, and will slow down by 0.09375 each frame. Once it is no longer moving, it will vanish. This will take around 32 frames.