Thursday, 26 November 2015

Game Engine Tutorial 2 - Forethought and Architecture

In the previous tutorial, we had our tools ready. in this one, we are going to look at the scope of our final product, that is in our case the engine we are about to make. A game engine is a big project, and any big project would require some planning to be done beforehand. Many engines start out not having a plan of development, and not many make to the finish without planning. We need to sett;e down on what we want exactly our engine to do, and the sketch out a rough idea on how it would do it elegantly.

Setting a Goal 

Now, we need a goal, don't we? we need a definite and countable  place we would like to reach with our engine. It must be a goal at which we can look at a decide what to do next, and how much effort we need to put into it in order to just achieve that said goal.

In the case of our engine, choosing such a goal is easy. A game engine helps in making games, so we want a game! We will base our milestones on the types of games the engine can produce and power, as that makes the most sense.

So there we have it. We are going to be making a maze game, and in doing so, we would be implementing the features that are required to run that game. What I was thinking was something that looks somewhat like this:


The screenshot is from a GameMaker tutorial. The game in the screenshot is made with GameMaker 8.0 , its from a really old tutorial and is actually isometric, meaning its not actually 3D but a hybrid of 2D and 3D where the lines that are parallel stay parallel even at large distances (orthographic projection). Though this game is made with a 2D engine, we want ours to be capable of 3D, and so we will make this game using real 3D graphics. Its a very basic game, and it would be just perfect for our first milestone. 

What do we need here?
Looking at this game, lets look at what the engine requires to do in order to run it.
  • Windowing. This one is obvious. the game has to be somewhere, and the user needs to see it. And for that, the engine needs to be able to make and draw to a window. this one is by far the most basic this any engine must be able to do. So we need a way to interface with the Operating System and ask it to make us a window.
  • 3D Rendering. The blocks and the ball would have to be represented in a 3D world and shown to the player as a 3D interactive world. Apart from basic 3D rendering, we would also require some directional lighting, so that the walls facing the light are brighter than the walls that are not.
  • Keyboard and Mouse Input. How else would this game be a game if the player is not able to interact with it? We will have to design a robust and flexible input handling system for our game.
  • Collision Detection. We don't want our ball to be going through walls, and for that we need a system which detects when two objects are colliding.
  • Some Game Logic. In the ball maze game, the objective is to find a hidden flag somewhere in the maze. Touching the flag will end the game, probably showing a message telling the player that they won ( instead of just closing off, leaving the player confused).  This is the Game Logic. Each game would have a different game logic and we won't want that logic to be tied to the engine. That calls for a system in which the game logic is somehow specified for each game outside the engine code. That second feature ( showing a wining message) brings us to...
  • A GUI System. For Showing things like buttons and text fields. For now, we will stick to just text fields here.

I think that would be all we would need for our maze game. Oh no, there are actually a few other things we need to consider! These are things which are usually up to the developer, independent of what game is being made. Things like
  • Platform. We need to decide where we want your game to be able to run. is it on a mac? on Linux? Windows? What about console and mobile? For now, the engine is going to support Windows, just like UNDONE does at the moment, but we are going to design it in such a way that porting it to other platforms would be minimal hassle. 
  • Development Language. This decision was already made in the previous post. We will use C++ for totally everything from the core to the scripting.


The Architecture

Now that we have a goal, we need to plan a path to reach it. The engine is obviously not going to be a monolithic ball of code that does all the stuff by itself. It needs some structure - some architecture, so lets decide on that.

It's a good choice to divide the game into modules. From the above requirement, it is evident that the specifics of game logic code must be separated from the engine code. The two of these would make two separate layers, with the game logic sitting on top of the Engine. Further, our requirement for making it cross platform in the future forces us to separated the system specific code into it's own separate module below the engine code. The engine can access the system-specific code through an interface which will be the same for all platforms, so it makes it easy to do cross-platform development. This looks something like this:
The engine itself must be divided into systems, each system being responsible for handling a specific aspect of the game. We would need the Window System for windowing, the Input System for our input, the Graphics System for all things graphics, the GUI System for the buttons and text fields and menus, the Physics System for collusion detection and other stuff., and a Game Logic System, that would manage the calling and dispatching of game logic code. Later we might also have system audio, animation and networking, but that is not important at this moment. 

We would be using the Component based architecture for our Game object. Each Object in our game would be a container for Components, which can be mixed and matched to give us whatever varied behaviour or properties that Game Object would require. Each Component would be associated with a system. The various systems would process the individual components. For example, we would have a Graphic3D Component which associates all the data that is required to render an object and the Graphics System would the have a list of all the Graphic3D components and process them at the time of rendering. 

Games are memory intensive programs, and allocating and deallocating a lot of memory at runtime would be slow and bad. We would also require a Memory Manager to manage all our memory.

Finally we will have an Inter-System Messaging System as well, in order for our varied Systems to be able to communicate and work together.  Together with the core Engine which manages all the systems from an overview, here is what the final architecture would look like :

That is enough to give us an over view of what we have to do. Now, prepare for the next tutorial, because we are about to actually dive into the code. See ya' then!

No comments:

Post a Comment