Database expert runs Doom in SQL with just 5,900 lines of code
4 hours ago
4
(Image credit: Lukas Vogel / CedarDB)
It's the year of two thousand and twenty-six, and "Running Doom on X" is still probably the most popular software hacking hobby. From pregnancy tests to space satellites, the 1993 game has been ported to pretty much anything under the sun that has a CPU and some memory in it. Now it's time to run the game in a database, in this case CedarDB, courtesy of the SQLDoom project by Lukas Vogel, who previously authored DoomQL.
If you're wondering how the heck one runs a game in SQL, it's actually much easier than you imagine, so long as you think like a database architect. The actual frontend displaying the graphics, playing sound, and taking inputs is in Python, but that part acts only like a PC's peripherals — all the math is done inside the database.
The backend is written for the performance-focused, Postgres-compatible RDBMS CedarDB. Much like modern Doom ports, SQLDoom uses two paths: one running at the game's original 35 Hz for handling all the logic, and a separate thread for displaying graphics, interpolating camera position between game updates.
To start, Vogel had to convert the entities in Doom's WAD package file to databases. That was easier than expected, as the data therein "is highly relational already," with Vogel presenting the example of map levels ultimately being structured in parent-child relationships that are trivial to replicate in plain tables. 1000 lines of Python was all it took.
For the main gameplay loop, Vogel was once again pleasantly surprised that the game logic was easy to convert. The resulting code was 5,900 lines of SQL, compared to the original C source code's 9,000. A lot of the savings came from the fact that whereas one has to iterate over entities with "for" or "while" loops to update values, a simple "UPDATE... WHERE" is enough in SQL to do that in just one statement — and in parallel, no less. As an added bonus, the fact that everything is a row in a database table makes for some trivial instant modifications, like changing weapon characteristics or enemy behavior on-the-fly.
The graphical renderer is also small at 1,300 lines, but it's trickier as it's the one query spanning 89 tables. Vogel notes that the pipeline is ultimately very similar to that of Doom. Data for Carmack's then-revolutionary Binary Space Partitioning (BSP) traversal, an implementation of binary trees, can be easily represented as a table.
Each left/right value can be converted to a bit, and ultimately the vertex order value can be reduced to just the one number. Thus, a simple "SELECT... ORDER BY" automagically sorts the walls front-to-back for you. Amusingly, I used the very same database technique when I wrote the defunct Tech Report's threaded comments system. Despite his best efforts, Vogel says the floor and ceiling renderers didn't map very cleanly to SQL, as ultimately they're clever flood-fill algorithms.
Get Tom's Hardware's best news and in-depth reviews, straight to your inbox.
When it came to multiplayer, that's when using a database was actually much better than the original game. The reason is simple: maintaining synced states across many tables with copious amounts of interdependencies is literally what databases are designed for, so snapshots, authentication, access control, are all effectively free and implemented for you. To run a game tick, all you need is "START TRANSACTION," run the logic, and "COMMIT," and everything magically synchronizes.
Bruno Ferreira is a contributing writer for Tom's Hardware. He has decades of experience with PC hardware and assorted sundries, alongside a career as a developer. He's obsessed with detail and has a tendency to ramble on the topics he loves. When not doing that, he's usually playing games, or at live music shows and festivals.