QuakeWorld Air Physics

boredemployee1 pts0 comments

mattias - Quakeworld Air Physics

Quakeworld Air Physics

Jan 23, 2013

Quake is one of my favorite computer games of all time. I played it for more<br>hours than I want to think about. After the source code was released, I used<br>it to look for new ways to improve my game. That's how I stumbled on<br>PM_AirAccelerate() and found the code behind the game's most abused<br>mechanic - speed jumping.

Disclaimer: This may be the narrowest technical article of all time. The<br>point of it all is buried near the end, so feel free to skip ahead.

Speed jumping is possible thanks to some odd characteristics of the in-game physics.

Changing direction in midair is allowed

Doing so causes the player to accelerate (!)

Jumping continously completely negates ground friction

Quake with speed jumping is an absurdly fast-paced game. Here's a<br>video that shows some gameplay. Note how players start bouncing around<br>like on pogo sticks whenever they need to go someplace in a hurry.

A Seed

Everyone who plays Quake knows how to speed jump. Before I saw the code I<br>didn't understand how something like this could be unintended. Either you<br>allow wacky air acrobatics or you don't. But reality is humbling sometimes.<br>See if you can spot the problem in the code.

void PM_AirAccelerate (vec3_t wishdir, float wishspeed, float accel)<br>int i;<br>float addspeed, accelspeed, currentspeed, wishspd = wishspeed;

...

if (wishspd > 30)<br>wishspd = 30;<br>currentspeed = DotProduct (pmove.velocity, wishdir);<br>addspeed = wishspd - currentspeed;<br>if (addspeed addspeed)<br>accelspeed = addspeed;

for (i=0 ; i

This function updates a player's current velocity by considering the "desired<br>velocity". It comes from the client as a vector split up into a normalized<br>direction wishdir and a magnitude wishspeed. The values for accel and<br>frametime are not important, but for completeness they are normally 10 and<br>~0.013.

This is some fancy vector footwork. I have just two basic tips for how to<br>understand vector math. First, some operations can be interpreted<br>geometrically. So when you see dot(x, v) where v is of unit length, it means<br>"find the length of x in the direction of v". When this fails, you can apply<br>the second and more primitive technique of putting in some sample values and<br>see what comes out. Put enough values in, and hopefully you can synthesize the<br>results into some kind of intuition. Yes, that means writing<br>code.

From playing the game I already knew what happens in some special cases.<br>If you press forward in mid-air,<br>nothing happens, you keep going forward. If you press backwards, you break to a stand-still, then you<br>fall down while going very slightly backwards. It's as if the game wants to<br>allow some minimum form of air control (up to 30 units of velocity, which is<br>about 1/10 of run speed). That turns out to be the problem.

Observe what happens to a player who is moving forward through the air and<br>presses left strafe. That results in a wishdir perpendicular to the current<br>velocity.

wishspd is clamped to 30

The DotProduct evaluates to 0 (perpendicular vectors)

addspeed is 30

wishdir is scaled by some factor accelspeed and added to the velocity

The scaling in step 4 matters less, since the same thing repeats in each<br>frame, until the dot product becomes 30 and the velocity has<br>reached a new steady state.

In the following picture, v is the initial velocity, w is the<br>desired velocity clamped to 30, and v' is<br>the final velocity. Note how |v|' > |v|. In other words, we're accelerating.

That's a small amount of acceleration. But if the player now adjusts viewing<br>angle in the direction of v', the move can be repeated. In practice it<br>is easy to do - just hold down the left strafe button while you slide the<br>mouse left. Keep doing this and keep building up more speed.

This explains two of the three physics quirks. The last one is about avoiding ground<br>friction. In the original version of Quake, speed jumping didn't really work<br>because even if you could stay in the air 99% of the time by jumping<br>continuously, there would be a very<br>short time between jumps (a single frame) where ground friction would be<br>applied, and that slowed you down far more than whatever speed you could gain<br>from the strafe-turning.

An Update

But the original game wasn't playable over the Internet. It ran the ancient<br>IPX protocol and was optimized for low latency LAN play. A new version came<br>out that added Internet Protocol support. But the Internet is not a LAN.<br>Latencies tend to vary a lot, and gameplay would suffer as a result -<br>when latency goes up, the player moves as if drunk. So the Internet version<br>also included player prediction, a feature meant to reduce the<br>perceived latency of a network connection, and a fascinating<br>topic of it's own.

Now, player prediction was a major change. The Quake client was designed as a<br>dumb terminal. It would record user input, pass it to the server, receive<br>updated positions and draw the world. With prediction, the client takes the<br>latest known state of...

velocity speed game player jumping addspeed

Related Articles