How DOOM was programmed

Chris Cable
6 min readApr 11, 2019

--

GOAT FPS

Doom is a famous FPS (First Person Shooter) that first came out in December 1993. In spite of this game being a few years shy of thirty years old it’s still one of my favorite games to play. I think part of what makes Doom a fun game is the simplicity of the gameplay as well as the general theme of the game itself. In this regards I really feel like they don’t make games like they used to, newer is not always better. That being said, as a software engineering in training I felt like it would be an interesting exercise to examine some of the code from an old favorite of mine since I now have the ability to analyze and better understand the code.

Brief History of Doom

Doom was developed using the same engine as its famous predecessor Wolfenstein 3D. Wolfenstein 3D was also a game produced by ID software and it came out just a year before Doom was released in May 1992.

Although Doom used the same general game engine as Wolfenstein 3D, it utilized an improved graphics engine that was developed by lead programmer John Carmack (Development of Doom).

With significant effort, choosing to isolate himself from the rest of the team for a long period of time in order to avoid distractions, he implemented various new features, including varying light levels and texture-mapped floors and ceilings.

The difference in the quality of graphics is pretty clear. I think that in terms of the user experience, I always found Wolfenstein 3D to be pretty boring and monotonous overall. Meanwhile I always found Doom to be much more entertaining to play as a result of the more diverse and dynamic backgrounds that were enabled by the improved graphics engine.

Wolfenstein 3D
Doom

Besides the graphic engine, the game itself was developed on something called a NeXT workstation using the proprietary NeXTSTEP operating system. I wasn’t actually familiar with what this was at first so I had to look it up, but it basically appears to have been a computer system that was created by the computer and software company NeXT that was founded by Steve Jobs himself in 1985 (In case you’re wondering, NeXT was an independent company that Steve Jobs founded after he was ousted from Apple, however the company as well as Steve Jobs ended up returning to Apple as a result of an acquisition deal in 1997). (A Short History of NeXT)

The NeXT workstation

As for the programming language used to code Doom, the primary language used was C. It’s interesting to note that typically many games are programmed using C++, however the reason that C was used to program Doom is simply because Doom is such an old game. In 1993 when Doom was being developed, C was the primary language that was being used for video game development at the time. While C++ was available it wasn’t yet as heavily entrenched as it is now and as a result C was naturally seen as the older, more reliable choice.

Examination of some of the code from Doom

Admittedly, playing Doom itself is more entertaining than analyzing the code for it; although I’m sure that programming Doom itself must have been a ton of fun to do too though. In the following paragraphs I will present a snippet of code from Doom and explain how it works:

IDDQD — Invulnerability

IDKFA — Full health, ammo, weapons, armor and keys

IDFA — Full health, ammo, weapons, and armor

IDCLEVxx — Warp to level ‘xx’ where xx is 01 to 19

IDCLIP — Walk through walls

Ok, just kidding, the above are CHEAT codes, but I was actually referring to programming code of course. Below I have included a snippet of the code used to implement the firing of the shotgun weapon in Doom as a well as a GIF image demonstrating the execution of the code itself:

The shotgun

void C_DECL A_FireShotgun(player_t *player, pspdef_t * psp)
{
int i;
S_StartSound(sfx_shotgn, player->plr->mo);
P_SetMobjState(player->plr->mo, S_PLAY_ATK2);
//player->ammo[weaponinfo[player->readyweapon].ammo] — ;
P_ShotAmmo(player);
P_SetPsprite(player, ps_flash, weaponinfo[player->readyweapon].flashstate);
player->update |= PSF_AMMO;
if(IS_CLIENT)
return;
P_BulletSlope(player->plr->mo);
for(i = 0; i < 7; i++)
P_GunShot(player->plr->mo, false);
} (ID software Github)

As someone who is thoroughly unfamiliar with C, the above snippet of code appears extremely foreign, although the basic functionality of the code itself (syntax aside) is more or less obvious. The “simple” act of firing the shotgun in the game is unsurprisingly executed by a couple of different methods that are wrapped into a single function eloquently named:

void C_DECL A_FireShotgun(player_t *player, pspdef_t * psp)

Within the function itself there are individual lines of code to execute the following four things:

1. The sound effect the shotgun makes when it’s fired

S_StartSound(sfx_shotgn, player->plr->mo);

2. The ability for the ammo counter to decrement each time the shotgun is fired (In the GIF the ammo column is in the panel at the bottom to the far left, conveniently labeled “ammo”)

//player->ammo[weaponinfo[player->readyweapon].ammo] — ;
P_ShotAmmo(player);

3. The sprite for the firing of the shotgun itself

P_SetPsprite(player, ps_flash, weaponinfo[player->readyweapon].flashstate);

4. Dictating the trajectory and damage of the action of firing the shotgun

P_BulletSlope(player->plr->mo);
for(i = 0; i < 7; i++)
P_GunShot(player->plr->mo, false);

The end result of all this code?

Pretty neat huh?

Conclusion

In spite of its old age, Doom is a game that has aged remarkably well. Moreover, I think it’s quite interesting to have finally taken a look at the internal mechanics of a game that I have been playing on and off for the majority of my life. I think it would be a lot of fun to program a game like Doom, although it would certainly require a lot of experience to do so. Even though Doom is an “old” game, this doesn’t mean that it was necessarily “easy” to program, maybe only easy in a relative sense compared to games that are programmed these days, but the code for Doom itself, in absolute terms seems relatively complex, even when not taking into account my sparse knowledge of C++ let alone C.

In closing, if you came of age long after Doom’s heyday then I strongly recommend you try it out if you enjoy first person shooters. Just remember one thing though: before Call of Duty, before Halo, before even Goldeneye, there was only DOOM.

Sources

A Short History of NeXT, simson.net/ref/NeXT/aboutnext.htm.

“Development of Doom.” Doom Wiki, doom.fandom.com/wiki/Development_of_Doom.

id-Software. “Id-Software/DOOM.” GitHub, 1 Feb. 2012, github.com/id-Software/DOOM.

--

--