Methods
42 (X): Cub3D, raycasting and walls that look 3D
A 3D engine without an engine: Wolfenstein-style raycasting, textures and the project
2 min read
There are projects that change the way you see video games. Cub3D is one of them: a 3D engine without an engine, built from scratch in C, where the walls you see are not modeled anywhere — they are the result of shooting rays of light through a maze grid and seeing where they collide. Before this came minishell, which I explained in 42 (IX): minishell, a terminal from scratch.
How the trick works
Raycasting (shooting rays for every line of the screen) is a simple idea with spectacular consequences. From the player, a ray is launched for every column of pixels (the colored dots that form the image); the ray advances through the 2D map until it hits a wall; the distance traveled determines the height drawn for that column. The farther the wall, the shorter it is. The viewer's brain does the rest and believes it is in a three-dimensional world. It is the trick of Wolfenstein 3D (1992), and rebuilding it means understanding trigonometry, distances and perspectives in a way that no book teaches you.
What I had to build
Before drawing anything, the map must be read: parse .cub files (read them and convert them into data) with textures, colors and the maze layout, and validate everything. I made thirteen error maps, one for each way I could think of to mess up: open walls, strange characters, missing textures, players outside the map. If the map is suspicious, the program refuses to start with a clear message.
Then: minilibX (the school's graphics library) for the window and pixels, directional textures (north, south, east and west each have their own image), movement with collisions to avoid walking through walls, and smooth camera rotation.
The part that doesn't show up in tutorials
minilibX is an old library with different versions for macOS and Linux, and making the project compile and behave the same on both platforms is a project in itself. There were days when the graphical debugging (the hunt for errors) was more about compilation than geometry.
And performance: when every pixel is calculated by hand, you learn to look at the inner loop with respect. One extra calculation on the ray distance and performance drops off a cliff.
What I take away
It was the project where the most people stopped to stare at the screen while it was running. Watching the maze appear column by column, with the textures in place and the camera rotating, has a magic that no other tool at 42 had given. And, as with all big projects, you come out with the feeling that the next time someone tells you "it's just a game", you'll want to explain to them exactly how much is inside.
The next step was going down from 3D to networks: 42 (XI): NetPractice, networks without a server.