## LongJump physics

Posted by Kpoluk 4 Jan 2019 in 09:25
In strafe physics article we used the following concepts: current velocity, view direction, `wishdir`, angle `u` bewteen current velocity and `wishdir`. Since it's quite difficult to describe such a dynamic process as lj using only static pictures, let's look at them in motion. GIF 31.01MB

This animation schematically shows an lj made on kz_longjumps2 and consisting of prestrafe and five strafes. Movement trajectory is an organge curve on the ground and yellow curve in air. Green vector defines `wishdir` direction, white is view direction, red is velocity direction. Angle `u` is an angle between green and red vectors.

Let's follow how the angle `u` changes. While we are running with W, it is zero. Then, when we picked up the speed of about 250 units/sec, we press A. As it was clarified in the article about the strafe physics, at the first frame after pressing A the vector `wishdir` will turn 26.565 degrees, and then it will become equal to 45 degrees. During the prestrafe angle `u` decreases from 45 to a certain value, at which we would not lose speed at the moment before the jump. For 275-277 units/s this angle is about 27 degrees. Therefore the angle between the velocity and view direction before the jump will be about `45 - 27 = 18` degrees.

At the moment of the jump we release W and `wishdir` is now 90 degrees with the view direction. Strafe physics tells us that the optimal angle `u`, which will give us the maximum speed increase, should be as close as possible to the value 88.96 at the beginning of the jump. However, if we tried to perform the prestrafe perfectly, then the angle `u` at the first frame in the air will be approximately `90 - 18 = 72` degrees i. e. we will need to turn the mouse as soon as possible towards the velocity vector so that it starts to grow. Later at the moment of switching from one strafe to another, everything is also not as smooth as we would like it to be. The vector `wishdir` jumps on the other side of view direction, and if the angle `u` we tried to maintain was 88.96 before, then after switching it will be `90 + (90 - 88.96) = 91.04` degrees. To get back to the optimal angle again, we need the view direction to be moved to the other side of the velocity vector during one frame, and the mouse to instantly change the movement direction to the opposite.

Physiologically it is extremely difficult to perform such a trick, therefore, in practice, it happens approximately as shown in the animation at the beginning of the article: the white vector of the view direction overtakes the red velocity vector (that is, we increase the angle `u` in advance), and after strafe switch it gives time to the red velocity vector to turn, and then we accelerate the mouse, and the white vector again starts chasing the red one.

And now let's combine the 3D graphics from the article about strafe physics into one. In this we will be interested in the speed from 250 to 340 units/sec, and the angle `u` will change from 110 to -110 (positive for the left strafe and negative for the right, for negative values of ​​`u` we can just mirror previously obtained graphs): During the prestrafe at a speed of 250 units/sec our `u` angle is close to 45 degrees, and the speed gain is somewhere near zero (yellow area). Then the angle decreases, we rise on the graph to the orange zone and, since our speed grows, we begin to move towards the plateau. When approaching the plateau, we make sure that `u` does not decrease too much, otherwise we will fall into the pit, where we will drastically lose speed. Then, in the air, we alternately sit on one orange knoll, then on another, continuing to move in the direction of speed increase. In case of failed strafe switch we can be either on a yellow plateau without speed gain or in a pit, where speed is lost.

And here an interesting idea pops up - what if while running with W and before pressing A we turn right? After pressing the A key, the `u` angle will be less than 45, that is, on the graph we will be in the orange-red zone from the very beginning! In this case, the speed gain will come faster, and the arc of the prestrafe will be less. This is convenient on maps like prochallenge_longjump, where lj blocks go one after another, so the less time you spend on the prestrafe, the faster the record will be. Anyway many lj geeks use this technique on kz_longjumps2 as well.

### World record

Let's move from theory to real jumps and look at the animation, built on data from the demo, where DeathClaw jumped 257 lj block (which currently is a world record, you can download it here): GIF 6.81MB

In the upper left corner `v` is the speed in units/sec, `u` is the angle in degrees between the green and red vectors (colors are the same as in the animation at the beginning of the article). You can also see on the left what buttons DeathClaw presses and how the speed changes (the brighter the green is, the bigger the gain, the brighter the red, the greater the loss, also you can see gray color at the beginning and at the end of the jump - speed did not change there). Playback is slowed down 20 times.

You can clearly see how DeathClaw moves the mouse to the right during the prestrafe, then presses A and, since the angle `u` turned out to be less than 45 degrees, quickly reaches 265 units/sec. Then the angle `u` grows (otherwise DeathClaw would have fallen into the pit, which we saw on 3D graphics). At some point, the speed exceeds 276 units/sec, but the angle `u` is too large (about 33 degrees), and speed is slightly lost before the jump. After the jump DeathClaw still holds W, so his first frame in air has constant speed and painted gray in animation. What is interesting, if DeathClaw released W earlier, he still wouldn't get any speed cause he wouldn't reach that knoll on 3D graph where gain is possible. And if DeathClw didn't increase `u` before the jump, there could be two or more gray frames after the jump. So the prestrafe speed greater than 275 units/s is not necessarily a good thing. For example, FreestyleR on the same 257 block had 276.28 units/s and `u = 30.85` before the jump, while after the jump he had `u = 33.32` at first frame (he was holding W as well) and `u = 82.72` at second frame, which is not enough to reach gain range, so he had two gray frames at the beginning of first strafe.

Strafe switch is also not much different from our prediction - while the mouse is slowing down, the red velocity vector is on the other side of the white vector DeathClaw looks along. Then the mouse accelerates, the white vector catches up with red, and the speed gain gradually rises, occasionally falling into loss. On 3D graph these losses look like a slide from an orange knoll into a blue pit.

### Maximum distance

Until now we've stuck to optimal angle `u` just because it gave us the maximum speed gain. Since every frame speed has the hightest possible value, the lenght of the trajectory will be longest. But lj distance is not trajectory's length, but a distance between jump and land points. How good is optimal `u` for achieving maximum distance? To understand we need learn how to gauge jump's distance by given `u`. First recall the vector addition that modifies velocity: Here `V` is a current velocity, `dV` - gain at the current frame, `Vnew` - resulting velocity. Generalizng results from the article about strafe physics obtained for `V = 275`, we can claim that speed gain starts at `u > arccos(30 / V)` and reaches the maximum at optimal `u = arccos(5 / V)`. For this angles range we can write:

`dV = wishspeed - currentspeed = 30 - V * cos(u)`

From cosine law

`Vnew^2 = V^2 + dV^2 - 2* V * dV * cos(180 - u)`

Substitue here `dV`:

```Vnew^2 = V^2 - V^2 * cos(u)^2 + 900 Vnew = sqrt(V^2 * sin(u)^2 + 900)```

This result will be utilized in the article about slide physics. For now we can see from it that maximum `Vnew` is indeed at `u = arccos(5 / V)`: at fixed `V` with growth of `u` we have increase of `sin(u)`, therefore `Vnew` grows too, running up to

`Vnew = sqrt(V^2 + 875)`

As we remember from PM_AirAccelerate function, for `u > arccos(5 / V)` we get `dV = 25`, and speed increase continues right until `u`, at which `Vnew = V`. Applying cosine law: `V^2 = V^2 + 25^2 - 2 * V * 25 * cos(180 - u)`, hence `u = arccos(-12.5 / V)`, which is a bit more than 90 degrees at `V > 250` units/s.

Let's calculate concrete values of `u` for a set of speeds: Note: there are servers in kreedz that have sv_airaccelerate changed from 10 to 100. In term of function PM_AirAccelerate it means that at `wishspd = 250` we get `accelspeed = 250 > 30`, so speed gain keeps growing until `u = 90°`, while maximum angle `u = arccos(-15 / V)`. Thus the range of `u` with positive gain is wider and maximum gain is higher. It can give you a few additional units on lj, while on slide effect is Just immence (we will learn how speed can be gained on slide in a separate article). Another interesting thing is that actually it's enough to use sv_airaccelerate 12 to reach such effect (at this value `accelspeed = 30`), further growth of it won't affect game physics.

Awesome, now we know how speed is changing during the jump. Strafe physics showed that for maintaining optimal `u` we need to turn mouse by 5 degrees every frame. At that we also know that standard lj is 73 frames long. Supposing we've fixed prestrafe and number of strafes, we can find the direction of velocity at every frame. Then by integrating the projection of velocity on jump's direction (let's denote it as `Vx`) we obtain desired distance.

Note. Futher examples take into account that frame when new button was pressed has `wishspeed` equal to 200, not 250 (see article about strafe physics), optimal `u = arccos(10 / V)`, speed is calculated as `Vnew = sqrt(V^2 + 800)` and required angle of mouse turn is 4, not 5 degrees.

1) Let's take 275 units/s and 4 similar strafes each 18 frames long. Width of strafes will be about 90 degrees (45 to the right and 45 to the left), i.e. jump trajectory will be very winding. New we can find `Vx` using derived formulas and depict it on graph: Here is also `Vx` for 257 block by DeathClaw. The graph illustrates that the most part of strafe speed growth, then descreases (DeachClaw has this tendency too, hence it's normal). A few times our `Vx` is even more than DeathClaw's one, it happens at moments when velocity has the same direction as the whole jump, i.e. when `Vx = V`. Actually this is not a big surprise cause we used optimal `u` that maximazid the speed. But what about the distance? To find it we need to integrate `Vx`, in other words find the area under the graph. Our 4-strafe jump gives us 240.88 units, so the conclusion is that optimal `u` wasn't very useful. For justice we could start with the same `Vx` as DeathClaw had and get 241.47 units, but it's not much better. Another trick is to release all buttons at the moment when last strafe has the maximum `Vx`, so its value would be the same until the end of the jump. The result would be 244.10 units, but this is still not the best distance for 4 strafes.

2) What if we try to emulate DeathClaw's strafes but with optimal `u`? We take his prestrafe 275.23 units/s, 8 strafes with fitting their length (9-10 frames), and the same first `Vx` (271.09 units/s). Estimated width of our strafes will be 40 degrees (actually 38 cause first and last frames of each strafe are 4 degrees wide), whereas DeathClaw's width is reducing from 30 to 22 degrees during the flight. Compare `V` on the graph: This time our distance is 263.45 units (if we release buttons at peak of the last strafe, then 263.83). Same calculation based on `Vx` for DeathClaw gives us 257.234 units. This is not his real distance cause he was in air not 73 frames, but also a part of 74th frame, which added him 0.7795 units. We'll learn how he did it after the article about Edgebug and Jumpbug.

Thus our 8 unhuman strafes surpassed world record with a big reserve. We could achieve even more shocking results with 18 strafes, but instead we'll get more utility from more realistic situation.

3) Look at how angle `u` behaved in previous case: For our lj we take first strafe of DeathClaw and 8 more strafes, each 8 frames long and 28 degrees wide. Behavior of `u` for these strafes will be taken from the best DeathClaw's strafe (I think it's fifth). If we find `Vx` on each strafe and calculate the distance, we get 258.226 units. Summing it up with an addition of 74th frame, we can get more than 259 units. It means that 259 block is somewhere near the limit of human abilites. As it's said in kreedz, impossible but very very hard.

### Practice

For calculating the distance we used identical simmetric strafes. However we don't have to do it - we could start with fast 8-frames strafes and switch to 12-frames strafes, or alternate them breaking symmetry. As for passing kz maps, there is no need to always perform maximum distance, often it's enough to land at certain point to start running from it or to do bhop on it. In that case variety of strafe styles becomes huge, and this is a salt of kreedz.

Despite a lot of possibilities doing lj in practice is not that easy. As we've seen above changing the direction of mouse movement should happen 1-2 frames later than switching strafe button. At this moment one of unpleasant situations may happen:

1) If mouse movement delay is more, then beginning of strafe has frames when red vector of speed stays idle, waiting for approach of white vector. When white vector is close, they both start to turn together. At some strafe red vector won't turn enough and white vector outrun it giving us speed losses.

2) Same effect may happen when we press new button while old one is not released yet. If this overlap lasts more than one frame, we have zero speed gain, i.e. red vector becomes static like in first case. And regadless of view direction we won't have any speed gain until old button is still held.

3) If mouse movement is too slow or its direction change is too early, than at the beginning of next strafe red vector will need a few frames to outrun white vector, and this is how we face speed loss at strafe start

All these mistakes amplify each other and influence futher strafes. Often player who can jump 250-253 units is confused how hard for him is to reach at least 255. Detailed analysis shows that he constantly makes mentioned mistakes and together they take away these few units. Let's examing as an instance my 250 block with 6 strafes (you can download it here): GIF 5.90MB

Here I have the whole collection: first and second frames have overlaps in button presses (gray region with constant speed); on the third frame I was moving mouse too slow and it led to speed loss at the beginning of the forth strafe; button of fifth strafe was pressed too early, during the half of its length red vector waited for white one to approach it. The last strafe is barely useful with trifling gain.

Thus we come to a conclusion that the better is strafe switching the easier for you to pass kz maps and the lower chance that your strafes will fall into pieces after a short break. That's why newbies are given advices to start with a few strafes, gradually inscreasing their amount. Here's an example of how to do it. Let's say player can do 4 strafes 18 frames each. With time he does first three strafes faster until they become 14-15 frames long. Then he just need to break the last strafe into two, and now he has 5 identical strafes.

In the next article we will deal with the Highjump technique and learn more about the friction in CS.