informa
/
3 MIN READ
Featured Blog

Long build times? You're doing it wrong.

If your game takes a long time to build, you are simply doing it wrong. You've most likely created a big ball of mud. The remedy is simple: don't include header files in header files.

When I hear developers complain about long build times, it immediately makes me suspicious about the quality of their code base. They have simply built a big ball of mud, a.k.a. spaghetti code. What has happened is that the compiler gets bogged down by an avalanche of include files. Don't fight the symptom by using precompiled headers! Instead, fix the root cause: the crappy architecture of your game. What follows in this article, is a recipe for a clean code base that builds in a couple of seconds, not minutes.

Here's the TL;DR version of this article: do not include header files in header files. The dependencies that foo.cpp uses to implement its functionality should never leak into the foo.h interface. I'll state up front that a C-like programming style lends itself better for this than a C++ programming style. But even when using C++ classes, it is often possible to avoid include directives.

If the interface of class Foo only contains uses of class Bar that are references or pointers, then the compiler does not need to know what Bar looks like when parsing the header for Foo. All that is required is that Bar is forward declared for the Foo interface. You tell the compiler that there is a class named Bar, and leave it at that. Typically, there will be some classes in your game that need to include large third party frameworks. It is paramount that these frameworks do not leak into the users of class Bar, like class Foo.

If you constantly ask yourself: "How can I keep the implementation details out of the interface?" then you can cut down on the include directives. Also preferring primitive types char/int/float/bool and pointers over custom object types is a great strategy for pruning include hierarchies.

So where can this get you? To illustrate this, I will examine the code base of the game I am currently creating. The only uses of middleware are OpenAL and OpenDE. It is a fully featured game with biplanes, AI, formation flying, dogfighting, explosions, menus, tutorials, whathaveyou, totaling roughly 50K lines of code. But building from scratch (including linking) takes less than three seconds.

real    0m2.687s
user    0m5.076s
sys     0m0.542s

This is because the include hierarchies are extremely flat. For instance, here is what gets pulled in to implement the logical representation of my game world.

And here is what the code that uses the game world sees when it includes wld.h:

In my code, dependencies are hidden, and almost never propagated throughout the system. The notable exceptions are the leaking of my vector math header and my rendering context data into the interface. The latter includes no further files, and the former only three system headers.

The world contains terrain, planes, bullets, hangars, explosions and much more. But the code that uses (creates, destroys, renders) this world should not be bothered by these details.

Personally I think that distributed build systems, build caches, precompiled headers are all curses disguised as blessings. These mechanisms that make your build go faster, allow you to ignore the root problem for longer. The mud ball grows and grows, and when you are finally fed up with long build times, the tangled mess may be beyond repair. Top tip: disable precompiled headers!

Let me conclude with a tip on how to inspect the sanitation conditions in your code. Snowballing include directives are brutally exposed with the 'Doxygen' tool if you tell it to generate include graphs with graphviz's dot program. Use the following directives in your Doxygen configuration file:

DIRECTORY_GRAPH = YES
INCLUDE_GRAPH = YES
HAVE_DOT = YES

If the Doxygen output includes huge dependency graphs, you know that you are on the wrong path. Also, cycles in the graph with lower level files pointing back to higher level files are a huge red flag.

I'm curious to know how my peers view this issue. Also, what is the longest build time that you have encountered? Drop your remarks in the comments, they are highly appreciated!

Latest Jobs

IO Interactive

Hybrid (Malmö, Sweden)
3.02.23
Gameplay Director (Project Fantasy)

Arizona State University

Los Angeles, CA, USA
2.27.23
Assistant Professor of XR Technologies

IO Interactive

Hybrid (Copenhagen, Denmark)
3.02.23
Animation Tech Programmer

Purdue University

West Lafayette, IN, USA
3.02.23
Assistant Professor in Game Design and Development
More Jobs   

CONNECT WITH US

Explore the
Advertise with
Follow us

Game Developer Job Board

Game Developer

@gamedevdotcom

Explore the

Game Developer Job Board

Browse open positions across the game industry or recruit new talent for your studio

Browse
Advertise with

Game Developer

Engage game professionals and drive sales using an array of Game Developer media solutions to meet your objectives.

Learn More
Follow us

@gamedevdotcom

Follow us @gamedevdotcom to stay up-to-date with the latest news & insider information about events & more