Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

Studying Doom's source code - where to start?

Recommended Posts

For months I've wanted to study Doom's source code, I want to understand how everything comes together, learning from it, but I don't know where to start?

I mean, got this link: https://github.com/id-Software/DOOM/tree/master/linuxdoom-1.10

But should I start with d_main.c? or doomdef.c? perhaps it is actually i_system.c?


Note that I've coded before, mainly C#, Java, a little bit of php, also toyed witch ACS before, so I'm not really that new to programming. 

However, when it comes to studying an entire program/game engine and C, I'm totally a newbie.

So I was wondering how the people here who know a ton of stuff about Doom's source code did it.


Share this post

Link to post
2 hours ago, mIMAS said:

So I was wondering how the people here who know a ton of stuff about Doom's source code did it.

i can answer to this. for me, it was like "oh, i want this sourceport to do that thing... let's find where is the code for it..." (weeks later) "ah, fuck it, this mess is incomprehensible!"


but seriously speaking, the best way to know Doom source code (and prolly to waste your life) is to start your own sourceport. then you will have to learn the code hard way.

Share this post

Link to post

I very much recommend the black book. It's got some mistakes here and there, but there's nothing that will trip you up too severely (thankfully there's an errata sheet and fabien's updated it at least once so far (btw, to anyone who owns it on Google Books, it is updated there, surprisingly!))


If you are interested in "unrolling" the whole game, d_main.c is where you will start, it's where D_DoomMain lives. g_game.c is where tics are actually run. the i_ files are interesting, as they're (supposed to, at least, the linux doom "sound server" was implemented in a somewhat intrusive manner) where all the system specific code is placed. The included i_ files are for Linux, but you can get a feel for what the dos ones are like from the heretic and hexen code.


In case it's even remotely helpful (after writing all of this I started to question it...), here's a quick look at the namespaces, as I understand them:

  • d_: overall things related to all parts of the game. Where D_DoomMain lives.
  • f_: finale, related to showing the text screens, the doom 2 cast call, and the screen wipe effect.
  • g_: game, handles running the game logic. Handles starting, progressing through, running, and the like with the game.
  • hu_: hud, handles the text line at the top of the screen and a few other things.
  • i_: things that are platform dependent.
  • m_: the source calls this the "main menu loop", but it also contains other misc functions.
  • p_: the playsim. Where all the logic making the maps do their things, all map objects do their things, player specific code, and so on.
  • r_: renderer. Elegant but it'll take a bit to understand. This is the one place where I feel the Game Engine Black Book can fall a little short in a few places, it gives a good feel for the overall picture but I think there's some really neat things that are lost in Fab's work. It explains perspective correct texture mapping in overall terms, but doesn't explain how Doom does it (which I believe doesn't require divides?). Do give it a good read though, it gives the overall picture of how the BSP tree is created and iterated, how lines are projected, how visplanes are created and merged, how lines are clipped, how sprites and lines with see-through bits are rendered, and many other things.
  • s_: sound. How sounds and music are emitted. the released Linux Doom source did a lot of changes to this...
  • st_: status bar.
  • v_: video. Handles the creation of the game's multiple framebuffers, handling the "dirty box" (region of screen to update), and basic drawing tasks. GEBB will give a good feel for why there are multiple framebuffers. Is this referring to the shotgun wrap bug in Final Doom?
  • w_: wadfiles. dunno what to say about this...
  • wi_: world maps and intermission. It's the intermission code.
  • z_: zone memory allocator. Why a custom memory allocator? Some of it is a legacy of id's 16 bit games, but it carries some useful functions and can help reduce memory fragmentation. Also allows for caching WAD assets.

Share this post

Link to post

Think of a simple change you could make (something like adding a new line type variant or tweaking a monsters behaviour) and then as a learning exercise try implementing them. You'll only need to touch a tiny fraction of the source for  each such mod, so you can learn one subsystem at a time. 

Share this post

Link to post
10 hours ago, ketmar said:

i can answer to this. for me, it was like "oh, i want this sourceport to do that thing... let's find where is the code for it..." (weeks later) "ah, fuck it, this mess is incomprehensible!",


Pretty much this. Doom's code is a library of "how not to do stuff" and it's a miracle that it worked out.

It took me several years to get a good understanding of the core logic.

The best approach would be to try something out on isolated features. For example, try to analyze how a monster or projectile moves and what functions get called while performing the movement. Once you start getting an understanding, the rest of the code will be easier to follow. But be aware what code base you choose as a start. I'd recommend something as basic as possible you can set up to compile.



Share this post

Link to post

I'm not sure what your programming background is, but it probably would be helpful to learn about memory allocation/management in C, as well. 

Share this post

Link to post

Wow, so many good responses.

Thank you all, I'll definitely check out the Black Book, I quickly read through chapters 1 to 4 and I learnt so much about old hardware and the limitations they had to work with. I'll also check the code for sourceports once I think I'm prepared to get deep into them (noticed some had C and others C++ files).


I'm both excited and terrified, I really don't mind how much time it will tke to figure out how things work, but I've wanted to study Doom's code since I started playing it.

Thank you all!

Share this post

Link to post

A lot of people are suggesting to jump in and start making changes. I have to totally agree. Here's my step-by-step:


1. Find a source port that easily compiles to a playable executable. If you're learning Doom from scratch, you don't want to be messing with trying to get it to compile.

2. Take a look at info.c and info.h. (Many source ports change these, so you may need to look via the Linux original source). These files are the heart of all thing animation, monster stats, and monster actions and sounds. These files define code pointers for monster line-of-sight, movement, attacks, etc. You can follow those pointers deep into p_inter.c and p_enemy.c, and each of those will send you further into the engine. DeHacked frame changes edit these info.c/info.h tables in the executable.

3. Temporarily change some info.c stats, compile, and see their effect. It's important, I think, to understand this relationship first.

4. Follow some info.c code pointers into p_enemy.c. Take some code from 1 monster's attack function, and dump it into another, and see the effects. p_inter.c is also good for some of this random "cause and effect" hacking.

5. Restore the original code to remove the above hacks. Then start imagining a *simple* feature that you want to add to the game. Maybe add a new monster with a special attack, or a new weapon. This will leverage the knowledge you gained from the above hacks.


I can't go further without knowing exactly what you want to accomplish. I assume you're wanting to make a source port, or possibly a new game. Or, maybe you want to write a book?? Simple curiosity?


I might then recommend tackling the renderer. Doom's renderer is a bit tricky, as a result of various optimizations.


One step I forgot to write above: Compare the various source ports to see how other programmers accomplish enhancements. This may be the most important study yet. Often, there are some nice, verbose comments explaining why changes were made. Also often, the programmers will include readme.txt files, where they've captured change logs.


If you are making a source port, you'll find that you can sometimes drop these changes in, with minimal modifications, and get them to work your source port.


Above all, prepare to spend a lot of time becoming familiar with how the engine works. There's a lot going on. Be careful, and test your changes often. My experience has been that it may take many months to realize that a change you made way back when breaks a certain map. Keep good logs!


Good luck! I'd love to hear about your progress.

Share this post

Link to post
Posted (edited)
On 6/17/2019 at 9:06 PM, mIMAS said:

I'm both excited and terrified, I really don't mind how much time it will tke to figure out how things work, but I've wanted to study Doom's code since I started playing it.

Thank you all!

Sorry - double post:

Don't be terrified about the code: The code is simple...there's just a lot of it!


What makes it difficult are self-imposed goals and restrictions. The Doom universe has become so massive that you can literally spend a dozen years bringing an early codebase up to speed. Because there are so many source ports, it becomes difficult to distinguish yourself - to bring something new to the table. Mappers and players alike expect many new features and abilities to work. This would suggest forking a mature port, and starting there. But these are typically much more complicated than the original code, so, there's that.


You almost need to start with a young codebase, and hack it to death, just to learn how Doom operates. Then, at that stage, you start over, with the knowledge you've gained. Only then will you know which code to use as a foundation for your particular flavor of Doom.


I can't stress that point enough: Learn how the original game worked first, so you know where everything originated. Because, the only real guarantee in Doom is that the original features of the original IWADs should work in every source port.

Edited by kb1

Share this post

Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now