Ask anyone and you will get a variety of answers; A quick Google search defines Game Engine as such:
In computing, a game engine is the core software component of a video game. It typically handles rendering and other necessary technology, but might also handle additional tasks such as game AI, collision detection between game objects, etc. The most common element that a game engine provides is graphics rendering facilities (2D or 3D).
This definition primarily centers around graphics facilities, but does touch upon other aspects.
The problem is Game Engine is a small word used to describe a large number of types of software.
What's in a name?
As the heading suggests, many things can be considered 'game engines' things such as:
- source code libraries (.h,.cpp,etc.)
- binary libraries (.lib,.dll,etc.)
- Game Development Tools (gamemaker,etc.)
- Data Driven Game Applications
One thing these all have in common is they strive to make game development easier.
What do I care?
As an indie developer (as I'm sure you are, given that you're reading this), you are likely working on a game.
This brings us to yet another distinction:
Game: an application with a finite number of game play concepts.
Game Engine: a solution used to aid in the creation of Games.
Let's choose a definition.
For all purposes in this article a Game Engine will mean:
A piece of software that maintains the 'Game World' and enables a developer to create and modify
the game world based on data files and external scripts.
Which are you making?
With this newfound knowledge it is important to ask yourself, "what I am trying to make?".
If you are making a Game it may be necessary to use a Game Engine, to simplify the development process.
If you are making a Game Engine it will be developed to reduce the effort of creating one or more Games.
To make or not to make, that is definitely the question!
Make no mistake about it, building a Game or a Game Engine is not trivial, however some Games and Game Engines are more trivial than others.
If you want to make a game, you need to decide if the game will need an engine.
For the most part, games like this Do Not need engines:
- Pac Man
- Platformers (trivial ones)
- Space Shooters (trivial ones)
However the above games can benefit from the use of an engine, for example:
A pong engine, would encapsulate the rules and game mechanics of Pong as well as the input, rendering, audio, etc.
It would allow the developer to determine the dimensions of certain game elements (ball, paddle, etc) and their look and function. Additional rules (such as 2 out of 3 scoring) could be created via scripts.
The purpose of this engine would be to distill the common elements of what makes pong, pong, and externalize all of the elements that make one pong game different from the next (look, feel, rules, etc.)
This would allow a developer to focus on a far smaller subset of features when making multiple pong games, instead of writing the core functionality.
Games that do benefit from engines are typically games with non-trivial game play mechanics, rendering, audio and world data.
These games use engines to provide a base level ambiguous world governed by basic game rules, and allow the developer to manipulate the world's environments, characters, themes, audio, items, etc. in short, the game content.
Games such as these benefit from engines:
- Graphic Adventures
- Role Playing Games
- First and Third Person Shooters(non trivial ones)
- Simulations(non trivial ones)
- Real Time and Turn Based Strategy
- Racing Games(non trivial ones)
If you are most interested in creating a game, then you are better off using an existing engine, or writing a game which does not need an engine.
For the remainder of this article I will assume you are writing your game engine from scratch.
So you want to write a game engine?
So after careful consideration you have decided you are going to make a game engine due to one of the following:
- I want to learn how.
- I enjoy it.
- There is no engine available that will do what I want.
- I'm just stupid and stubborn.
For the record, I happen to fall in the categories of, learning, enjoying and stupidity.
I've written three complete engines to date, over a period of about five years, so I think I am somewhat qualified to speak about it.
So first off, within reason, there are a few things that all game engines need; these are the things I will cover.
At the end of this article assuming you've read and understood what I've written you should have a new understanding
of just what a game engine is and how it's basic structure can feature can be composed.
Before we even get started I would like to speak a bit about development attitude and how the proper attitude can save you lots of time and fustration.
For starters are some mantras:
If it can save time without compromising quality then it is a good thing.
The goal here is to get something done; there are plenty of people 'working at it' but few people who have much to show for their time. Saving time can range from cutting to simplification of features to using existing tools or technologies to save on development effort.
Sometimes I must solve with design and other times tech.
There are some features which are incredibly difficult to implement. Sometimes sacrificing a bit of this feature (design) can ease its implementation (tech).
Other times a design can be enhanced easily through the use of simple tech.
The Less Code I Write The Fewer Bugs It May Have.
Using tried, true and tested code from reputable sources to aid in reaching your goals, reduces the potential of you making mistakes.
Fewer mistakes mean fewer bugs, and fewer bugs means more sleep.
The structure of an engine.
As previously stated a Game Engine is an application, a piece of software designed to do certain tasks to process input and give output, this is something most software has in common.
Data is a general term for information, which is a very broad subject. In games we are concerned with many different types of information.
- Image Data
- Map Data
- Audio Data
- User Input Data
- Script Data
- And loads more...
The data that the engine has loaded at any given time can be referred to as it's State.
State is very important to us; it governs what our engine is currently doing.
A common pitfall for the novice engine developer is to ignore how special state is, they tend to boil it down to just 'variables' scattered all over the place, it is however, very important to keep your state well organized because for most games the ability to save and restore this state is very important.
The Engine Foundation
Anyone can tell you, the number 1 is very symbolic; it is one more than nothing, but not more than one. In your game-engine if it's more than a trivial game there should be one class that acts as the root of the entire system.
The Engine Class is what you might call it, and there are many ways to implement it.
Some people would make the class and have a global variable to its instance:
Engine* engine=new Engine();
Others could use a singleton or a monostate pattern, and still there are other ways I won't cover.
For my purposes, I tend to use the singleton pattern for my engine class, given that I rarely use
the singleton pattern it makes things special enough to remind me that class Engine is special.
While I won't cover the singleton pattern here, its main purpose is to provide automatic creation and deletion and to insure that it can only be instantiated once, and that the single instance can be acquired through a static method of the class.
//Engine object returning its single instance pointer and calling init on it
Your engine class should have an init method, which is called via the entry point (main function)
of your application, the init function is responsible for 'booting' the engine, initializing:
And handing control over to the scripting system for further init.
Your engine instance will have many variables, but the most important ones make up the application and game state information.
A state is a configuration that a Data Model is in at a specific point in time. By default a state is Transient this means that for each game session the state is set to its default value. In a game engine we deal with different categories of state, some we want to be Transient and others we want to persist, which means for each engine sessions you can restore the state to the state it was previously in.
The application state is the state of the engine and all of its supporting systems. Application state is not directly part of the game data and is not saved with each game-state instance.
Transient Application State
Most simple applications exclusively use a transient state. When the application is run, its state is initialized to defaults, and through the course of the application use the state is changed.
In a game engine transient application state could be the main menu state, which is always set to be the first thing you see.
Persistent Application State
Some aspects of application state should be preserved across game sessions. A good example of this are user settings, each time a user starts a session the engine will reload the previous, display, audio, control, etc. settings that the user previously chose automatically, it is as if the session never ended.
The game state is the data representation of the game in its current state, saving a game state, and reloading it later should produce the illusion that the session never ended.
Transient Game State
Game state data that is not saved between sessions and is always reset to default values. This is very rare but it sometimes helpful.
Persistent Game State
Persistent game state data makes up the current state of the game. This is the most important kind of state data for a game-engine.
A game-state of guess-the-word might look like this:
word; //the word to guess
A game-state of tic-tac-toe the game-state might look something like:
whosTurn; //(X or O)
square; //game board (X, O or Empty)
A game-state of Tetris might look something like this:
timeLeft; //time counter
music; //music index (0,1,2)
nextPiece; //piece type index
currentPiece; //pointer to current falling piece object
difficulty; //0,1,2 (easy, med, hard)
board; //array of all piece objects on the board
As you can see as game complexity increases so does its game-state, just imagine the game-state for a typical platformer!
State of the State
As you've seen a game-state can be as small as a single variable, or could be many, many variables and complex objects. On important aspect of game-state is that can be in two states.
It can be clean or dirty
A Clean state is a newly created and unmodified state (sometimes called pristine, or default). A Dirty state is a state that was once clean but has now become modified.
Your game should have a well defined way to setting its current Game-State to Clean. If you have only a few variables cleaning a game state might be as simple as setting a few values to defaults. However in more complex games an easier method is preferred.
With object oriented programming, you can define a state as a class; its default constructor can initialize the state to its default settings. Using this method creating a new game-state (New Game command) is as simple as deleting the existing game-state object and instantiating a new one.
Having your data nicely arranged into a state object allows for you to easily save a representation of the state to a persistent storage, such as a Hard Disk Drive. Later this stored state can be re-created into a new state object and used as the current game-state to allow the player to continue where they left off.
The process of transferring objects between volatile and persistent (and back) storage is called
Serialization, boost contains a great serialization library that should fulfill your needs.
Putting it all together
In practical terms you can now see that your engine class houses a number of variables and objects which makeup the 'state' of the application and game. The engine class also should have various 'controller' functions which serve to modify the game-state, functions such as:
- init: called once during engine init, boots all sub systems and hands control to the scripting system.
- newGame: clears existing game-state and creates a new game-state
- saveGame: commits the current game-state to persistent storage (hard disk)
- loadGame: reads an existing persistent state into a clean game-state restoring the game
- deletes all game objects and returns from the entry point causing the session to terminate.
You should now have a pretty good handle on what to expect from a game-engine, and a general idea of how it should be structured. You learned that a game engine has a foundation object which contains a variety of state information which serves as both input and output via the games processing. Next we will cover input and graphics and how they relate to the game-state.