A First-Person Shooter Written in Pure COBOL
A developer builds a Wolf3D and Doom-style 3D engine using GnuCOBOL and FFplay.
We all know the stereotypes. COBOL is the language of ancient mainframes, green screens, and the global financial systems that everyone is terrified to touch. It is verbose, rigid, and decidedly not designed for real-time graphics.
But then a developer goes and builds a 3D engine with it.
Created by developer icitry, FPS.cob is a fully functioning first-person shooter written almost entirely in COBOL. Comprising 99.7% COBOL and a tiny 0.3% sliver of Shell script, the project serves as a brilliant, slightly unhinged proof of concept: with enough determination, you can bend even the most business-oriented legacy language to your gaming will.
The Stack: Compilers and Media Players
To get a 3D game running in a language that doesn't even have a native concept of a screen pixel, the project relies on a clever combination of three basic requirements:
cobc: The compiler for GnuCOBOL, which translates COBOL code into C before compiling it into a native binary.ffplay: The lightweight media player from the FFmpeg suite.bash: To glue the build and execution steps together.
Because COBOL lacks built-in graphics libraries, the engine bypasses traditional windowing APIs entirely. Instead, it relies on a classic developer pipeline: compiling the COBOL source, calculating the 3D projection mathematically, and piping the raw frame data directly into ffplay to render the window and handle the display.
Building and running a specific map is handled via a simple bootstrap script:
# To load the Wolf3D-style grid map
bash build.sh ./map/level1.map
# To load the Doom-style sector map
bash build.sh ./map/doom_sectors.map
From Grids to Sectors
What makes this project particularly impressive is that it isn't just a basic raycaster. The engine actually supports two distinct styles of level design, defined in its map/ directory:
map/level1.map: A classic, grid-based pathing system reminiscent of Wolfenstein 3D. This relies on simple raycasting math against a uniform grid to draw walls.map/doom_sectors.map: A much more sophisticated sector and linedef map. This approach allows for doors and varying floor/ceiling heights, mimicking the core architectural achievements of the Doom engine.
Implementing sector-based rendering in COBOL—a language designed for record processing and decimal arithmetic—requires a serious amount of mathematical heavy lifting. The engine has to parse these map files, calculate line intersections, handle player positioning, and project 3D geometry onto a 2D plane, all using COBOL's famously verbose syntax.
Controls and Assets
The game features a standard control scheme mapped to the keyboard:
- W / S: Move forward and backward
- A / D: Turn left and right
- Space: Fire weapon
- Q: Quit the game
All of the visual assets, including textures and sprites, live in the res/ directory, while the map layouts are parsed directly from the map/ directory at runtime.
Ultimately, projects like this are a fantastic reminder of what "Turing complete" actually means. COBOL might have been built to balance ledgers and process batch payrolls in the 1950s, but at the end of the day, a CPU just executes instructions. If you can calculate a vector in C, you can calculate it in COBOL—even if it takes a few more lines of code to get there.
Sources & further reading
- FPS.cob: A first person shooter in COBOL — github.com
Lenn writes about cloud platforms, Kubernetes internals, and the infrastructure decisions that quietly make or break engineering organizations. Based in Berlin's vibrant tech scene, they have a talent for turning dense platform-engineering topics into prose that people actually finish reading.
Discussion 2
i love that the project is on github, but i have to wonder about the licensing - is it really open source if there's no explicit license specified?
@opensource_maya that's a good catch, implicit public domain or unlicensed isn't the same as open source - icitry should probably add a license file to fps.cob to clarify