So… this is it. I’m getting old.
id Software is one of the most important software house for both videogames history and me… and 5 days ago (1st Feb 2018) was its 27th birthday!
1st Feb 1991, 5 guys (not the fast food) registered the name “id Software” for their newborn game development studio and gave birth to one of the most important games ever: Wolfenstein 3D, the first FPS ever.
Apart from defining a genre, the most important thing that Wolf3D did was to introduce a new technique to render a 3D scene in plain 2D without calculating a single 3D object. This technique is called raycasting and is based on geometrical interpretation of a 2D map using some linear algebra trick. Then, in 1993, id created Doom that used the same principle, but with a more optimized engine that permitted to render levels of incredible detail, the possibility to make mods, and a lot more texture. Then, one year after, it came Doom 2, with more mods, big spaces and the illusion to have more than one floor.
In this article I’m gonna try and explain how you can implement a Raycasting engine to create from scratch a pseudo-3D fps like Wolfenstein (or Doom) in C++ with SDL. Yes, I know, nowadays you can create actual 3D fps way more easily with Unity or Unreal Engine, but creating a raycasting engine from scratch in pure C++/SDL is not only a very good exercise for your programming skills, but it teaches you an important lesson: when you don’t have enough resources and you have to optimize a lot, maths skills kicks asses! This is not just a graphical engine to make a Wolf3D/Doom clone, but it’s a project that shows you how it was possible to revolutionize the world of videogames with just a good idea.
For this project you can use whatever graphical library you want: SDL, SFML, PixelToast… they’re all good. I’m gonna use SDL2 because it’s the lib I know best and it’s pretty common in the game dev (mostly in indie and linux game-dev).
We’re gonna use C++ as programming language and of course you can choose whatever IDE/compiler you want… it’s not gonna break anything, don’t worry. The only thing you have to check is how to configure SDL2 (or the library you chose) for that IDE/compiler.
If you need a tutorial to setup SDL2 or to know how to use it, you can try the amazing tutorial series by Lazy Foo.
Theory and planning
So, how this raycasting thing works?
If you ever played Wolfenstein 3D, you probably noticed that the whole game take place in a labirinth without stairs. All the game take place on the same floor. This is because raycasting is not real 3D, but the projection of a 2D map. The principle under this technique is the same that lies behind the axonometry.
The 2D map can be implemented in various ways… you can create a matrix MxN of various symbols each of which represent a different object in the room. This is the way they did it in id Software and we’re gonna copy them! 😛
This is what the first level of Wolfenstein 3D map looked like in the original map editor. Every character means something for the map parser that tells the engine what to render and where.
A super interesting thing about this system is that you can actually implement endless type of object because you can use every ASCII/Unicode character, and if that’s not enough, with a little more effort, you can create a more advanced parser that can process more sophisticated maps… but that’s not the case. We’re gonna keep things simple and by the way, even just using non-extended ASCII is more than enough for a lot of games.