From bonkers to bananas; Doom!

Freedoom's title screen in glass, with the strip above it

Yesterday was bonkers. Today went bananas.

Two days ago I told Espen about my current projects, about the circuit board app, the chess in the terminal and the chemistry bench. He handed me a challenge, “How about you make a game engine for the terminal?”.

Friday was too busy for that since I also made an SQL database and a browser. But Saturday had some spare time, and a game engine was born. It plays Doom!

The game itself is running in my terminal, on my desktop written in assembly. Lots of ground work in Assembly and Rust, but it was done in less than a day.

A game engine for the terminal

The engine is funkey. A game draws pixels into a frame and reads keys. funkey runs the loop at a fixed rate and puts the frame on the screen. First as half blocks, two pixels a cell in full colour. By the afternoon the first game ran on it: climb, a Jumpman-style platformer. Ladders, coins, blobs.

Then I leveled up my Assembly terminal. Two Claude sessions worked side by side, one on the engine and one on glass (my terminal), talking over a message bus. glass learned to show real pixels through the kitty graphics protocol, with the frames handed over in shared memory. And it learned to report when a key goes UP. A terminal never tells you that. Now it does, so holding an arrow walks and a tap takes one step.

My battery rule is waived for games. I know, I know.

Doom

First the renderer. The level is drawn along its own BSP tree, front to back: textured walls, floors and ceilings. Sprites go in against a depth buffer, lit by the sector and the distance. A frame of the first map takes one millisecond.

Then the rest. Every monster from both Dooms, with Doom’s own frame timings. They see you, hear your gun, chase, shoot, bite, feel pain and die like monsters should. All nine weapons. Health, armour, keys, backpacks, powers. Doors, lifts, floors, crushers, stairs, teleports, switches, exits. The status bar with the face. The automap. The red flash when you are hit. The intermission, then the next map. Sound from the WAD. Some five thousand lines of Rust from the WAD loader up.

That film is the game’s own frames and sounds, written straight to video by a scripted run. Every pixel is what the terminal shows.

Doom in glass, on the CHasm desktop

And that is the real thing: glass, in my desktop, with the strip on top. The WADs are Freedoom, which is free. Doom’s own WADs load the same way.

cargo run --release --example doom

Arrows move, Space fires, E opens doors and presses switches, Tab is the map. The old cheats work.

Summary

Built with Claude. The browser took some hours. Doom took an evening.

For the anti-AI crowd; Now would be a good time to say a prayer to King Ludd.


Link to this post: https://isene.org/2026/09/Doom.html