Over the last few weeks, I have been working with open-source game engines to understand how they work. In the long term, my objective is to identify similarities and differences in the architecture of different engines and verify if these can be improved in some way. I will do so by running a dynamic analysis tool called Callgrind, which allows me to see when and in which order the engine methods are called when running a game.
My first stop to search for open-source engines was GitHub. While there is no lack of projects of this kind, many of them are no longer maintained. From an initial list of 16 engines I selected, eight no longer receive frequent updates. Even Cryengine, which is quite well-known in the industry, has not received any updates to its open-source codebase since 2016 (the proprietary version, however, is still actively maintained).
I tried to compile and run seven out of the 16 engines from my list on Ubuntu 20.04.4 LTS. I followed the steps provided by developers on README files and documentation and managed to do the entire process successfully with four engines: Godot, Pilot, Unreal Engine 4 and Urho3d. In the case of Godot and Unreal, the well-written documentation was the main reason why the process was easier. As for the others, most are only sparsely documented.
Before we dive into the issues with each engine, I believe it is important to say that my compilation scenario was a bit different from what a regular game developer would usually do. I did not only want to compile these engines in regular “release” mode but also in “debug” mode. Since my objective is to analyze the architecture of the engines, I need to compile with the debug symbols (e.g. names of classes and methods). Otherwise, even though Callgrind would provide me a call tree with all methods called by the engine, I wouldn’t have their names and therefore no reference of what they do.
Now that you have a brief context of what I’m doing, let me show you what problems I encountered while trying to compile each engine, and how I solved - or tried to solve - them:
Part 1 - The successful compilations
Godot Engine v3.4 [source]
You can find everything you need to know about the compilation process on a single page of the documentation, which is great! However, the procedure you need to do to run the game in debug mode is a bit different in Godot compared to other engines. Instead of compiling the entire engine (including the editor) in debug mode, you can use the build tools provided by Godot to create an "export template", which is a binary file containing the "core" of the engine, compiled in either release or debug mode. When you want to generate an executable for your game, you have to manually "link" these binaries to your project via the editor's GUI.
Pilot Engine v0.0.5 [source]
This is a “toy” engine, created for a game development course provided by the Chinese company BoomingTech. The documentation is written entirely in Chinese, and while they describe the inner-working of the engine, there is no information about the build process. However, they provide a script (build_linux.sh) that is supposed to do everything that is needed. However, when I ran it, it just suddenly finished the compilation with the message “Error 2” and the mention that some source files were not found. After a couple of hours of reading error logs and testing different approaches I discovered that:
- I had the wrong version of clang: Pilot Engine requires 3.19 or higher. I then installed the latest one (3.23.2).
- One of the folders on the path to my local repo had a space in its name, which for some reason messed up the cmake scripts. Renaming the folder solved the problem.
Unreal Engine 4 [source]
UE4’s documentation is fantastic, showing everything step-by-step with screenshots. The compilation scripts provided in the repo download most of the dependencies they will need, so you don’t have to worry about installing anything besides clang (which you may have installed already if you compile projects from the source often).
The only downside: if you want to compile and run Unreal, you must have reasonably good hardware: a quad-core 2.5GHz processor, 32GB RAM, and at least 100GB available on your disk are recommended in the docs. If your setup does not match this description, be prepared to wait some hours. In my Intel i5 2.5Ghz, 8GB RAM laptop reading the files from an external USB 3.0 HDD, the engine took around 8h to compile.
Urho3d v1.8 [source]
For this engine, you run cmake to generate a build tree and makefile for different IDEs (such as Visual Studio and Codeblocks). First I tried the more “user-friendly” approach and compiled it with Codeblocks. While it worked for the release mode, it didn’t for debugging (Codeblocks simply shows the message “cannot debug target).
Since it didn’t work, I tried what the Urho3d docs call a “generic” build, which is supposed to work straight from the CLI, with no need for a specific IDE. For this case though, the docs don’t provide any explanation on what should you do to compile in debug mode. Should I pass a parameter in the command line? Should I change the script? After a lot of trial and error, I eventually discovered there is a CMakeCache.txt inside the folder where the build tree was generated. Inside this file, you can set CMAKE_BUILD_TYPE:STRING=Debug.
Part 2 - The unsuccessful compilations
GamePlay3d v3.0 [source]
Both for release and debug, I get a compilation error for several files with the message: “relocation R_X86_64_32S against `.rodata.str1.1' can not be used when making a PIE object; recompile with -fPIE”. I searched this message on the web and couldn’t find many references as to where should I pass this “-fPIE” parameter. All I found was SO answer saying that the g++ compiler has a “no-pie” flag, which should be enough to prevent the program to be compiled as a position-independent executable (PIE). So I edited CMakeLists.txt to include it:
set(CMAKE_C_COMPILER_INIT g++)
add_compile_options(-no-pie)
However, the error persisted. I believe it will be hard to find any information on how to fix this one since GamePlay3d is not maintained since 2016.
FlaxEngine v1.3.6228 [source]
Both for release and debug, I get an error on the “Platforms/Android/AndroidNdk.cs” file: “CS0136: A local variable named `v' cannot be declared in this scope because it would give a different meaning to `v', which is already used in a `child' scope to denote something else”. While I found a description of the error in the official .NET documentation and tried to fix it directly in the code by declaring the variable in a different scope, the error persisted. This engine is still being actively maintained, I may try to open an issue on Github in the future.
Lumix Engine v2.0 [source]
For this engine, I can compile and run the editor, but it is unresponsive. The window where the 3D world editor should appear keeps blinking, but most of the time it only shows the message "press W to move" (image above). The log window mentions a deprecated library, but I found no information on what it does or how to update it. Lumix is also actively maintained, so I may try to contact the community in the future (even though it doesn’t appear to be very active).
Conclusion
Compiling game engines from source may be a challenge, especially when the process is sparsely documented and no longer maintained. Additionally, in my case, there was another factor at play: experience. I don't have an extensive background working with build tools, so I made mistakes and also learned a lot from them along the way.
This made me think about the importance of creating good documentation and build processes. It does not only make the life of the seasoned developers easier but also keeps the doors open for newcomers to explore, understand, and possibly contribute to these open-source engines. While many don't seem to find this a priority, Godot and Unreal show that creating a user-friendly and straightforward build process is possible.