Featured image: Crysis Expanded Mod
Most people are familiar with the following video game titles: Battlefield, Halo, Doom, Civilization, Call of Duty, Half-Life, the Sims, and Unreal Tournament. Chances are, you may have seen the term “game engine” associated with them, but don’t really know what the term means. Perhaps you know what game engines are and think you have what it takes to write your own? In either case, I will introduce you in this article to the wonders of game engines and attempt to explain their internals as simply as I can. I assume that you, the reader, is familiar with basic programming parlance. If not, you might not understand everything I’ve written here.
A game engine is essentially a software development kit (SDK) that contains the source code and tooling necessary to get a basic video game up and running fast, letting the developer script in the gameplay, levels, and characters, without needing to touch a single line (or at least, much fewer lines) of C/C++ code or know advanced programming.
This allows the game developer to focus more on the gameplay and the “fun factor”, spending less time on complex math and other mundane boilerplate trying to get everything set up. This is analogous to an automobile designer selecting a ready-made engine from a trusted third-party vendor, eliminating the need to build a custom engine from scratch and therefore saving time, money, and effort.
There are plenty of reputable companies that license game engines for profit, and chances are you’ve probably heard of them. Here are some examples of popular commercial 3D game engines:
- CryEngine, created by Crytek GmbH, is a visually stunning game engine powering the long-running Far Cry and Crysis series of games, Ryse, and Warface.
- Frostbite, by EA DICE, is used to power the Battlefield series and several other AAA titles.
- Gamebryo, by Emergent Game Technologies, used in Fallout 3 & New Vegas, Drift City, Epic Mickey, Sid Meier’s Civilization IV, and a few others.
- id Tech, created by id Software, is the oldest family of engines still in common use. First appearing in 1993 with DOOM, variants of id Tech continue to power an obscene number of open source and proprietary games.
- IW Engine, Infinity Ward’s in-house engine distantly derived from id Tech, is found in most of the Call of Duty games.
- Unity 3D, by the eponymous Unity Technologies, is a popular high-quality “freemium” game engine powering numerous indie and mobile games.
- Unreal Engine, created by Epic Games, is one of the most widely-used AAA engines out there today, powering the Mass Effect series, the Gears of War series, Mirror’s Edge, the Unreal Tournament series, and others.
Are there free and open source game engines? Sure! There are plenty out there, and they have great instructional value for budding programmers interested in game engine development. Here are some of the most popular examples:
- Crystal Space is not quite a game engine, but is a versatile rendering engine (see the penultimate section on this page for more on this distinction) that has been used in several games, including the Blender Foundation’s game Yo Frankie!.
- Cube and Cube 2 engines by Wouter van Oortmerssen, powers AssaultCube, Red Eclipse, and a few others.
- Darkplaces, written by “LordHavoc”, is a heavily modified Quake I engine. It powers many GPL’ed games, including Xonotic and the classic Nexuiz.
- Delta3D is a powerful game engine, typically used in military training programs, FPS games, and virtual reality programs.
- Irrlicht, by Nikolaus “niko” Gebhardt, is a speedy engine focused on performance rather than visual effects.
- OGRE 3D, initially written by “Sindbad”, is an impressive open source 3D rendering engine.
- Panda 3D, developed at Carnegie Mellon University, is an “all-purpose” game engine with many features, including in-web browser playing support.
How do they work?
This is a tricky topic to cover, as there is no standard game engine architecture and they all vary widely, but the majority have the following subsystems in common.
This is the core component of any game engine, 3D or 2D, tying together all the subsystems to be discussed below in a neat little user-friendly package. Its job is to abstractly represent the game world and the objects residing within it, making it easy for developers to reason about their game. Usually, the game loop is responsible for updating the state of the world on every tick. Making a save system for your game is typically as simple as snapshotting your world state to disk and having mechanisms in place to read it back in when the user asks to resume from a save file. Some engines use a traditional class hierarchy to represent types of game objects, while the latest trend has shifted to entity-component-system models instead.
Most renderers use some kind of abstract drawing API (e.g. Direct3D and/or OpenGL) to blit 3D or 2D graphics on the screen. They are typically implemented as a class where objects and parameters can be passed to it. It contains a loop that iterates over all the objects in the game world and draws them to the screen. OpenGL users might use libraries such as GLFW, SDL, or SFML to avoid too much boilerplate when building their renderers.
The audio subsystem plays background music and sound effects in-game. If you like open source libraries, OpenAL-Soft or PortAudio are fine choices for helping you write a cross-platform audio system. For decoding audio formats, I recommend integrating Xiph Theora (.ogg for audio) or Xiph Vorbis (.ogv for video) into your game, as both are efficient and royalty-free. Remember to make it easily accessible from the scripting system, if you have one.
Artificial Intelligence (AI)
Every game engine must have some form of artificial intelligence controlling your NPCs (Non-Player Characters) and their spawn points. This is usually accomplished with a third-party or homemade pathfinding library bundled with the engine that can be accessed through the engine’s internal scripting system.
The game engine must recognize the user’s keystrokes, mouse clicks, or joystick movements in order to play the game. If your engine is based on DirectX, you can use the Windows message loop or XInput to accomplish this. If the engine is based upon OpenGL, GLFW, SDL, and SFML already have advanced input support built-in. Otherwise, you must write your own input handler, but note that this may be a little difficult to make yourself and is not very cross-platform.
This subsystem is deeply integrated with the rest of the engine, funneling debugging and error information to a human-readable text file that can be easily examined by developers for diagnostic purposes. The logger should be easily accessible from any engine subsystem, and ideally its API should resemble a standard printf statement, for simplicity’s sake.
logger.print("This is an example message!", OutputType::Info);
Logging must be easy to disable at release time, since it has a negative impact on overall performance.
Nobody likes writing this, but it must be done! This subsystem loads and unloads levels, models, textures, and other game content from the engine in a predictable and controlled manner, often using custom memory allocators. The resource manager also tracks how the resources are being used throughout the program to avoid memory leaks and crashes.
In the past decade and a half, it has become commonplace for games to have some form of multiplayer support. Split-screen style multiplayer is usually done by separating the output window into viewports and drawing independently into each. Networked multiplayer is done by implementing a client/server or peer-to-peer architecture either on your own, or with third-party libraries like HawkNL, to reliably replicate the state of the game world across multiple machines at a distance.
This is one of the most important developer-facing parts of any game engine! The quality and ease-of-use of the scripting system can make or break an engine’s popularity. Most popular game engines either interface with familiar, established scripting languages (Lua, Python, Ruby, etc.) or provide a custom text/flow-based language. The game logic typically can be edited in a text editor, a custom IDE, or through an in-game developer console. Remember to build some form of security in your scripting systems; you wouldn’t want players to hack or cheat, would you?
There should be some kind of graphical user interface subsystem that takes care of in-game menus, dialog boxes, and overlays. As always, you can write this yourself or use a third-party library such as Crazy Eddie’s GUI. Some game engines such as Unity and Unreal couple the UI and rendering systems together so you can have cool-looking floating menus in 3D space. No matter how it’s designed, remember to make your API accessible from the scripting system so that game developers can easily hook up logic to your UI.
Rendering Engines vs. Game Engines
Most people tend to confuse game engines for rendering engines and vice versa. These two types of programs are quite similar in terms of function and purpose, but are fundamentally different from one another.
A rendering engine such as OGRE consists of only a renderer and a minimal resource manager, and is intended to only draw graphics. Rendering engines are usually more general-purpose than full game engines, and rarely include all of the features I described above. While they can be used to make games when coupled with other supporting libraries to fill in the gaps, they can also be used in cases where many of the subsystems mentioned above aren’t needed (e.g. real-time architectural previewers and CAD programs).
A great option is to download a rendering engine and leverage its drawing capabilities within your game engine, saving you time and effort so you don’t have to write a renderer of your own.
If you wish to write your own game engine, be prepared for some very hard work! There is no “right way” to build one, but sticking to the guidelines above and staying organized will get you a long way. Brushing up on your high school trigonometry and matrix algebra will also help you immensely. Fortunately, there are many forums, communities, ebooks, and online tutorials to help you out on your way. Remember, Google is your friend (and Amazon, too).