The Beauty of Doom 3 Source Code (and how to write CLEAN code)

Phil Choi and a guest break down what made Doom 3's source code elegant: consistent structure, functions that do one thing, strict naming rules, and minimal comments. They pull out lessons for writing clean code today, from file organization to how junior developers should approach their work.
Questions this video answers
13,000 lines
Chapters
So recently on YouTube I've seen a bunch of articles, these articles on Twitter or x that this Doom 3 code is super beautiful and the source code is all there for us to see. I thought we'd review it with mini. So minis in this video. Let's get into it.
Thank you for having me.
You're always here. Anyways, I think I have the articles open. So the exceptional beauty of Doom 3's source code. I'm not really into game development, but code is code, so they should just follow a couple methods. It should look very formatted. It should explain the code. Well, you're communicating your thoughts to like other people really well and let's see if it's good.
All right.
So the exceptional beauty of Doom 3 source code. This is a story about Doom 3 source code and how beautiful it is. Yes, beautiful. Allow me to explain. So now I'm. I'm expecting something, but expectations, frustration a little bit sometimes. So let's see here. This guy's talking about. After releasing my video game dyed, I took a little break, blah, blah, blah. This article originally appeared, I added 13,000 lines of code for main menu CC. Okay, so it ballooned the code to. Yes. Like menus are going to be huge, right? Like you're going to be able to like press on something and then a new menu pops up. So he went through the code. I spent a bit of time going through the source code. It probably, it's probably the cleanest and nicest looking code I've ever seen. All right, I did bring it up here. Before we go deeper into the article, maybe we can just look at the source code real quick.
Sure, let's check it out.
This is pretty clean. It's all C code.
How's the folder structure? You think as a senior dev, like looking at it, Right.
There's a base that's empty, but then there's Neo and then there's something called CM D3XP curl. So these are some request stuff, I guess. I honestly I cannot tell you. You know, I see some C files for the ui, right? Good for me. You know, it's. It's all consistent. It looks like one person wrote it and that's the most important thing and looks fine to me. Some header file. I think that's what an H file is. General notes. The source code does not contain any game data. It's covered. So that's fine. It's just a little explanation. We expect the solution file compatible with express releases. So you can kind of. They tell you how to compile it on each machine. The licenses, the curl library, which is you know, like an HTTP request thing, JPEG library tell you all the libraries they use. So they give like some credits that you know, libraries and codes that they use and like the, you know, the copyright stuff.
As a junior developer, you know, I'm sure a lot of people watching, right. Junior devs, like how, how much focus should he have on like these readmes? Because me personally, like I'm not gonna lie, I'm not really good at reading, but I've seen you take hours on readmes.
Well, honestly for me, when I use a readme, I'm. I'm trying to like gather my thoughts and. Cause honestly, I must be able to explain it to a new user or like a, like a, a new person that's going to help me. And if I'm coding and I have my plan set in my head, someone asking me a bunch of questions is going to take away from my coding time. Right?
Right.
And in the end, coding time is equates to money basically. Right?
True.
So if someone keeps asking me some things that are in the read me, it's going to be kind of why are you asking me? Read the readme and then get to work. That's kind of like I want in the end. Right. So it's just a time saver and every little piece of thing that you're going to do, like a comment in your code or like a variable name that's named correctly. It's all time savers in the end. And clean code means that it's saving time. And then you don't. You're not creating this technical debt where you're going to have to go back and refactor something. Right. I like skimmed through the article before. They said they have like horizontal spacing. The code looks very uniform. Right. This is ID register set regs. Like they're very minimal comments, but it's very informative. But to be honest, I'm not a C developer.
Right.
Code is all kind of similar. Anyways, so let's get into the article. Okay. So he's saying after days of research, I was confused by my own tweet that started this whole thing. What would nice looking or beautiful for that matter actually mean when referring to source code? Right. So I guess he asked his friends. Code should be locally coherent and single function. One function should do exactly one thing. It should be clear about what it's doing. That's, that's so true. I think about single responsibility and separation of logic all the Time and I like me when I think about my code, I kind of think about a factory or where I have like my factory functions, I have my whatever. Like I think about each function being a little bit of worker and they. And if you give a worker too many kind of things, it's bound to be bad for that worker.
Right? Right.
So every code needs to just do one thing and local code should explain or at least hint at the overall system design. Definitely. So all the code it should like hint like what kind of like patterns or whatever you're going to use.
Right.
But code should be self documenting. Comments should be avoided whenever possible. Comments duplicate work when both writing and reading code, if you need to comment something to make it understand, it should be probably rewritten. So if the code gets a little bit like too complicated, they're basically saying is make it simple enough that the variable name can kind of explain what it's doing. Say you're catching a bunch of promises in JavaScript, maybe it should be called promise catcher. Right. And then a promise at all and that's like a resolver and stuff like that. So unified parsing lexical analysis to be honest, like I. What I know like Lexer is doing is it's interpreting the code or whatever. Right. It's in. In JavaScript Lexical Analyzer and parser, all resource files are ASCII files with unified syntax, including script animations. It's just very consistent basically. Right. And it's because everything is very consistent. It's easier because C is compiled. So whatever's doing that is making the code cleaner and making it faster to.
Run C. Like running from top to bottom like JavaScript does or I think so for sure.
I think all code is running top to bottom, except especially when it's compiled. I don't like holding to that, but I think it is because the synchronous stuff that JavaScript is doing inside of the event loop or whatever, that's particular to JavaScript. Like Python, PHP, like all the other languages they run line by line by line by line.
Right.
So Doom's code is fairly rigid, although not rigid enough in my opinion to respect const. Cons serves several purposes which I believe too many programmers ignore. My rule is should I have everything always be constant unless it can't be So I wish all my variables were const by default. Doom almost always sticks to and no in out parameter policy this function. So I'm just going to kind of skim through this function definition makes me happy. Hans tells me a lot about the Function also hints to a larger system designed simply by reading this function. Decoration on other services. So, I mean, they're saying that, you know, everything's named correctly. Everything is giving context to what you're actually building. The big parts. Minimal comments. I think we went over that. That's fine. I think that that's a good thing to happen. Spacing, that's pretty obvious. If you're using, like, tabs or four spaces, two spaces, it should be very consistent and should look. Look that way. Right. Minimal templates. So there's basically, you know, no boilerplate code. They rewrote all the. They rewrote all the required STL functions. So they, you know, there's no. Like, they kind of like the spacing inside of the code. I saw. Maybe they all did it like themselves. Like, these spaces usually, like, you know, the code or the formatter or whatever is kind of like fixing all those spacings. But they have, like, their own way to code.
Right.
It's. It's all very consistent. Right. It looks like one person wrote the whole thing. That's the most important thing. So remnants of C. I mean, I know Quake 3. That would like. Yeah, Quake 3, okay. Was written in C, I guess. And I know that that code is, like, supposed to be very beautiful as well. And. Yeah. So, you know, what are horizontal spacing? That's something I kind of saw earlier. Method names, they should all be very. That's like, same with, like, variable naming.
Right.
And it's beautiful. So, you know, I guess, you know, if you're like a coding nerd, you can appreciate, like, what they did in the doom3 code. As for me, like, I, Like, I. It looks good, right? It looks good, but I don't know enough context, I guess, about game programming or whatever. Kind of like, really know it, like, really deeply. But I think I can appreciate that. Everything doesn't look like spaghetti. Right? And, you know, just some code that I think that I've written that's, like, pretty clean.
Right, right, right. I was gonna actually say, because I remember when I was working for you, you know, and like, you're the one who gave me my first break. Like, when you showed me the code that you wrote, you had like, dude, like, each file was very short. Yeah, yeah, And I noticed that. And like, you really broke up everything into bits and pieces of it. So, you know, I think it would be pretty cool if we get to review that a little bit.
Okay, cool, Cool. Like what? I define clean code. You know, it's hard to say. Every code Is like super clean. It's very subjective too. But you know, like me, like every file has its like own responsibility. So like I'll just go over like community posts. It's this coffee app server that I made the backend server, I think you remember it was for the last company I worked at. I won't mention any names, but basically if you open up the folder, if you open up the code and your first line of defense or line of understanding the code is going to be the file names. Right? That's the first. Like as a human you don't even have to be a code or anything. Yeah, you see the file names and you open up. Okay, community posts. You know exactly that it's going to have ad community posts. Going to have delete community posts. Get community posts. Like community posts. Update community posts.
Right.
Like you know exactly what the code is going to do in this section just from the file names. So like there's like a community post factory here. Basically you have, I define a function that returns, you know, a prototype and inside of the function community post factory. I have a create function that adds everything that I need to add. But can you. It's single responsibility. Add community post. Basically you just add the community post. Make sure that it adds in the database. Add comment to community post. Basically it's adding a comment. Very simple. And get community post. You know what the parameters are, the id. If an ID is passed, I say detail API, it gets the one community post. If not you get the list of community posts. Yeah, and just like basically yeah, just everything is just doing its one thing here. All my get things, here's like my aggregate function where I can kind of query the database and join the collections. It could be broken down a little bit more. But I, you know, this file is just all about getting community posts.
Right.
I follow those methods. And yeah, I think the first line you have is the file naming. Then inside of the file like whatever you're going to do in there and it gets easier to work with, you know, and you want to make yourself as easy to work with as possible to really get a job.
Right, right, right, right, right.
Oh, you know, like name things. Naming things is very important. Your variable name should kind of explain what the code is going to do.
I guess, you know, if someone was to like work with you to finish this project, let's say in the future, one day, you know, and it's a big project. Like I know you as a senior developer, your job mainly was to teach juniors to work on these projects. Basically, right. Where. If they see this code, like, where would they start?
If they see this code, where would they start?
Like, how would you decipher this code? As a junior, how would they understand this code? Basically, what are the steps to kind of like reading this code?
I guess just running the code. Right? That's the first thing. So Docker compose up or whatever.
Yeah.
And that's going to be here. And it's going to be. This is like. And then you probably, like, ask your senior developer, whoever created it, you have the readme to check or whatever.
Right.
The first thing is how do you run this code?
Right, right.
Then once the code is running, then you can kind of decipher what needs to be done. And you're going to have your task board or Jira or Trello or GitHub projects, whatever you're going to use, there's going to be, like, tasks to do, Right. Because there's unfinished stuff as well.
Right.
Always. So basically, like, is it all running in Docker? Can I just run Docker combos up and everything goes up? Sure. And then once there, you look at the tasks that are left to do and then you get started, right. The code in, like, the correct way. I think everything is in here. Like the eslint, your prettier file is all in here to kind of make sure the code is pretty good.
Right.
And it would just about be like getting your hands dirty. Right.
For you. What are like the top three things that makes a beautiful code as a person? Web development. Mobile development person.
I think there's something I always try to follow there. Who is this guy? Builder. Builder. Builder Bob. No, no, Uncle Bob. Clean Code. It's a blog.
Okay, cool.
I try to read this or like, I used to read this a lot and it's about, like, clean architecture. Right. When I was first learning how to code, I had this printed out in my room to kind of like, you know, like really look at it.
Right.
And you have your entities and then you have your use cases. And basically all this is saying is you have your separation of logic, right? Everything is doing its own thing. How you would start writing the code is making sure, like, hey, is the route handling the route? And do I have a controller here to kind of handle all that control with the database? And I'm not just mixing everything into like one little pot, right? I have my, you know, I maybe I have my pot, then I have my stir, then I have my ingredients and I kind of separate everything so they can be reused in other places, right? Like I'm always going to talk to the database in the same way through my adapter.
Right? Right.
Say I have one parameter going in the get request. I'm probably going to put it at a path parameter rather than like a get request body. Have the code very consistent, and as long as it's consistent and you're following the rules of whatever is already in place, then go for it. And if you feel like what's in place is kind of like really bad, make your own folder in the way that you want and make it very readable but able to be used like a node module, like basically like a local node module. And that would be like a good way that you can separate your code and code the way that you need to and then later always refactor it or redo it in the way that it needs to be done.
Yeah. I think thing that you always stress, and I think it's underestimated is like the fact that in the beginning when we're learning programming, like we're a solo developer, you know, in the job field you have to work with others. Right. And it's underestimated writing beautiful code.
You know that is true. There are definitely a lot of YouTube out how to write the clean architecture code.
Right.
Have a bunch of things and I watched all of them. Like, not all, there's too many. I've watched many of them. You're not the first person that's doing the code.
Right.
There are many people have done it before and everybody has a lot of opinions. But if you have enough knowledge, I think you can pick the things that you want to do, make arguments for why it needs to be the way that it needs to be. Right?
Right.
And I think the kind of argument where it's like, okay, because this person said this, let's do it this way.
Right.
I think it's not a very good way to do it. I think you need a lot of perspective. I'm not saying like read every, every little thing. Right. Maybe read the clean code blog and then read something about like a different architecture and then pick out the things that you want and make your own. Right, but like make your own abstraction of clean architecture or something. But like if you read this book Clean Architecture and stuff, it's actually like it's broken down a little bit too much. Like you have like a function and he says like, function should only be like five lines at most. And then you call a function inside of a function and that function calls a function inside of a function and it gets like it gets a little too crazy, and, you know, in the end, you're the one that's going to be working on it. So make it as easy as possible.
You're going to have to don't get into fights.
Just make the code easy to work on. And if it's easy for you to work on, and you can make arguments for why it's easy to work on, then you can explain to other people you know how to do it right. No code is supposed to be an obstacle for someone. You know, if you want to ever talk to people like me, Mini, or any people looking to get, you know, hands dirty in programming or ask any questions, just come to the discord. The link. It'll be linked in the description. You know, I always say, if I can do it, you can do it, too. Coding saves lives.
More from Phil

day in the life of a software engineer | 5 hour productivity | building my dev agency 🔥

day in the life of a software engineer | 3 hour productivity | coding my 6-figure community startup

day in the life of a software engineer | 5 hour productivity | coding our sns startup app LFG

day in the life of a software engineer | 5 hour productivity | creating apps that makes big money






