## Learning and Applying Mathematics using Computing

### Doomed

Today’s trigonometry example comes from gaming history: the early days of what are now known as first-person shooters (FPS). But don’t worry, you don’t need to like or play FPS games to understand this post.

The first major FPS was Wolfenstein 3D, by id software. It used raycasting and texture mapping (both of which we’ve recently covered on this blog) to draw 3D graphics way before the existence of the specialised graphics cards we have today. Wolfenstein’s control scheme was quite simple. The up and down arrows moved you forward and back. The left and right arrows turned you. You could also hold down the Alt key, which would make the left and right arrows move you side-to-side, which came to be known as strafing. Strafing allowed you to more easily move into cover (as you could shoot an enemy, then sidestep behind cover, without having to turn away first).

Fast forward a year or two, and Doom was id software’s successor to Wolfenstein 3D. Graphically it was superior, and used cleverer algorithms underneath (which, if I’m honest, I never quite got my head around). Anyway, the interesting thing for this post is the control scheme. Doom allowed for more customisation of the controls, and introduced the now-ubiquitous idea of using the mouse to control movement, while using the keys to control forward/back and strafing.

Wonderfully, id software regularly release the source code of their old games as open-source. So here is the actual movement code from Doom:

if (gamekeydown[key_up])
forward += forwardmove[speed]; //50
if (gamekeydown[key_down])
forward -= forwardmove[speed]; //50
//...
if (gamekeydown[key_straferight])
side += sidemove[speed]; //40
if (gamekeydown[key_strafeleft])
side -= sidemove[speed]; //40


This works out the forwards and sideways movement, and later they use sine and cosine to translate this into movement at an angle — just as in our movement code (you can’t move at an angle without sine and cosine!).

There is an interesting issue with this movement code. You can use it to move in the obvious four directions — forwards (which I’m drawing as upwards), backwards, strafe-left or strafe-right — going slightly faster forward and back than strafing:

However, there is nothing stopping you pressing forwards and strafe-left or any other combination, giving a further four directions you can move (coloured red):

I’ve labelled the amount moved there as $\text{diagDist}$. What is the value of this distance? Well, it’s a simple case of Pythagoras. The two sides of the right-angled triangle in each case are 40 and 50, so Pythagoras tells us:

$\text{diagDist} = \sqrt{50^2 + 40^2} = 64.03~~~\text{(to 2 dp)}$

So you can actually move further diagonally than you can by simply moving forwards. In Doom, fast movement is an advantage: the faster you move, the harder you are to hit, and the quicker you can get away from monsters. So quite soon, people realised that when you move around in Doom, doing the obvious thing of moving forwards is slow: moving diagonally is much faster. This became known as strafe-running and was soon essential in competitive Doom matches.

It does mean that you need to face at an angle from the way you’re heading, making you slightly vulnerable to attack from the other side. And what angle is it that you need to run at? Well, that’s a case for inverse tangent:

$\text{angle} = \arctan(\displaystyle\frac{40}{50}) = 38.66^\circ (\text{2 dp})$

Many later FPS games have “corrected” this oddity, by instead using the movement keys to decide which of the eight directions to head in, then moving the same amount no matter whether you’re going forwards or diagonally. But that original behaviour in Doom, coupled with basic geometry, added an extra dimension to Doom’s play.

#### Comments on: "Doomed" (2)

1. yedefei said:

where is the sample scenario for this post?

2. There isn’t one, although you can find various open-sourced versions of the Doom enginer around if you want to have a play to see the effect.