Sonic and Sega Retro Message Board: How to Build a 2D Sonic Engine - Sonic and Sega Retro Message Board

Jump to content

Hey there, Guest!  (Log In · Register) Help
  • 2 Pages +
  • 1
  • 2
    Locked
    Locked Forum

How to Build a 2D Sonic Engine Starting my own side project

#16 User is offline HedgeHayes 

Posted 01 October 2017 - 08:49 PM

  • Chaos Emeralds, Alola form
  • Posts: 357
  • Joined: 01-June 17
  • Gender:Male
  • Location:Bilbao, Spain
  • Project:Too many of them
Thank you very much, that's the kind of help I needed! Or so it seems, I'll have to put it in practice to really know. I'm not sure about how much I need to do my way and how much use could I make from some already made content, but I wanted to include palettes and block mappings in the same fashion as they are in 16-bit Sonic games, and some other "tiled" effects like the way some ledges crumble. Last time I forgot to tell you that I already had plans on trying rom hacking to understand better how do the original games work because of this all.

As I told you, I know programming and I'm pretty decent at it, but I know nothing at all about coding game related things besides making all the tutorials and checking all the examples from GMStudio1, and I want to do more than what that toolkit allows me to, and I don't like buying a new version every 2 years (at least GMS1 had a usable free version), so I chose to do my own engine even if it's a long, hard and tedious task. Maths will be the hardest part, I have it almost forgotten, and I didn't know that much in the past, but I'm smart and confident about my coding capabilities; not that much about my time managing ones, though. :v:

Thanks again, let me ask you just a little question that has come to my mind after checking the links: Is there something useful to find in GameDev, or something that makes creating an account there worth enough? That website was one of my only hints to try and find something like what you've told me.

#17 User is offline Zphase 

Posted 01 October 2017 - 08:55 PM

  • Posts: 8
  • Joined: 19-June 17
This retro engine sounds kinda like you may be able to use it, or just check it out for ideas.

http://www.tilengine.org/index.htm

post #4 from forum
http://www.tilengine...hread.php?tid=6

Quote

Your best bet for "companion libraries" is the SDL ecosystem (SDL + SDL_Mixer): they're open source, cross-platform and give everything you need to build a game, including tracked music (I'm a longtime fan of MODs, since the early 90s Smile ). Lots of commercial games are built on top of it, and the default windowing in tilengine uses it too, so its source code can be already used as a starting point:

https://www.libsdl.org/
https://www.libsdl.o...ects/SDL_mixer/

It has a basic sonic background demo and it also has c# bindings

here is a video
https://www.youtube....h?v=wjrCPRD1BKk

#18 User is offline Aerosol 

Posted 01 October 2017 - 09:58 PM

  • FML and FU2
  • Posts: 9937
  • Joined: 27-April 08
  • Gender:Male
  • Location:Not where I want to be.
  • Project:Sonic (?): Coming summer of 2055...?
Hey that TileEngine thing is neato.

I just started faffing about with Godot Engine myself.

#19 User is offline Lapper 

Posted 02 October 2017 - 03:58 AM

  • Posts: 1462
  • Joined: 15-June 08
  • Gender:Male
  • Location:England
  • Project:Sonic 2 HD, Sonic Studio
  • Wiki edits:111
While the actual process of making the engine is up to you, what doesn't change is how the collision actually *should* happen. There are methods using tiles and methods using vectors but other than that, it's always the same if you want authentic results (unless you don't care about accuracy)

Posted Image

2 floor sensors (red), 2 ceiling sensors (green) and 1 wall sensing line (blue). I've illustrated him as a box but honestly he is just a bunch of 'lines' when it comes to collision.

His wall sensor is illustrated as 4px below the centre, however I think it's actually 8px below his centre and then ends up right at your centre when you are on any kind of incline. 4px is a good average though because I'm not certain, I bet someone could shed light on that. It pokes out 1px each side (it's effectively 2, one side pushes you out of solids left, and the other right).

His floor sensors will always pick the highest point it finds (if it finds 2). The second illustration shows how far these sensors actually check into the ground (they only extend like this when he's already on the ground).
So while he's on the ground, if those extended sensors find anything, he'll stick to the highest one found. The only time he stops is when that wall sensor touches anything, which would only happen against a wall. This means he'll never just come off a slope, he'll stick to it unless it's a 16px or higher cliff

The ceiling sensors are exactly the same when seeking, but of course react different when they find something. A flat ceiling wont attach you, it'll just stop your Y Speed. Other angles will rotate you correctly and stick you as if they were floor sensors, using the ceiling sensors as floor values, as described above.

As someone said above also, this whole setup will rotate 90 degrees for walking on walls, ceilings, etc. So on a flat angle (0 degrees) if you walk up a curve and pass 45 degrees, it'll all flip sideways.

Of course, that's just collision. How his speeds change and how he reacts to things is all about using the right values and trig.
http://info.sonicret...SPG:Solid_Tiles
This post has been edited by Lapper: 02 October 2017 - 05:13 AM

#20 User is offline HedgeHayes 

Posted 02 October 2017 - 08:15 AM

  • Chaos Emeralds, Alola form
  • Posts: 357
  • Joined: 01-June 17
  • Gender:Male
  • Location:Bilbao, Spain
  • Project:Too many of them

View PostZphase, on 01 October 2017 - 08:55 PM, said:

This retro engine sounds kinda like you may be able to use it, or just check it out for ideas.

http://www.tilengine.org/index.htm

post #4 from forum
http://www.tilengine...hread.php?tid=6

Quote

Your best bet for "companion libraries" is the SDL ecosystem (SDL + SDL_Mixer): they're open source, cross-platform and give everything you need to build a game, including tracked music (I'm a longtime fan of MODs, since the early 90s Smile ). Lots of commercial games are built on top of it, and the default windowing in tilengine uses it too, so its source code can be already used as a starting point:

https://www.libsdl.org/
https://www.libsdl.o...ects/SDL_mixer/

It has a basic sonic background demo and it also has c# bindings

here is a video
https://www.youtube....h?v=wjrCPRD1BKk

View PostAerosol, on 01 October 2017 - 09:58 PM, said:

Hey that TileEngine thing is neato.

I just started faffing about with Godot Engine myself.

My goal is a multi-platform C++ only engine, but I'll check anything helpful, just in case. ;)


View PostLapper, on 02 October 2017 - 03:58 AM, said:

While the actual process of making the engine is up to you, what doesn't change is how the collision actually *should* happen. There are methods using tiles and methods using vectors but other than that, it's always the same if you want authentic results (unless you don't care about accuracy)

Posted Image

2 floor sensors (red), 2 ceiling sensors (green) and 1 wall sensing line (blue). I've illustrated him as a box but honestly he is just a bunch of 'lines' when it comes to collision.

His wall sensor is illustrated as 4px below the centre, however I think it's actually 8px below his centre and then ends up right at your centre when you are on any kind of incline. 4px is a good average though because I'm not certain, I bet someone could shed light on that. It pokes out 1px each side (it's effectively 2, one side pushes you out of solids left, and the other right).

His floor sensors will always pick the highest point it finds (if it finds 2). The second illustration shows how far these sensors actually check into the ground (they only extend like this when he's already on the ground).
So while he's on the ground, if those extended sensors find anything, he'll stick to the highest one found. The only time he stops is when that wall sensor touches anything, which would only happen against a wall. This means he'll never just come off a slope, he'll stick to it unless it's a 16px or higher cliff

The ceiling sensors are exactly the same when seeking, but of course react different when they find something. A flat ceiling wont attach you, it'll just stop your Y Speed. Other angles will rotate you correctly and stick you as if they were floor sensors, using the ceiling sensors as floor values, as described above.

As someone said above also, this whole setup will rotate 90 degrees for walking on walls, ceilings, etc. So on a flat angle (0 degrees) if you walk up a curve and pass 45 degrees, it'll all flip sideways.

Of course, that's just collision. How his speeds change and how he reacts to things is all about using the right values and trig.
http://info.sonicret...SPG:Solid_Tiles

I' read most of the SPG past year, and also checked the GMate engine at the beginning of this one. I figured out a lot on how layout and object collision worked back in the pre-3D days, so I think this battle is already won, but I needed to know the low level coding to do what I want or, at least, start from where I want. Thanks for your time anyway, I appreciate a lot there's so many people willing to help with this.

#21 User is offline Cooljerk 

Posted 02 October 2017 - 09:07 AM

  • NotEqual Tech, Inc - VR & Game Dev
  • Posts: 4198
  • Joined: 06-April 06
  • Gender:Male
  • Wiki edits:9

View PostLapper, on 02 October 2017 - 03:58 AM, said:

While the actual process of making the engine is up to you, what doesn't change is how the collision actually *should* happen. There are methods using tiles and methods using vectors but other than that, it's always the same if you want authentic results (unless you don't care about accuracy)

...

Of course, that's just collision. How his speeds change and how he reacts to things is all about using the right values and trig.
http://info.sonicret...SPG:Solid_Tiles


Actually, this doesn't paint the entire picture for collision, and there are multitidue of ways to check for collision, some faster than others. While you are correct, for the purposes of Sonic, at some point, you're going to need to do this (which is really just basic trigonometry), how you check for collision, and how often is incredibly important. For example, you don't want to have to check every single point on the screen, that is what results in poor performance (and usually will make your CPU load increase by a ton). There are plenty of collision checking methods out there, from a simple axis-aligned bounding box, to complex circle collision, and a near infinite amount of methods in between.

However, what is smart (and generally not talked about, and not covered at all in the physic guide) is the general approach one should probably take for collision detection. In most game programming, this involves splitting collision into two phases - a broad collision detection phase, and a narrow collision detection phase. You have described one manner of narrow collision detection, but broad collision detection is just as important. The idea behind this principle is that you have a speedier method of collision detection that checks the entire screen first, to determine where and within what range to do the slower, narrower check that you just described.

Myself? I use morton encoding, it's a variant of octrees that isn't really taught very often. Moron encoding is a method where you keep a list of every object available on screen at once, be they ground tiles or enemies or whatever. By taking these objects X and Y coordinates and representing them in binary, then interleaving their bits, you arrive at a morton encoded string. To give an example, say I have 4 objects, at the following positions:

1, 2 -> 001, 010 -> 000110
2, 2 -> 010, 010 -> 001100
4, 3 -> 100, 011 -> 100101
5, 4 -> 101, 100 -> 110010

There is an interesting phenomenon regarding binary representations of space which morton encoding exploits. Due to the nature of binary spacing, each bit in a morton encoded string will divide the considered screen space in half. This means that, if you begin at 000000 and increase all the way to 111111 you will follow a Z-ordered space filling curve like so:

Posted Image

This plays into the concept of the principle of locality, where objects near each other are stored next to each other in memory. Using such curves for general collision detection allows you, for example, to limit a range around sonic (or whatever) to ensure you only check collision around immediately relative objects. It makes no sense, for example, to use expensive narrow collision detection half-way across the screen when it'd be impossible for those two objects to collide.

You could visualize the collision checks like so:

Posted Image

Where each "box" is a collision check. You see that using a space filling curve like this drastically reduces the number of collision checks necessary.

I generally use morton encoding to check for collisions among objects in my memory pool (which, again, plays into how important properly implimenting a memory pool is, because, for example, if objects spawned in your pool automatically spawn in-order then that's one more sort that you don't have to spend time doing -- I use what is known as a free list, that is -- a linked list that uses a union in memory to act as a map for the next available open slot simultaneously -- to speed up my auto sort upon creation. Also -- there are many, many ways to morton encode - some faster than others), but for ground collision detection, I use another method.

The way Sonic levels are organized -- by chunk -> block -> tile -- lends itself to a method known as Data Binning. I only have to check the number of chunks visible on the screen, then check the number of blocks visible in each chunk, in order to accurately figure out where to narrow my collision detection to, rather than using narrow collision detection all over the screen at once, because if Sonic is in 1 chunk, he is assuredly not in any other.

This is precisely what I mean when I say that there is no single right or wrong way to implement any of this stuff. You can get 10 programmers together and have them write the "same" collision detection routines, and wind up with 10 radically different collision detection systems, that all do precisely the same narrow logic.
This post has been edited by Cooljerk: 02 October 2017 - 09:19 AM

#22 User is offline HedgeHayes 

Posted 02 October 2017 - 12:09 PM

  • Chaos Emeralds, Alola form
  • Posts: 357
  • Joined: 01-June 17
  • Gender:Male
  • Location:Bilbao, Spain
  • Project:Too many of them
Well, I suppose I would keep a track of which objects need to be loaded on screen plus a bigger area (maybe 3 x 3 screens, with the actual screen as the center one), and check their collision boundaries are inside others' boundaries as well if relevant, so I'd check only objects too near to sonic's position to know about his collisions, but others could interact between them in other positions if necessary. Since the terrain is a collision map, I would have it loaded, not sure if for all the map once or for the above described area each time it changes, and make proper collision checks for every present object with the terrain when necessary (for example, not necessary for buzz bombers which fly and ignore the terrain). Objects in the given area should probably mapped as some sort of "collision tiles" to track their collision more easily, or maybe outright by necessity. Well, I think I messed a couple of concepts here, and I won't talk any more to avoid evidencing my ignorance, but that's the rough idea that makes sense to me to start with.

That said, I don't get most of the technical terms, callback functions and binary trees are the farthest they taught me about that level of programming when I learnt C. With C++ they went directly to object specific questions, so I'm OK with operator overloads, inheritance, etc., but nothing more about algorhytms when working with the "big picture" (no pun intended). It's still great because it helps me getting interested in learning more and go for it, a shame I didn't try to learn this before.

#23 User is offline lotzi 

Posted 25 November 2017 - 08:26 PM

  • Posts: 6
  • Joined: 24-September 17
  • Gender:Male
So I've been working on learning C++ while trying to implement a basic game engine with what I learn. However, I feel like I haven't made that much progress with the engine. I still have a lot to learn about C++, but I do not know enough to build an engine. I was thinking I should work with the Unreal Engine while I learn C++, and then start building my own engine once I'm more comfortable with the language. What is everyone's opinion on my issue? Should I work with an established engine first, or does it not make a difference if I start building my own engine?

#24 User is offline winterhell 

Posted 26 November 2017 - 03:27 AM

  • Posts: 1141
  • Joined: 16-October 10
  • Gender:Male
How far did you get with game making? Can you show some examples in pictures or a video? It'll help with giving you further advice.
This post has been edited by winterhell: 26 November 2017 - 03:27 AM

#25 User is offline Amnimator 

Posted 26 November 2017 - 05:49 AM

  • Posts: 222
  • Joined: 15-April 13
  • Gender:Male
@Cooljerk - Thanks for writing that out. As someone who dipped his toes in handling 3D collision, it's neat to see some good ideas how to handle it if someone were to go and make it all from scratch. For now, I use Nvidia PhysX for collision detection, and handle response by myself, but there's reasons why I'd want to be able to code collision detection from scratch-ish sometime down the line. What I do is that I go for a simple higher level (but not the world's most efficient) approach:

- Get the start point and end point of a physics calculation.
- Divide the path into a few nodes.
- Do collision on each node. If I don't hit anything, apply position from the physics calculation, otherwise apply position from collision response.

I got the idea from Mario 64s half-steps and quarter-steps. Simply dividing your path into 4 can handle insane speeds reliably. Obviously it's not ground breaking, but there's a whole lot of ways you can tackle this if you're like me, and don't have all that technical know-how (yet :V).

It's neat to have some direction if I eventually try to make this faster and do the detection part myself, you can skip a whole lot of checks having to deal things in a broad-narrow kind of way. For now I'm worried more about functionality. But as you said, there's many ways to tackle this (although, not all methods will be as efficient).
This post has been edited by Amnimator: 26 November 2017 - 06:39 AM

#26 User is offline HedgeHayes 

Posted 27 November 2017 - 12:02 PM

  • Chaos Emeralds, Alola form
  • Posts: 357
  • Joined: 01-June 17
  • Gender:Male
  • Location:Bilbao, Spain
  • Project:Too many of them

View Postlotzi, on 25 November 2017 - 08:26 PM, said:

So I've been working on learning C++ while trying to implement a basic game engine with what I learn. However, I feel like I haven't made that much progress with the engine. I still have a lot to learn about C++, but I do not know enough to build an engine. I was thinking I should work with the Unreal Engine while I learn C++, and then start building my own engine once I'm more comfortable with the language. What is everyone's opinion on my issue? Should I work with an established engine first, or does it not make a difference if I start building my own engine?

Depends on how much you knew about programming before starting learning C++, but looks to me like you're trying to run before knowing how to walk. You should try having a solid knowledge of the language and a comfortable use of it at its base to start building something over it, not to mention CoolJerk gave us an extensive list of things to know, so just C++ may not be enough to try what you want. As WinterHell says, it would be easier to answer you if you give more details.

#27 User is offline Gammatron 

Posted 28 November 2017 - 09:01 PM

  • Posts: 70
  • Joined: 26-June 17

View PostZphase, on 01 October 2017 - 08:55 PM, said:

This retro engine sounds kinda like you may be able to use it, or just check it out for ideas.

http://www.tilengine.org/index.htm

post #4 from forum
http://www.tilengine...hread.php?tid=6

Quote

Your best bet for "companion libraries" is the SDL ecosystem (SDL + SDL_Mixer): they're open source, cross-platform and give everything you need to build a game, including tracked music (I'm a longtime fan of MODs, since the early 90s Smile ). Lots of commercial games are built on top of it, and the default windowing in tilengine uses it too, so its source code can be already used as a starting point:

https://www.libsdl.org/
https://www.libsdl.o...ects/SDL_mixer/

It has a basic sonic background demo and it also has c# bindings

here is a video
https://www.youtube....h?v=wjrCPRD1BKk


That tileengine thing is sweet. I might start faffing about in real programming languages and get away from Game Maker with stuff like that available.

I wouldn't make a Sonic game, though. Classic Sonic is one the most advanced and complicated 2D platformers out there. I think a lot of people underestimate just how much of a technical marvel Sonic the Hedgehog was and still is. There were no games like it before 1991 and there haven't been very many since '94. It kind of blows my mind how they wrote all of that stuff in assembly. It's way above my head.

  • 2 Pages +
  • 1
  • 2
    Locked
    Locked Forum

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users