Have you already seen a basketball or a soccer player plays a simple yet effective game to such a point that you say: Why couldn’t everybody play like him, he uses only easy techniques?
And as C++ programmer I had the same remark when exploring the John Carmack source code. It’s so simple, we wonder why we can ‘t develop like him.
Let’s explore some Doom3 source code choices and try to understand why the code even if it’s simple, it’s very efficient.
On November 23, 2011 id Software maintained the tradition and it released the source code of their previous engine. This source code was reviewed by many developers, here’s as an example of Doom3 feedback from fabien (orginal source):
Doom 3 BFG is written in C++, a language so vast that it can be used to generate great code but also abominations that will make your eyes bleed. Fortunately, id Software settled for a C++ subset close to “C with Classes” which flows down the brain with little resistance:
- No exceptions.
- No References (use pointers).
- Minimal usage of templates.
- Const everywhere.
- Classes.
- Polymorphism.
- Inheritance.
To resume only a subset of the c++98 standard is used. And Here are some design choices of Doom3:
1 – Provides a common base class with useful services.
Many classes inherit from the idClass:
The idClass provides the following services:
- Instance creation.
- Type info management.
- Event management.
2- Make easy the string manipulation
Generally, the string is the most used type in a project, many treatments are done using them, and we need functions to manipulate them.
Doom3 defines the idstr class which contains almost all useful methods to manipulate strings, no need to define your own method as the case of many string classes provided by other frameworks.
3- The source code is highly decoupled from the GUI framework (MFC)
In many projects using MFC, the code is highly coupled with their types, and you can find types from MFC everywhere in the code.
In Doom3, The code is highly decoupled with MFC, only GUI classes have a direct dependency on it. As shown by this following CQLinq query:
This choice has a big impact on the productivity. Indeed, only the Gui developers must care about the MFC framework, and for the other developers, it’s not mandatory to waste time with MFC.
[adrotate banner=”3″]
4- It provides a very good utility library (idlib)
In almost all projects the most used types are utility classes, as shown by the result of this following query:
As we can observe the most used are utility ones. If C++ developers don’t use a good framework for utilities, they spend most of their development time to fight with the technical layer.
idlib provides useful classes with all needed methods to treat string, containers, and memory. Which facilitate the work of developers and let them focus more on the game logic.
5- The implementation is very easy to understand
Doom3 implements a hardcoded compiler, and as known by C++ developers, it’s not an easy task to develop parsers and compilers. However, the implementation of the Doom3 is very easy to understand and its code is very clean.
Here’s the dependency graph of the classes used by the compiler:
And here’s a code snippet from the compiler source code:
We already study the source code of many parsers and compilers. But it’s the first time we discover a compiler with a source code very easy to be understood, it’s the same for the whole Doom3 source code. It’s magic. When we explore the Doom3 source code, we can’t say: WOW it’s beautiful!
To resume the Doom3 source code is very clean, easy to understand and maintain and use only a subset of the standard. No advanced techniques were used and it respects a basic best practices of designing, naming and formatting the code.
We can say that the John Carmack secret was the KISS principle as defined in wikipedia:
KISS is an acronym for "Keep it simple, stupid" as a design principle noted by the U.S. Navy in 1960.[1][2] The KISS principle states that most systems work best if they are kept simple rather than made complicated; therefore simplicity should be a key goal in design and unnecessary complexity should be avoided. The phrase has been associated with aircraft engineer Kelly Johnson (1910–1990).[3] The term "KISS principle" was in popular use by 1970.[4] Variations on the phrase include: "Keep it simple, silly", "keep it short and simple", "keep it simple and straightforward",[5] "keep it small and simple" and "keep it stupid, simple".[6]
What’s interesting about this definition is the following assertion:
The KISS principle states that most systems work best if they are kept simple rather than made complicated.
What lessons to learn when adopting the new C++ standards?
The new standards introduced many new interesting features. Think that using all these features will make your code very efficient it’s a bad idea. many new features are more useful to develop the generic libraries especially all the features related to the generic programming.
Don’t force yourself to use all the new features, use a feature only if it’s absolutely needed and contribute to making your code more efficient.For example, this interesting post talks about the drawbacks of the overuse of the auto keyword.
[adrotate banner=”3″]