DEV Community

dev game
dev game

Posted on

Why Doom Bet on Custom C and Fake 3D: The Boring Code Behind the FPS Empire

Doom did not license a 3D engine in 1993 because there was nothing to license. On December 10, 1993, id Software shipped Doom for MS-DOS on its own Doom engine, written in C with Assembly helpers, developed on NeXT workstations and ported to DOS for release Doom release and engine credit. That unfashionable choice — portable C and fake 3D instead of waiting for true 3D hardware — is why a small core team could run on a 486, sell an estimated 3.5 million copies by 1999, reach up to 20 million players within two years, and still be playable through community source ports 30 years later.

That engine question still has search demand. In October 2026, English suggestions clustered around what language was Doom coded in, what language was Doom written in, what game engine does Doom use, what engine does Doom use, and Doom 1993 source code. This article answers that intent for indie developers: what the custom C stack actually was, what it bought, what it cost, and what to steal today.

The short answer: portable C, BSP, and 2.5D on purpose

Lead programmer John Carmack, with John Romero, Dave Taylor and others, built the Doom engine as the successor to the Wolfenstein 3D raycasting engine Doom engine credits and lineage. The id Tech history places it the same way: pseudo-3D engines for Hovertank, Catacomb and Wolfenstein, then the Doom engine for Doom in 1993, Doom II in 1994 and Doom 64 in 1997, before true-3D Quake id Tech lineage from Wolfenstein to Doom to Quake.

Technically it was:

  • Written in C and Assembly, listed as C and Assembly with MS-DOS as the launch platform and later ports everywhere from NeXT and Linux to Jaguar, 32X, PlayStation and Switch Doom engine language and platform list.
  • Developed on NeXT, shipped on DOS. It was originally developed on NeXT computers and ported to MS-DOS for Doom's initial release NeXT origin and DOS port.
  • A 2D floor plan rendered as 3D. Although it renders a 3D space, that space is projected from a two-dimensional floor plan, with line of sight always parallel to the floor, walls perpendicular to floors, and no multi-level rooms or slopes 2D floor-plan limit.
  • Binary-space-partitioning (BSP) precomputed offline. A tool builds BSP data beforehand, which is why walls cannot move sideways while doors and lifts can move up and down BSP precomputation and static walls.
  • Separated simulation tick. The graphics run as fast as possible, but the game world runs at 35 frames per second regardless of hardware, so machines with different performance can play together 35 fps world tick.
  • WAD-separated data. Levels, textures and sounds were packaged as WAD files — Where's All the Data? — with IWAD for base data and PWAD for add-ons, so new levels did not require patching code WAD separation and IWAD/PWAD.

Carmack's own 1997 release note is blunt about the trade: polar-coordinate clipping was silly in retrospect, but horizontal and vertical lines of constant Z with fixed light shading per band was dead-on Carmack on rendering concept. He also flags the big miss: he used BSP for rendering but did not at first use it for movement and line-of-sight testing Carmack on BSP miss.

Naming note: id Tech 1 was never an official release name. Before id Tech 5 branding in 2007, engines were named after games; CEO Todd Hollenshead later considered the Doom engine as id Tech 1 in a FiringSquad interview id Tech 1 retronym.

What fake 3D actually meant in play

Doom looks 3D but plays 2D. Enemies and objects are 2D sprites at fixed angles, a technique sometimes called 2.5D 2.5D sprites and billboarding. All walls are drawn vertical, so you cannot properly look up and down; modern ports fake it with y-shearing that moves the horizon line and distorts at extremes no true look up/down.

Level structure follows from that:

  • Vertexes join into linedefs, linedefs have sidedefs, sidedefs group into sectors with floor height, ceiling height, light level and flats sectors and linedefs model.
  • To get a different light in one spot you make a new sector. One-sided linedefs are solid walls; two-sided linedefs bridge sectors sectors for lighting and steps.
  • Top-down, every level is two-dimensional. Room-over-room is impossible, but the automap falls out for free no room-over-room, automap bonus.
  • The renderer walks the BSP tree front-to-back, draws closest segs first, clips later segs, and stops drawing a screen column once it hits a solid wall BSP render order and clipping.

Shareware distribution matched the tech: id published Doom as three episodes and gave the first away free, selling the full game off that sampler shareware three-episode model.

What the custom C stack gained — and what it cost

Decision Gain Cost
Portable C + small Assembly on NeXT, then DOS Ran on 486 without 3D accelerator; later ported to 15+ platforms from PC-98 to Switch and PS5 No hardware help; all tricks had to be software: column renderer, fixed shading bands, non-power-of-two textures
2D plan + BSP + 35 Hz logic Deterministic multiplayer across unequal PCs; huge maps with no overdraw penalty; speedrun-friendly fixed tick No jumping-as-geometry, no slopes, no stacked rooms; precompute step made iteration slow for large levels
Sprites instead of models Fast billboards, memorable monsters on tiny memory; artists could iterate without rigging Fixed angles age visibly; no true vertical aim
WAD file split Players became level authors without coding; Origwad on March 7, 1994 and Doom Editing Utility on January 26, 1994 arrived weeks after launch Core behavior stayed hard-coded in the EXE until DeHackEd let users patch parameters
Source release under GPL Dozens of source ports keep Doom alive on unsupported OSes and add transparency, slopes and scripting source ports after 1997/1999 release Commercial control diluted; id had to learn to hire from the mod scene with Master Levels and Final Doom

The modding payoff was explicit. Carmack designed Doom internals to be extendable after Wolfenstein modding proved cumbersome, backed by Carmack and Romero against internal legal worries Carmack designed for extension. The Linux source arrived December 23, 1997, Doom II a week later, then GPL-2.0-or-later on October 3, 1999 1997 and 1999 source releases. Licensees proved the same base could carry Heretic, Hexen, Strife, Chex Quest and Freedoom Doom engine licensees.

My take: Doom won by being less 3D than it looked

Most retrospectives say Doom won because it was 3D. I think the opposite is more useful: Doom won because it refused to be fully 3D.

1. Fake 3D was a distribution strategy, not a graphics demo.
True 3D in 1993 meant tiny windows or expensive workstations. By staying 2D for logic and faking the third dimension with vertical columns and BSP sorting, id fit the game on the PCs people already owned. Shareware then did the rest. My read: resolution and color sell trailers; frame rate and download size sell installs. If you are solo today, the equivalent is not ray tracing — it is a game that holds 60 fps on a school Chromebook.

2. Missing features became readable design.
No room-over-room sounds like a flaw, but it gave Doom legible maps, a usable automap, and arenas you can read in one glance. No look up/down sounds primitive, but it removed a whole axis of aiming frustration and made circle-strafing the skill. Fixed 35 Hz logic sounds rigid, but it made demos, netplay and later speedrunning comparable across decades. Constraint did not just save cycles; it taught players one skill deeply instead of five shallowly.

3. Boring portable C outlived every clever trick.
Carmack himself calls parts of the code silly and sketches a cleaner front-to-back BSP walk he would do next time Carmack rewrite sketch. That honesty is the point. Because the code was portable and the data was separate, strangers could fix, port and extend it for 30 years without asking permission. A fancier, hardware-locked engine would have died with its GPU. If you want longevity, write code a stranger can compile.

None of this means you should clone BSP in 2026. It means: pick the least 3D that still delivers your fantasy, lock your tick, and separate data so players can build.

What indie developers can steal this week

  1. Prototype the floor plan first. If your level is not fun as a top-down map with heights written as numbers, columns and sprites will not save it.
  2. Lock logic to a fixed tick. Even 30 or 60 Hz is fine. Determinism gives you replays, netplay and testability that variable delta-time never will.
  3. Split engine from WAD. Put levels, strings, damage numbers and spawn tables in editable files. The Doom Editing Utility ecosystem started because Matt Fell could publish specs and Brendon Wyber could ship DEU without id's build chain DEU and specs history.
  4. Ship one free episode. Doom's first-episode-free model is today's polished demo or itch.io vertical slice. Make it self-contained and shareable.
  5. Plan your GPL moment. You do not need to open-source day one, but decide what becomes hackable and when. Source ports are marketing that compounds.

Train the Doom skills in a browser

You do not need DOSBox to feel why Doom's loop works. Two free browser shooters isolate the same muscles:

  • For circle-strafe, corner-peek and weapon-swap pressure, play a few rounds of Hazmob FPS: Online Shooter on Team Deathmatch or Free for All. Its compact maps punish standing still, its 1-2-3 weapon keys and G-to-pickup flow echo Doom's shotgun-first triage, and its seven-mode structure lets you practice aim in Free for All before trying no-respawn Elimination — the modern version of Doom's 35-tick fairness where positioning beats hardware.
  • For arena control and warm-up discipline, use BuildNow GG Aim Training plus a BoxFight lobby. Treat edits like Doom doors: open, tag, close. The guide's 3–6 sensitivity starting point and unlimited-FPS notes are the 2026 version of Carmack's run-as-fast-as-possible renderer advice — smoothness first, effects later.
  • For weapon-ladder intuition, spend ten minutes in Stick Merge. Merging pistols into rifles into automatics is a toy version of Doom's pistol-to-shotgun-to-chaingun-to-BFG escalation. It teaches the real lesson: damage is pacing. A new tier should change which fights you take, not just the number on screen.

None of these are Doom, and that is the point. They let you practice one Doom verb — move, aim, escalate — without nostalgia.

Open questions worth keeping

  • How much of Doom's gun feel came from fixed light bands and column textures versus level pacing? Sanglard's 427-page teardown with forewords by Carmack and Dave Taylor digs into 486, VESA, DOS extenders, Watcom and NeXTStation details that still repay reading Game Engine Black Book: Doom scope.
  • Would Doom have modded as fast without the EXE hard-coding that forced DeHackEd into existence? Limits created tools.
  • When does fake 3D stop working? Horror and vertical platforming broke Doom's model quickly — which is why Quake had to go true 3D with client-server and QuakeC.

Bottom line: Doom bet on boring, portable C and a 2D map pretending to be 3D, then gave players the files. Rivals chased polygons; id chased machines players owned and maps players could edit. That is still a winning indie bet.

Top comments (0)