So last night I was up until the early hours working on my new game engine for the Oni World game series. I had code block (writers block for programmers), and couldn't think of what to write. So I decided to
write this blog post...
So I'm currently working on a new, advanced 2D game engine for my latest project: The Oni World series. One of the hardest things I've come across so far is getting a proper working structure down, and without this I can't think of what to code next. I've just been programming little bits of each subsystem, such as the "smart textures" idea I had (more on that soon).
Tried searching around for an example of how to structure a game engine in an efficient and scalable manner, but I can't seem to find anything relevant. So, I threw together this flowchart to outline how a decent engine should behave:
Now don't get me wrong, this is far from perfect. Any criticisms are welcome. Now lets break it down a little...
MainSo to begin, every program needs a "Main" class. For us, this class is simply called "Oni" and is the base for the entire engine. This class actually doesn't contain much. In our case, it contains a few event declarations since our engine is event based, detecting what platform we're on, a screen manager and an input manager.
Screen managerOne thing that I see people doing is listing screens in their main class, or not having any separate screens at all. The best way to manage the different game states, or "screens", is by having a central manager that controls switching between each state. We have a class for each state/screen that inherits from a base "Screen" class. This allows us to transition between each screen easily and in an organised way. It's also scalable, which is very important if you want to reuse a game engine.
Input managerArguably the most important system for a game engine is the input manager. Input is everything in games, if the controls are hard to learn or don't feel right, the players get frustrated and then dislike the entire game just because they can't figure out how to jump - for example. The input manager should handle any input from the keyboard, mouse, controllers/joysticks and transform it into workable events. For example, if my game supported keyboard controls as well as an xbox controller, I would need to manage both of these input types yet produce the same outcome. If I didn't have one central manager handling this, I would have to check what controller we're using for every subsystem that needs to use input. That would be time consuming and overall, stupid. Instead, we can just have the input manager fire off events like "MOVE_PLAYER_LEFT" whenever the left arrow key or the analog stick was moved (I love event based systems).
Game screenNow we have the base covered, we can move onto our game screen. I'm not going to cover the menu screen or settings screen, as they are just examples of different types of screens that can be used. The game screens primary components are the entity manager and the scene renderer, followed by the script manager and then the sound renderer. The game screen doesn't do much besides handle a transition to and from itself and containing the components mentioned above.
Scene rendererA scene renderer doesn't have to be complicated at all, it really depends on what you wish to achieve visually with your game. For the Oni World games, we want some awesome lighting effects - so we've implemented a lighting system. For this we need to take a diffuse map and a light map to produce a "composite" map (which is what the player sees). However, a scene renderer for a simpler game could just be a loop drawing all the sprites. They can also be as complicated as to use multi pass rendering with various shader effects in play. The entire look of the game is supported by the scene renderer.
Entity managerYour game is comprised of entities (sometimes called sprites), and as such you need something to manage them since there are often a lot of entities at any given time. Entities can range from player characters, to NPCs, to event triggers and even lights. The entity manager will handling adding, updating and the eventual removal of entities. It should work, in theory, with the scene renderer, sound renderer and script manager.
Script managerIf you want your game to be any good, you should really have some form of scripting in there (even if its just simple event triggers). Otherwise, gameplay can get very boring and repetitive. This doesn't mean that your level designers should know how to code, you can make it a purely visual thing for them. However, you'll still need something to manage these scripts on the backend. The script manager will parse any code given to it at runtime and interact with the sound manager and the entity manager. For example, a player jumping on a button to open a door would probably be handled by some kind of script manager (albeit a basic one).
Sound rendererIf you want a good level of immersion in your game, sounds are essential. Background music isn't always needed, but is great - so you need something that'll loop that for you. You also need something that will take one-off sounds, such as mario squishing a dirty goomba or taking shrooms. There isn't much else to say, besides that make sure you can invoke sounds from the script manager and the entities at the very least.
Physics, AI etc...Ok so this should be self explanatory. You need some systems working in the background to aid your game, from a simple tile-tile collision manager to a full blown physics engine like Box2D. AI, or artificial intelligence, is what NPCs use to be able to move around, attack the player and even die. AI can be very simple, but it can also be very, very complex. I recommend reading a few books or articles on artificial intelligence to get a basic idea down.
Wrap it upAlright so that's my outline of a game engine. This was written from a 2D perspective, but you can easily translate this into a 3D engine. Although, for a good 3D engine there is alot more that needs to be covered. Hopefully you learned something from this, and feel free to suggest any alterations or ask any questions.