First, let us ask ourselves, what is a game engine? It originally solely referred to a library/software whose sole purpose was to handle all internal of the game in the background. However, lately, the game engine has become synonymous with more than just games. Today, the game engine can be used more than just games. For instance, We have seen that the Unreal game engine is being used for creating movies like the Star Wars Series Mandalorian. Where they create realistic interactive environments as the background instead of a green screen.
Aside from what game engines are being used today. A game engine can be seen as something similar to an operating system/kernel or an engine of a car. It provides resources, It is the part that is running the game itself and everything behind the scene, similar to what drives the car, the engine, and its components. You don’t have to think about the gas/oil intake of a car engine when driving nor in a computer context when the computer operating handles what process to run at current movement on a CPU core.
Today, there exist many various game engines, all from small to triple AAA. In addition, general-purpose and specific purpose games. Some of the known general-purpose game engines are Unity 3D, Unreal, Godot and etc to name just a few. On the other hand, all the other specific purpose games don’t get named as often since they often tied a smaller set of games and specific genres.
Before continue with how to start creating a game engine, let us simply give a quick oversight of what a game engine can be responsible for in more specific terms. It will handle the loading of assets into textures, geometry, shaders and etc. It will handle the rendering pipeline of what object should be rendered and where with what textures shaders. Furthermore, it what order these objects shall be rendered in order to create correct visual. Updating object transformation relationship, that is to say, if the character’s upper arm moves forwards, then the forearm along with the hand will move along it and etc.
Why Bother Creating a Game Engine
So why should we bother with writing our own game engine when so many engines already exist that have many more great features, great UI for adding modifying the game asset directly in the editor, built-in features, and much more? Simply, because creating game engines are not only fun and rewarding. It provides a great number of different fun challenges. Furthermore, it contains many sub-fields topics in computer science and other fields. Thus, it will help our own knowledge in many areas that were perhaps not initially thought would be associated with game engines. But is discovered as one starts digging deeper into how the engine works.
To give some examples of subfields that game engine development is associated with. Mathematical topics such as Linear Algebra; Calculus whereas in computer science some of the following topics very likely to be needed: Data Structure, Sorting Algorithm, Architecture Design, Signal Processing, Image Processing, Color Theory, Ray Tracing, Hardware, Assembly Instruction, Software Design, Software Development processes, Network, Programming. Multi-threading with concurrent processing, physic, light theory, machine learning, and many more. Many of the example sub-fields mentions are common among all game engines, from small to triple AAA game engines.
In addition to the specific topics, there are additional topics that are more associated with the development process rather than what the engine contains, such as Continuous Integration, Continuous Deployment (CI/CD), debugging, and analysis techniques. Programming optimization and much more.
Hardware and Platforms Compatibility
Many platforms such as PC, Playstation, Xbox, Nintendo, and etc can all be running different hardware. However, many of the platforms run similar compatible sub-component hardware such as X86, ARM CPU unit and etc. Thus, the most common challenge for programmers is dealing with CPU architecture for building it for multiple platforms. In addition, there are some hardware-specific features that developers might have to handle, for instance, when NVIDIA Ray Tracing was originally released. Only NVIDIA card could run it. Fortunately, now more graphic devices are starting to support it.
Thus it should be remembered that the hardware-specific feature used will create a restriction on what platforms the game-engine/application will be able to run on.
What many game engine has in common is that they are using the graphic in some form of way. Commonly these are either 2D or 3D graphics. There are some exceptions, such as the command prompt like in the old days. Thus, learning a rendering API that can handle either or both 2D and 3D is recommended as the first goal. Most of the computer graphic uses a rasterized renderer that commonly hardware accelerated. This is where 3D geometry is projected onto a 2D screen.
A low-level rendering API does not simply take a 3D model and render it like when working in a 3D application such as Blender, Maya and etc. No, you, as the developer will have to handle the loading of the file, parse it, extract the data, and reorganize it so that the rendering API can understand it. In addition, loading the texture data in a texture format that the rendering API can handle internally, pass additional information about the texture. Then create shaders for processing the multiple rendering stages. Setup the rendering commands for passing all the information for finally issue a rendering call. So there is a couple of things that are required before having rendered something onto the screen.
So what rendering API should you choose and what are some of the options. OpenGL, DirectX, and Vulkan are the most common low rendering API for rasterization, Compute, and today Ray-Tracing and most graphic operation for game engines. These are the most common rendering APIs on desktop and mobile phones. There is a couple of other rendering API. However, for very specific platforms such as Metal for MacOsX and many others. However, if you know one common low-level rendering API, then any other rendering API will be relatively easy to understand. Mainly because they share a lot of similarities with each other.
Vulkan and OpenGL are recommended, simply because of their cross-platform capabilities instead of DirectX. Because it is being a closed software to Microsoft’s operating system only. However, Windows has a big market, since it is installed on many more devices than for instance Linux/macOS. But, for beginners, OpenGL and DirectX are recommended. Vulkan does the same thing as OpenGL, but comes with a much more modern design and have much more control. It has the same kind of basic features, but it can control, such as rendering pipeline, command buffer, synchronization, and much more. OpenGL and some DirectX versions handle many of these low-level control in the drivers. Though it is can be much harder getting started with Vulkan but it can yield much higher performance and control if used correctly. Partially because the driver doesn’t have to make a prediction on how the application will be run.
If you are a beginner in graphic programming, it is recommended that you simply start writing code instantly, and simultaneously continue reading and follow along a bunch of tutorials on various rendering techniques. The design and architecture of a game engine and etc can wait in till you have a good understanding of game engines. Since it requires that you have a good understanding of how rendering works and among other game engine related topics.
Start Writing Computer Graphic Code
Before we can start writing the code using any of the low-level rendering APIs methods in the previous sections. It will need a window and its corresponding events to handle things such as resize, close, focus and etc. Furthermore, it would quite useful if getting access to user input easily accessed. Fortunately, there are many preexisting libraries that can handle the system level management of input, window, network, display and etc. See the window library section for suggested libraries.
These are various good online resources, all from step by step tutorials to various articles on rendering techniques. In addition, there are many more other great resources that can be discovered online.
There are many books that cover topics in great detail about rendering with all the common rendering APIs. As well as more specific rendering techniques such as Light, Shadow, Ray Tracing, and the math commonly used in-game engines.
- OpenGL Superible –
- Real-Time Shadows – A dedicated book about various type of shadow technique.
- OpenGL Insights – Many great article for adding rendering features and optimization techniques.
- Ray Tracing from the Ground Up – A comprehensive resource of how to create ray tracing pipeline.
Computer graphic is based on several mathematical models, such as Linear algebra, Calculus, Probability and statistics.
- Mathematics for 3D Game Programming and Computer Graphics
- 3D Math Primer for Graphics and Game Development
Window Management Libraries
The following list is a couple of cross-platform libraries to handle many of the common low-level functionalities associated with game development. One recommendation would be the SDL2 library since it has cross platforms and is used in for instance valve games and works great. Furthermore, it has built-in functions for creating and handle OpenGL platform-specific. Of course, it should be chosen based on that it has the best functionality and etc that are required for the engine.
Graphic Library Wrapper
It is possible to create your own math libraries and educational. However, it is easier to get started using existing so that one can focus on graphics programming.
- glm – A declarative math library that allows for compilation optimization.
- Eigen –
- Hpm – A small 3D math library, but is not as good as glm.
- OpenAL – A open-source audio library. It follows a similar coding convention as OpenGL.
- FMOD – A audio library used by many game engines and provides.
FreeImage – A library for loading must common image formats from both via file IO and Memory.
FreeType – A library for loading fonts.
What type of Game Engine Should you make
When developing a game engine, it is very important that the requirements are established in what it shall and shall not do. This is mainly because of the reason that individual components/features of a game engine are relatively straightforward. However, when combining it with many other features together does it becomes very challenging. Especially, if the game engine is not designed to be flexible with, for instance, handle interfaces like plugin, modules and etc for making expandable for new features. Furthermore, every additional requirement increases the complexity with consequently will increase the development time and cost. Let us take a look at two types of game-engines in the following sections.
General Purpose Engine
Unreal and Unity are two among many popular big commercial game engines. Used by many, all from hobbyist, indie developer, and all too big game titles,. For instance, Star Wars Fallen Order was created with Unreal 4. But what these two game engines have in particular in common is that they are relatively a general-purpose engine. Meaning, that can handle most game concepts and genres. This put a big challenge on the design process and on the creation of the engine. Because it must handle rapid changes, external interfaces such as plugins within the game engine system to have the option to handle additional features and much more. All the while maintaining a high level of performance.
Specific Purpose Engine
Designing an engine for a specific game/application is much easier, faster, cheaper, and easier to optimize. Because the workload is predictable. The rendering pipeline can, for instance, be optimized to handle for instance, in an RTS game, multiple entities at the same time, since the rendering pipeline can much quicker decision on what level of details in geometry, what materials and texture to use, what lights should be used and etc. Furthermore, it can be optimized based on the game-specific by add and remove features that are only needed for that game/application. For instance, having plugin support and etc.
This can allow for less level of abstraction and thus consequently less overhead. Furthermore, it can for instance using different programming paradigm from the ground up. For instance, using more of a DOP (Data orientated programming) design over OOP (object-oriented programming) from the engine layer to the game layer. Because the DOP design can use the hardware resources much more efficiently than OOP in general because of several reasons, one being the hardware caching feature and etc.
Create a Game Engine for Your Next Game/Application
When having a game or application in mind that you could create a game engine with. If this the first game engine, Then start with something relatively simple game that the engine should handle. But create it for fitting some specific application. That is to say, a specific purpose engine since that is much possible to create as a solo developer or a small group. But when deciding what the engine should have based on the game title, you should try to be time realistic, since programmers are known for being time optimize. So if you think it will take a week then it will most likely take more than a week and so forth.
When having done some research and having a good grasp of some fundamentals such as window, graphic, math, and idea of how game engines work and are created. then it should be possible to start designing the game engine for your application.
I will in future blog go through more in details on various possible design approaches and examples. Including various design patterns.
There is still much information left about game engine creation that can be discovered. Here are some additional resources.
Book: Game Engine Architecture – Great overall insight of a game engine is designed and all of its design layers
A great huge list of C++ libraries that will most likely be useful for your next application for must type of application at GitHub.
Free/Open software developer, Linux user, Graphic C/C++ software developer, network & hardware enthusiast.