Category: Programming

Wolf3D raycasting engine – The Implementation

Here we are! After a one-day full-immersion, here is the first version of what I called Dog3D: a pseudo-3D raycasting engine inspired by Wolfenstein 3D’s engine.

Dog3D is based on the same principles I described in the previous article. I’m not gonna repeat myself, so if you haven’t read the theory, go read it and then come back here.

In this article I’m gonna explain how you can implement the raycasting theory we saw previously to build a real world raycasting engine.

Since there is a lot of code to show, I will just show you the most important, so I can explain it to you. To see the complete work, just check out my github.

The basic idea and data structures

Design, in software development, is probably the most important thing. It allows you to program faster and better and a good design makes possible to optimize your work with less effort.

So, let’s decide what we want to make!

We said we can represent our levels with a 2D matrix, so we want our engine to read levels from external files (no one likes to create integer matrices manually) in a form like this:

The numbers defines different types of objects, the white spaces represent walkable area and the P character is the player.
The player will move in the walkable area and the engine will render every block in his field of view respecting the proportions based on the distance from the player.

This matrix is obviously a 2D characters matrix, so we can implement it as a pointer to string:

std::string *level;

It’s useful to store also matrix’s width and height, so we can work more easily, in case we need those informations. It’s probably a good idea to store those informations in the same structure… and now that we are on this, it would be nice to save also player’s position in it, since we can only have one player in the level and the player is an object of the level.

Continue reading

Wolf3D raycasting engine – The Theory

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.

Let’s start!

Ingredients

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.

 

Continue reading

Navigation