Last server records
IN_DUCKbit is set and reset the same way as
IN_JUMP, except that instead of the commands +jump and –jump its state is determined by +duck and –duck. In addition to it, several other variables appear in PM_Duck, describing the state of the player. For example,
trueduring the process of ducking. As soon as the player is in a sitting position, the flag
FL_DUCKINGis set in the variable
pmove->flags, and the variable
pmove->usehullbecomes 1, which means changing the physical size of the model. To better understand the relationship of these parameters, we are going to consider several situations.
Ducking and Unducking
Standing on a flat surface, we press the duck button, thereby sending the command +duck. In the same frame the
IN_DUCKbit is set in
pmove->cmd.buttons, and the variable
true. During the next 0.4 seconds (40 frames at 100 fps) the eyes level will be lowered, and the vertical coordinate the player's center
pmove->originwill remain unchanged. And only after this time has elapsed, the player’s origin will move down by 18 units, the model will switch to a sitting position, the
FL_DUCKINGflag will be set, and
Staying in a sitting position, we begin to move forward. The article about strafe physics suggests that holding down the W key gives
pmove->cmd.forwardmove = 250, so that inside the
PM_Duckfunction we get
pmove->cmd.forwardmove = 250 * 0.333 = 83.25unit/s (about 3 times less). This is the speed we are moving in duck with.
When we release the duck button sending –duck command, PM_UnDuck function is called:
Here the engine tries with the help of the trace to move us 18 units up, firstly in a sitting position, and then in a standing one. If successful, along with the change of our origin we have the eyes level lifted abruptly, the flag
FL_DUCKINGand the variable
pmove->usehullare reset, and
In the air ducking happens in one frame, during which
trueand back to
false, the eyes level changes from 17 to 12 units above the origin, while there is no downward movement by 18 units. The transition to a standing position also takes place in one frame and without lifting by 18 units.
Decreasing the variables
pmove->cmd.sidemovein a sitting position reduces the gain of the velocity vector (recall the functions PM_AirMove and PM_AirAccelerate, which we discussed in the article about strafe physics), so it becomes more difficult to get more speed or even simply change its direction in the air. At that in order to obtain the greatest gain, the mouse will have to be driven more smoothly than in a standing position.
Now we can understand how stand-up bhop works. In flight we press the duck switching into a sitting position in one frame. As we have just found out, in this position it becomes more difficult to pick up speed. Approaching the ground we release the duck, thereby calling PM_UnDuck. With the help of the trace it checks if the model is stuck somewhere when you switch it into a standing position. While we are near the ground, the stuck is guaranteed, so after the trace PM_UnDuck does nothing. The flag
FL_DUCKINGis not reset, the speed is still gained with difficulty.
When we finally find ourselves on the ground, the trace comes to a point that is 18 units above the player’s origin (that is, the function checks to see if something will prevent us from standing up). If we were in the tunnel, then we would not be able to get up, and we would have done the usual bhop in a duck. However, if nothing gets in the way, and we will immediately stand up. Regardless of whether we jump into the same frame or later, PM_Jump will be called after PM_Duck, so the jump will occur from a standing position, as if there was no sitting. Actually it is acceptable to release the duck button right on the ground, the main thing is that this should happen no later than the frame with the jump command. But of cours, it is safer to do this a little in advance cause it does not affect physics anyway.
While on the ground, we try to make scroll duck. From the point of view of the engine, this will look as the command +duck;-duck, which will lead to setting the
IN_DUCKbit in the
pmove->cmd.buttonsvariable, so the process of ducking will begin in PM_Duck, the eyes level will go down a little. If we were running at a speed of
v, then, according to the article about strafe physics, a call of PM_Friction would take away 4% of
v, and PM_Accelerate would not give any gain (since
addspeed = wishspeed - currentspeed = v * 0.333 - (v - v * 0.04) <0). For example, when running forward with W the speed would decrease from 250 to 240 units/s.
At the next frame, the
IN_DUCKbit is already zeroed, so the function PM_UnDuck is called, which throws us 18 units up. It turns out that instead of ducking we did something like a small jump. And the most remarkable thing about this mini-jump is that it does not affect the variable
fuser2, which was discussed in the article about the bhop physics. Thanks to this, CS gives us some interesting tricks:
1) double duck
You can climb stair of 18 units high or below without additional actions, while higher stairs will require a jump. According to the estimate of the jump height at zero
fuser2given in the article about bhop physics, we can jump onto boxes up to 45 units high (and subsequent duck increases this value to
45 + 18 = 63units). After jumping on the box
fuser2will be greater than zero, which will slow down our futher movement.
However, if instead of a jump we make a scroll duck, and then hold down the duck key, this will allow us to climb obstacles up to 35 units high without affecting
fuser2! In other words, climbing along such stairs can be accomplished almost without loss of speed (except for 4% taken away by PM_Friction). This technique is called double duck (or simply dd), although in practice scroll duck is also called dd.
2) landing with dd
If in flight we gained a high enough speed, then after landing, PM_Friction will start to cut it pretty quickly. We can weaken this process if, once on the ground, we do dd. This will "transfer" some frames to the air, where PM_Friction cannot do anything to us. Depending on the situation, under dd you can mean a scroll duck paired with a regular duck, a single scroll duck or a series of scroll ducks done in a row (note that too fast scrolling makes no sense in such a situation, since commands will “stick together” and give the effect of a regular squat).
3) CountJump and DoubleCountJump
When running on a flat surface, the scroll duck lifts us into the air by 18 units, after which we fall about 0.21 seconds (21 frames at 100 fps). In this short time we can not only compensate losses from calling PM_Friction, but also gain additional speed with the help of strafes. If you make a jump immediately after landing, then on the one hand, due to zero
fuser2, it will be as long and high as LongJump, and on the other hand, the horizontal speed after it can reach 299.973 units/s, as we found out in the article about bhop physics. This combination not only gives a significant increase in the distance, but allows you to effectively deal with the edgefriction described in the article about HighJump physics. This technique received its name CountJump in honor of the Count who discovered it.
download demo 270_cj_FAME
In practice, even with a good acceleration before the scroll duck, it's very hard to reach a speed of almost 300 units/s during 21 frames, so the idea was to make the scroll duck and gain the speed in the air twice. As you know, this technique was called DoubleCountJump. If strafe after each of the scroll ducks is made at the same direction, then prestrafe and air strafes are made in opposite directions, so this is called 180° DoubleCountJump.
download demo 272_dcj_mF^
This is how the first dcj records were done, but in practice it is quite difficult to find a map where the use of 180° dcj would make sense. It turned out to be more useful to do Straight DoubleCountJump, when you change the direction of strafe on the second scroll duck, so that the prestrafe and air strafes are made in the same direction.
download demo 273_dcj_DeathClaw
It is also worth noting that a similar physics at the moment of the jump (and therefore a potential distance) can be obtained with the help of other techniques. It is enough for this that
fuser2is zero i. e. the previous jump was made earlier than 1.31 seconds ago. For example, DropBhop with a long enough drop or WeirdJump fit this description.
Before jumping you can do not just one or two, but any number of dds (here by dd we mean jumping with a scroll duck and subsequent staying in the air). However, maintaining speed while doing dds is not so easy. If you make a scroll duck not at the first frame on the ground, but later, then PM_Friction will inevitably take from you even more speed. Of course, as in the case of bhop, you can send several commands at once by scrolling, but then you need to be prepared for the fact that there will be less time for returning the used finger to its original position.
In addition to the late scroll duck, too early one may dangerous too. Indeed, if the scroll duck was made one frame before we land on the ground, then PM_UnDuck called at the next frame would find that the model would get stuck in the ground, which means that model should remain in a sitting position. And then we, just like during stand-up bhop, will continue to fall to the ground in a duck.
Before moving on, let's say a few words about terminology. The dd series is usually called dd run. There was also a suggestion to call it GroundStrafe (or just gs or gstrafe). If we make a jump at the end of dd run, then we get MultiCountJump. In addition to these names, you can meet the term sgs, which stands for Stand-Up GroundStrafe. Often the concepts of gs and sgs are mixed, however, generally speaking, they are different techniques. With sgs you do full double ducks, i. e. alternate scroll ducks on the ground and squats in the air. It gives the same effect with falling to the ground in a duck, which was described above, but here it happens intentionally. As in the case of stand-up bhop, ducking makes it difficult to pick up speed, but allows you not to touch the ground for longer. But actually sgs has one important feature - after landing you need at least one frame to get up, and only after it you can do a scroll duck. That is, we touch the ground less often than with gs, but spend more time on it. From this we can conclude that sgs may be more practical than gs at high horizontal speeds or in the case of a specific relief.
As an example we can take the map smk_hnseu_airstrafes. Korean guy LeblE in his demo (download) used gs, while Romanian jumper brokoly showed a run with sgs (download). Also we cannot ignore a special way of performing dd run by prize, who instead of separate scrollings did one movement of his hand over the scroll from the tip of his finger to almost the elbow (download).
In general, dd run can be used instead of normal running or fastrun, but maintaining a high enough speed (at least more than 250-260 units/s) will require a lot of training. At the same time, the top speed is not limited to 300 units/s, although it will not greatly exceed this value unless using sv_airaccelerate 100, which, although used on some servers, is illegal (as we recall from the strafe physics, by default cvar sv_airaccelerate is set to 10). Our friend rawe agreed to show the usual dd run on the standard map de_nuke (download).
Everyone knows that DoubleCountJump can give us prestrafe of more than 300 units/s, but what about CountJump? In the article about strafe physics we found that to maintain optimal angle
u(that maximizes the speed) we need to move our mouse about 5 degrees per frame. That is for one 21-frame dd the turn is 105 degrees. Also in the article about LongJump physics we learned that speed at that is changing like
Vnew = sqrt(V^2 + 875). If we take 277 units/s as maximum prestrafe before dd, plus take into account 4% taken away by PM_Friction (which leaves us 265.92 units/s), than after 21 frames we reach 298.48 units/s - this is approximate value of maximum CountJump prestrafe. For comparison FAME on his 270 block had 263.89 units/s before dd and 293.25 unit/s at the moment of jump.
But what if we use Stand-Up CountJump, i.e. CountJump with duck at the end of dd, which gives us 9 more frames in air? With pressed duck in PM_AirAccelerate we find that
wishspeed = 250 * 0.333, so the optimal angle
u = arccos(8.325 / V), from where reproducing calculations from the article about LongJump physics we obtain the formula for speed change:
Vnew = sqrt(V^2 + 830.69). Supposing we've spent in air 20 frames without duck and 10 frames with duck, we come to more than 310 unit's at the moment of jump which is more then 300 with big reserve.
And one more interesting estimation. If we could maintain optimal
uduring gstrafe (recall that we also need to switch strafes to avoid spinning on one spot, which makes this example absolutely unreal), than we would reach 464 units/s - starting from this speed all gain of one dd is taken away by PM_Friction.
Duck in confined places
Since the height of the model in the standing position is 72 units, the minimum height of the tunnel in which we can walk is 73 units. The sitting height is two times less, so in this case the minimum height of the tunnel will be 37 units. If we sit down and try to jump in a tunnel with a height of 73 units, then we will definitely hit the ceiling with our head, since the jump height at zero
fuser2is 45 units (
36 + 45 = 81 > 73). Interestingly, in the same tunnel we can jump from a standing position if we hold the duck in advance. Indeed, as we found out earlier, after setting the
IN_DUCKbit, we have 0.4 seconds, during which the center of the model will remain at the same height. If at this time we make the jump, then after calling PM_Jump we will be in the air, and right at the next frame without hitting our head we will switch to a sitting position in PM_Duck. Sadly, we will not fly long, because up to the ceiling there will be only
73 - 36 - 18 = 19units left. Nevertheless, this reserve gives us the ability to jump out from under the overhang, which turns out to be very useful on kz maps.
And now let us ask ourselves a question - what will happen if we make a scroll duck standing in a tunnel? The tunnel with a height of 91 units and above will not create problems for us, but at a height of 73 to 90 units we will get into a tough situation: first, PM_Duck will start ducking, setting the variable
true, and at the next frame PM_UnDuck will find that it is not possible to raise the model by 18 units upwards, so
true. In subsequent calls, PM_Duck will think that we are in the process of ducking, and therefore slow us down. At that the slowdown will not disappear until we press the duck button and completely sit down. You can also simply “crawl out” of the tunnel, then PM_UnDuck will finally throw us 18 units up, setting
Duck will be also important to us in the next article dedicated to EdgeBug and JumpBug.