|
9 | 9 | caption: "Exploring the legendary DOOM engine" |
10 | 10 | --- |
11 | 11 |
|
12 | | -I've been reading Fabien Sanglard's [Game Engine Black Book: DOOM](https://fabiensanglard.net/gebbdoom/), and it's honestly blown my mind. The book breaks down all the clever tricks behind id Software's masterpiece and makes you realize just how insanely talented those early developers were. Reading about BSP trees has me wanting to build something myself. |
| 12 | +I've been reading Fabien Sanglard's [*Game Engine Black Book: DOOM*](https://fabiensanglard.net/gebbdoom/), and honestly, it has blown my mind. The book breaks down all the clever tricks behind id Software's masterpiece and makes you appreciate just how insanely talented those early developers were. Reading about BSP trees, sub-pixel accuracy and perspective-correct texture mapping has me itching to build something myself. |
13 | 13 |
|
14 | | -So that's exactly what I'm going to do. |
| 14 | +So that is exactly what I am going to do. |
15 | 15 |
|
16 | | -I'm building an id Tech 1 engine recreation project in C++. This isn't about making a game, it's about learning by doing, understanding how this stuff actually works, and appreciating the engineering genius that Sanglard documents so well in his book. I want to implement the core systems from scratch and really get to grips with how they work together. |
| 16 | +I am starting an **id Tech 1 engine recreation project in C++**. This is not about making a game. It is about learning by doing, understanding how everything works under the hood, and gaining a deeper appreciation for the engineering genius Sanglard documents so well. I want to implement the core systems from scratch and see firsthand how they all fit together. |
17 | 17 |
|
18 | | -The plan is deliberately old-school: pure software rendering using [SDL](https://www.libsdl.org/) just as a display window. No modern GPU tricks, no shortcuts. I'll be calculating every single pixel in a framebuffer and pushing that each frame, just like the original engine did back in 1993. |
| 18 | +The plan is deliberately old school: **pure software rendering using [SDL](https://www.libsdl.org/)** as a display window. No modern GPU tricks, no shortcuts. Every single pixel will be calculated in a framebuffer and pushed to the screen each frame, just like the original engine did back in 1993. |
19 | 19 |
|
20 | | -## The approach |
| 20 | +--- |
| 21 | + |
| 22 | +## The Approach |
21 | 23 |
|
22 | | -After a couple of evenings chatting with GPT, I've come up with a rough plan of action: |
| 24 | +After a couple of hours thinking the problem through, and with a little help from GPT-5, I sketched out a rough plan: |
23 | 25 |
|
24 | 26 | ### Foundations |
25 | 27 |
|
26 | | -Setting up the C++20 project structure, getting SDL running, and implementing the basic framebuffer system. You can read about this below, aside from some tooling issues, it was pretty straightforward. |
| 28 | +Set up a C++20 project, get SDL running, and draw something. Aside from some tooling quirks, this part was surprisingly straightforward. |
27 | 29 |
|
28 | 30 | ### WAD Loader |
29 | 31 |
|
30 | | -This is where things get interesting. I need to parse DOOM's WAD files and extract the maps, textures, and sprites. The WAD format is beautifully simple but requires careful handling to get right. |
| 32 | +This is where things start to get interesting. DOOM stores all of its game data, including maps, textures, sprites, sounds, and more, inside WAD files. WAD stands for 'Where’s All the Data' and is essentially a simple archive format with a structured directory of all the resources the game needs. To bring the engine to life, I will need to parse these files and extract the maps, textures, and sprites. |
31 | 33 |
|
32 | | -### BSP & Software Rendering |
| 34 | +### BSP and Software Rendering |
33 | 35 |
|
34 | | -This is the big one. Implementing the Binary Space Partitioning system for proper visibility determination, then building the software renderer that draws walls, floors, and ceilings pixel by pixel. Texture mapping in particular looks like it's going to be a real pain. |
| 36 | +This is the big challenge. DOOM’s maps in the WAD file already provide all the geometry in terms of sectors, lines, and vertices, but to render the world efficiently I will need to build a Binary Space Partitioning system to determine what is visible at any moment. On top of that, the software renderer will draw walls, floors, and ceilings pixel by pixel, and getting the texture mapping right promises to be a real headache. |
35 | 37 |
|
36 | 38 | ### Game Features |
37 | 39 |
|
38 | | -Player movement, input handling, sprite rendering, lighting effects, and all the other systems that make DOOM feel like DOOM. |
| 40 | +Finally, player movement, input handling, sprite rendering, lighting, and the other systems that make DOOM feel like DOOM. I'm keeping my goals for this section open-ended for now. |
| 41 | + |
| 42 | +I am not trying to recreate every feature or optimize for modern hardware. I just want to understand the clever solutions Carmack, Romero, and the id team came up with given the limitations of early 1990s PCs. |
| 43 | + |
| 44 | +This project feels like the perfect bridge between my web development background and my eventual goal of making games. It is low level enough to teach proper C++ and graphics programming but focused enough that I will not get lost in scope creep. |
| 45 | + |
| 46 | +--- |
39 | 47 |
|
40 | | -I'm not trying to recreate every feature or optimize for modern hardware. I just want to understand the clever solutions that Carmack, Romero, and the rest of the id team came up with when working with the limitations of early 90s PCs. |
| 48 | +## Laying the Foundations |
41 | 49 |
|
42 | | -This feels like the perfect bridge between my web development background and wanting to make games eventually. It's low-level enough to teach me proper C++ and graphics programming, but focused enough that I won't get completely lost in scope creep. |
| 50 | +At the start, I set up a new C++ project in JetBrains Rider. At this point, I was unfamiliar with most IDEs for C++ development, so I figured it did not matter much which one I used, and I defaulted to Rider after reading that it was becoming quite popular for game development. I planned to use CMake for build management due to it's portability, but after wrestling with the configuration for a while, I realized that Rider does not fully support CMake for native C++ projects out of the box. |
43 | 51 |
|
44 | | -## Laying the foundations |
| 52 | +I quickly realized that none of this mattered at the moment and that I was wasting time. I switched to Visual Studio and MSBuild instead, which integrates cleanly with vcpkg for dependency management. This made it much easier to get a working project structure up and running, and I can always port the project to CMake later if I want to. |
45 | 53 |
|
46 | | -I began by setting up a new project in JetBrains Rider, thinking I could use CMake. After some confusion, I realized that Rider doesn’t support CMake for native C++ projects out of the box — a frustrating discovery, but it quickly led me to switch to Visual Studio, which has native support for C++ and integrates seamlessly with vcpkg, which should hopefully make dependency management less of a headache. |
| 54 | +With the environment ready, I moved on to the first rendering test. For this, I used [SDL](https://www.libsdl.org/). |
47 | 55 |
|
48 | | -For those unfamiliar, [SDL](https://www.libsdl.org/) (Simple DirectMedia Layer) is a lightweight, cross-platform library that handles graphics, input, audio, and more. In this project, I'm using it purely as a window and display backend — all the actual rendering will happen in software, which gives me full control over every pixel, just like the original DOOM engine did. |
| 56 | +For those unfamiliar, [SDL](https://www.libsdl.org/) (Simple DirectMedia Layer) is a lightweight, cross platform library for graphics, input, audio, and more. In this project, I am using it purely as a window and display backend. All the actual rendering will happen in software, giving me full control over every pixel just like the original DOOM engine. |
49 | 57 |
|
50 | | -Once the setup was complete, I wrote some boilerplate for initializing SDL creating a window and drawing some stuff into it: |
| 58 | +Once the setup was complete, I wrote some boilerplate to initialize SDL, create a window, and draw a simple pixel: |
51 | 59 |
|
52 | 60 | ```cpp |
53 | 61 | #include <SDL3/SDL.h> |
@@ -108,8 +116,8 @@ int main() { |
108 | 116 | } |
109 | 117 | ``` |
110 | 118 |
|
111 | | -Seeing it compile cleanly was a relief after banging my head against google for an hour trying to work out the best tools to use. Heres the end result: |
| 119 | +Seeing it compile cleanly was a relief after an hour of wrestling with tools. Here is the result: |
112 | 120 |
|
113 | 121 |  |
114 | 122 |
|
115 | | -It aint much, but it's a start... |
| 123 | +It's not much, but it is a start. |
0 commit comments