Uniracers physics

Started by
8 comments, last by JavaWorksForMe 19 years, 2 months ago
Who remembers Uniracers? If not, who remembers Sonic the Hedgehog? In the past few days I've adamantly been trying to find any information I can on the collision detection in Sonic the Hedgehog games. Unforunately, the most I've been able to find is information on ROM hacking and a few fan game coders who have yet to respond. While the information on the ROM hacking sites has proven insightful about how collision information was actually stored, it has not been useful on how collisions are dealt with and handled. Uniracers recently came to mind as a game with similar (perhaps better) physics. In the old days of 16 bit programming, how was motion on slopes and curved surfaces accomplished? I feel like there is a lot to be learned from looking at classic examples, but unfortunately the knowledge doesn't seem to be there unless you're willing (or able) to dive through thousands of lines of assembly code and try to figure it out. People are rapidly moving to 3D as the solution to all their problems in terms of gameplay, but it's no secret that 2D has its nostalgia value. So why are all the tricks of the 2D trade so hard to come by when they seem to be so established? The hidden question in this thread is where are all the veterans, but my actual question is where can I even start when trying to clone a game like Sonic or Uniracers? Traditional tile-based games are easy. Is the block solid, or isn't it. Move in the x, move in the y, correct for collision. So what about speed games with curvy environments where your speed can actually determine your ability to stick to a wall or ceiling? Are there any hints at all for modelling this sort of world? If it was done on 16-bit systems, it can't have been hard. Anyone? Cheers
Advertisement
Yeah, info on old-school game mechanics is practically non-existant online, but luckily I work in handhelds so I have some concept of how it was done.
The answer is mostly finite state machines. Once you have some good data structures, it's pretty easy to detect a collision. The challenge is in responding to it.

In Sonic, there was most likely an 'on the ground' mode, where your Y position gets snapped to the ground level. Then if you jump, switch to 'going up', where you have a constant upward velocity as long as you hold the jump button down, or until a certain amount of time has passed.
When either of those happens, switch to 'falling' mode, where more realistic physics take over, and leave your velocity upward so gravity slows you down gradually before you start to go down. If you collide with the ground, which back to ground mode.

Idle/walk/run/spin were probably seperate states within the more general ground mode. Also, in the 'snap to ground' function, before you snap, make sure the distance to the new ground level is small enough, otherwise switch to falling mode. That will automatically handle walking off edges.

For loops, put a trigger at the bottom of it that says "if you're going fast enough, switch to 'going around a loop' mode, otherwise just stay in normal walking mode". In loop mode, check if your speed gets too low, and if it does switch to walk mode again (which will then switch to fall mode if you're upside down at the top, because of the ground distance check).


The key is in keeping it simple. The physics aren't real at all, it's just a bunch of state transitions that have different movement processes.
Another thing you'll notice is that in most old platform games, when you get hit by a bad guy, you flash and can go through bad guys for a while. That's just a sneaky way to get out of dealing with colliding with more than one sprite at a time :)
The snapping to ground makes sense for another reason. In Sonic, if you had a ledge that immediately dropped off into a half pipe, and you ran straight off the ledge into the half pipe, instead of sliding of the edge and arcing down to the ground due to gravity, you actually take a sudden 90 degree turn downward and start following the half-pipe curve.

I guess I wanted to think of things as being a little bit more feature rich. Here I was trying to figure out how they worked centrifugal force into a Genesis because I was hoping to avoid having special states for things. I guess it's unavoidable though.

Thanks for the tip. Anyone else out there with experience?
I actually Programmed a sonic 2 clone a few years ago. It had loops, hills, slopes, curves, sand slides, etc.. As mentioned, I used states for many things like walking, running, jumping... you know, the standard stuff. But when it came to loops and other collision, I created a common 'collision block set' that I attached to the tile groupings I made.
ie:
4 8x8 tiles = 1 16x16 block
64 16x16 blocks = 1 8x8 cluster
and each cluster has 2 collision clusters made in the same way(for loop perposes). If you pay close attention to Sonic, you will notice that whenever he goes around a loop, at the tip top he hits a 'special sprite' that esentially switches to either collision map 1 or 2 depending on whether he is moving left or right. Therefor, the first half of the loop is on collision map 1 and the second is on collision map 2.

AAAAAAAAAAAAaaaaaaaaaanyways...

To achive rotation, I created an object state named 'CurrentRotation' that could be either ROTATION_0, ROTATION_90, ROTATION_180, or ROTATION_270 depending on what 'wall' sonic was running on. Next, whenever sonic hit a 45 degree angle slope his rotation switched to the next rotation in the diraction he is going(clockwise or counter-clockwise) and I basically flipped the x&y coordinates when calling the collision function depending on what direction he was rotated in:

ROTATION_0 = (x,y)
ROTATION_90 = (-y,x)
ROTATION_180 = (-x,-y)
ROTATION_270 = (y,-x)

Umm.... Thats kinda a chunk of what I did. I used to have the game on angelfire a loooooooooooong time ago, but I don't remember the address now, and I think its gone anyways. If you really want, I could send you the really old, ugly, bloaded code I wrote(MSVC 1.0!!!) for you to look at. lmk k?

Goodluck,
-Linolium
The Great and All Powerful Linolium
Linolium - I would like to take a look. According to the ROM collision information, something similar was done. 8x8 image tiles were combined into 16x16 tiles, which were then tied to collision data that, in two parts, defined where the tile was solid, and what its slope was. The confusing part about that is the part that defined the slope -- it was a single byte which was split in two, for two values between 0 and 15. For visualization, these two numbers would be placed on parallel vertical lines (basically the left and right side of the tile), and the slope of the line formed between them could be interpolated. This was how Sonic games achieved something other than just 0-45-90 degree angles.

What I don't understand is how that schema went beyond 45 degrees.. obviously if one number is 0 and the other is 15, that's 45 degrees (or -45 if the two are flipped). I don't know if there were extra flags to rotate those collision blocks or what.

Also, I know the special sprite you're talking about, it shows up as 4 vertically aligned rings when you're in debug mode. I can't say I like the idea of using an invisible entity to cause collision zone swapping, but sometimes there are necessary evils.

Still, coding on today's computers means I'm not really in need of bit packing, so I guess I can give a tile whatever slope I want. =P
Ok, I'll try and dig up the code. I belive I still have it. I warn you, it is VERRRRRRRRY UGLY! and you probably won't be able to compile it... but atleast it'll be there. now I dunno if I screwed with it at all since it last worked so its given on an as-is with no garontee.

As far as bit packing goes, there is none. I calculated the slopes of line segments depending on what tile group you were on- so there are lots of if/then statements(hence why I have a common collision block set ;) ).

I'll also include the level editor with the game/game-code so you can more easaly visualize what I did. Again, this was programmed using dos' mode 13h and will run really freak'n fast on todays comps. If you have an old 300esh MHZ machine around with windows 98, run it on that for more accurate speed results. I'll e-mail this stuff to the address you have on gd-net with a little more info on it.

Peace,
-Linolium

PS. heh.. eyeball icon... heh...
The Great and All Powerful Linolium
ok... so aparently, according to MSN/Hotmail, the zipped up source I'm sending you contains a virus, so it's not letting me send it. I scanned it using Panda-Active Scan serveses to find no problems with the files...

so until I can figure out this problem, you kinda outta luck dude. sorry <:^(

I'll fix this asap to send you the files, so hang tight.
-Linolium
The Great and All Powerful Linolium
Yeah, hotmal has gotten really screwy about zip files lately. Just rename the extension to .bin or something unused and it doesn't care anymore. I'd like to see your Sonic clone too, if you wouldn't mind shipping it to my screen name here @hotmail.com.

For the sloped tiles, I think they just never have slopes > 45 degrees, except for the loops, and those are probably handled specially as an actual curve rather than a straight slope (much like Linolium's system, I think).

Personally I think invisible entities are a fine way of handling special events. Mostly an easy way to recycle the collision code. It's only a hack if your engine isn't designed for it and forces you to make a transparent image to load :)
Well, I was able to send each file as an attachment finally(I forgot to give the message a title btw. Its from Linolium)... but only to Deku. Java: I need your e-mail if you want these files.

-Linolium
The Great and All Powerful Linolium
Whoops, guess I didn't have it public.

It's gtg661g@mail.gatech.edu

This topic is closed to new replies.

Advertisement