Choosing open-source libraries for game development

Choosing open-source libraries for game development

June 22, 2025

At the beginning of each project there are a lot of decisions to be made. For example, one of the decisions for Z-Com was to not use an existing game engine like Godot or Unreal. Instead, I want to gain experience with various cross-platform open-source libraries.

A solid choice for cross-platform games is the Simple Directmedia Layer library. Better known as SDL, it offers an abstraction layer on top of many low-level systems a game engine requires from the underlying OS. This includes access to audio, input, graphics, event handling, program entry point etc. Lately, it also offers support for so called “main callbacks” which also greatly simplify handling of the game loop across different platforms.

For the rendering part, I decided to use Vulkan. It is the spiritual successor of OpenGl and comparable to other modern graphics libraries like Microsoft’s Direct3D 12 or Apple’s Metal API. Since all these APIs abstractly represent modern GPU architectures, then I think learning Vulkan will provide me with some transferable skills, should I ever decide to dive into one of the others.

As a GUI solution I’ve chosen DearImGui. This library is a immediate mode GUI and appears to be quite popular among game developers. It also seems to be highly customizable, with a lot of examples available on the internet. Really looking forward to see how this is going to turn out for Z-Com. Immediate mode GUI’s can be quite expensive, but I don’t see Z-Com requiring a lot of heavy GPU or CPU utilization, so it’s probably going to be alright.

Asynchronous I/O operations are provided libuv. This includes file and network I/O. Even though no network features are currently planned for Z-Com, then there is at least a need to load resources from disk. Doing this off the main thread is the only sane approach to deliver a smooth UI experience, and this is what libuv does.

Since performance is critical, I’ve decided to integrate the Tracy profiler right from the start. It is a hybrid-profiler that can do both sampling and instrumented profiling, and gives inside into not just the CPU profile, but also GPU, memory, and locks.

Also, I consider using spdlog for logging at the moment, even though SDL does come with some logging functionality as well. My motivation here is that spdlog has a lot of built-in features to control the log output, which is something I’d otherwise have to write on top of SDL. Now I just need to bridge the SDL emitted logs into spdlog, which seems relatively straight forward.

To ease usage of those libraries, all but two are installed through the vcpkg package manager. The libraries that need to be acquired manually are Vulkan and Tracy. In both cases they do not built with the LLVM provided clang compiler at the time of this blog post. CMake offers various ways in which the locations of those libraries can be made known to the build. For Vulkan, this can be done with the VULKAN_SDK environment variable, for Tracy one can use CMake’s <PackangeName>_DIR-style environment variable, e.g. Tracy_DIR.