This is More than Mashing, a column on amazing demonstrations of skill in video games where I try to collect and showcase the best the net has to offer in skilled game playing and break it down so anyone can understand. This week I’m looking at “too much for zblock” by phoon.
This video is just a great demonstration of how crazy you can be when you have an absolute mastery of Bunny Hopping in Counter Strike: Source. Bunny Hopping, or Bhopping, is a classic FPS movement technique; originating all the way back in Quake 1 as a result of how the velocity system was coded. The GoldSrc and Source engines, both of which Valve uses for all their games, were based on the Quake engine and thus carried over these old velocity systems and the exploits that came with them. Valve actually patched out a bunch of the original things that allowed Strafe Jumping in the Quake source, such as adding a server variable that limits the amount that a player can accelerate in the air. They also made it so if you press jump in the air, you won’t jump the instant you hit the ground.
In all first person shooters related to the Quake engine, when you are in the air, you still have limited control over where you are going. When you press a button in midair, you move in that direction. When you are moving on the ground and then jump, you keep your ground speed. Unlike the ground, there is no friction in the air, so if you have velocity in the air, it is sustained until you are brought to a halt. This means if you jump exactly each time you land, you can keep your speed without friction getting in the way. Back in the original Quake, this technique was first called Zigzagging, because players would do a zigzag motion along the ground. When they realized you could jump to avoid friction, it became known as circle jumping and eventually bunnyhopping.
The Quake engine handles movement by generating velocity acceleration “impulses” in the direction the player is currently pointing and pressing (the direction they wish to go, called wishdir in the code). When you turn, it starts turning the direction these impulses are generated. By generating new impulses in this way your movement direction changes by simply adding together the old movement vector with the new impulse vectors until the vector is pointing in the intended direction, causing a quick but smooth shift in movement direction.
However if the engine simply generated impulses to move forward constantly when W is held, you’d rapidly accelerate forward. Instead the engine limits your speed with a max velocity variable that is server defined. Where it gets funny is the way the game checks whether you’re going over the max velocity and how it limits your velocity when it’s going over the max. Instead of simply checking whether your current velocity plus the acceleration impulse to be applied is over the maximum velocity, it instead checks whether the vector projection of the current velocity onto the direction you wish to go, plus the acceleration impulse, is greater than the maximum velocity. If the vector projection plus the acceleration are greater than the maximum velocity, then it will subtract from the acceleration until it’s under the maximum velocity. Then here’s the funny part: Once it’s done that, it adds the acceleration impulse to the current velocity vector. This is funny because the two vectors added together might have a greater combined speed than the max velocity variable. It’s not checking whether the final result of the vector addition is greater than the maximum velocity, it’s only checking a reduced form of the current velocity and acceleration.
This means that if you’re going straight forward and hit the maximum velocity, then the current velocity exactly lines up with the wish direction, so the projection is exactly equal to the current velocity and the acceleration impulse is entirely subtracted, resulting in no acceleration forwards, you just keep moving at the maximum velocity. If you decide to change directions, it means you keep moving a bit in the direction you were already going, but rapidly begin to move in the wish direction until you’re entirely moving in that direction. It is possible in normal turns on the ground to exceed the maximum velocity, but friction usually handles that until you steady out going in one direction.
So why does Bunnyhopping require such smooth motion? The idea is to turn the mouse enough each frame that the vector projection of your current velocity is small enough to allow the most acceleration possible, without turning it so much that there is additional space to go before hitting the maximum velocity. optimally, the projection of the current velocity plus the acceleration are exactly equal to the maximum velocity. If you turn it less than the optimal amount, you won’t gain as much speed because the acceleration vector will be made smaller by the maximum velocity limitation. If you turn it more than the optimal amount, you’ll get the full acceleration vector possible, but it will be directed off into a less useful direction. The closer to parallel the acceleration vector and the current speed vector are, the greater their sum will be when added together. If you turn too much, then you’ll begin directing acceleration vectors off away from the direction the current velocity is going, which will actually result in losing speed.
What is very important to remember is that in the Source engine pressing or holding jump will not cause you to jump when you hit the ground unlike the Quake engine. Because of this, if you don’t hit jump EXACTLY when you hit the ground, you get hit with friction from the ground and lose velocity. To combat this, Counter Strike players use a couple clever tricks with the way they set up their controls. They set the mouse wheel’s scroll up or down to trigger the jump. This means they can spin the mouse wheel to trigger the jump input many times in rapid succession. This is made easier with free scroll mice or by removing the binder that makes the mousewheel click as it spins. The less accepted method of spamming jump is using source engine scripts that repeat your jump inputs when you hold the spacebar. Anti-cheat scripts on the servers, like Z-block typically ban these, they’re considered unfair.
No matter how great a player is maintaining velocity in Counter Strike is tricky work. It’s almost impossible to jump exactly when the ground is hit each time, so a bit gets lost to friction for the brief time the ground is touched. In the video at the top, phoon uses the mouse scroll trick, but even he can’t hit every jump perfectly. In order to maintain speed, he has to keep building up speed so that even if he takes a bit of friction, he has an excess of acceleration and velocity so it doesn’t throw him off completely. A lot of people call him a hacker or scripter, but a fully automated script wouldn’t vary Bunny Hop methods like he does, or have the mouse move different distances at inconsistent speeds. He does both smooth turns and pulling the mouse back so he only has to strafe on one side. Similarly, if he were scripting to just auto-jump, he wouldn’t need to do all the mouse movements he does and could maintain velocity with much less movement. Additionally, in the demo (a recording of someone playing) he wouldn’t be hitting the ground at varying heights and for varying times. Despite this, he has attracted no less accusations of cheating, though all my research indicates that he did in fact play legitimately.
One of the key characteristics of Counter Strike, unlike games such as Quake, is the slow pace and loud footsteps. Counter Strike was designed to be a very careful game where you could figure out when enemies were near, move slower to sneak up on them, and generally keep control of the action with good attention. However Bunny Hopping completely destroys this design choice. It’s so difficult as to be massively impractical, but phoon clearly pulls it off. The result of this is that he can be in places far ahead of when he should be, pulling off assaults from otherwise impossible directions. In a normal game, there is a certain flow. Over time, the enemy team can only really be in so many places because they only move so fast. Counter Strike was designed around allowing players to vary their assault between multiple possible routes, but the ability to jump so fast and far through the air enables phoon to reach rooftops otherwise restricted and ambush the enemy team from impossible angles. On top of that, he doesn’t make much sound due to being in the air all the time, which is perfect for sneaking up on people.
Another thing worth mentioning is that phoon has absolutely crazy aim. Those deagle headshots are just awesome. Doing that and keeping up bunnyhop momentum is insanely hard. This is further accented by the clip at 2:00 where he gets hit with a flashbang and still manages some headshots on the sniper rifle, the first being a double headshot no less. All throughout the video are some pretty excellent examples of great reflexes and quick thinking. You’d think that his opponents would learn to check their backs just a little more often.
On a sad note, Counter Strike Source and its successor CS:GO both have locked the sv_airacclerate variable to 0. When Valve realized that Bunny Hopping was still possible in their games, they implemented a simple check for air acceleration. It compares your velocity on the current tick (like a frame, but for servers, the image of where everything is at a current point in time) versus your velocity on the last tick, and if you have accelerated greater than what the sv_airaccelerate variable is set to, your acceleration will be limited to what the variable is currently set to. A setting of 0 is now the norm for all Source games since the Orange Box, whereas Counter Strike: Source allowed higher values by default. Now that it has been locked to 0, acceleration in the air is impossible, and all we really see of the old strafing methods is air strafing off rocket jumps or sticky jumps in TF2, which allows the player to control their trajectory a little, but that is all. It’s unlikely that we’ll ever see such a beautiful destruction of a competitive game like Counter Strike anywhere in the near future.
See you next time!
You can find a more detailed explanation, with diagrams, here.