Before we dig into slide theme let's examine too related techniques –
WallRun and
WallSlide.
WallRun
In the article about strafe physics we found that if you run with
W than periodic pressing of strafe button for 15-30 frames leads to oscillation of speed in range of 249-262 units/s. Trajectory won't be linear, but on the average you move faster this way, that's why it's called
FastRun.
But this is not the only way to run faster on the ground without ducks and bhops. When you run along the wall with pressed
W and start to turn towards it you can notice that your speed is more then 250 units/s. This technique is called
WallRun. Under the hood we have the same effect as we had during lj prestrafe. The only difference is that each frame velocity
Vnew
, which was received as addition of current velocity
V
and increment
dV
, is projected onto the plane of wall, thanks to
PM_ClipVelocity, that we faced in the article about EdgeBug and JumpBug:
Here the wall is located on the right and vector
dV
has direction of our view cause we pressed only
W. Unlike running without wall we don't have to turn our mouse all the time trying to keep a certain angle between line of view and velocity, cause velocity is always directed along the wall. If we recall 3D graph of speed gain depending on angle
u
we find ourslef on the edge of pit starting from 250 units/s. Now let's increase angle
u
between
dV
and velocity
V
i.e. turn more towards the wall. Then on 3D graph we crawl along the edge of the pit, moving to the area of higher speed and larger angle
u
. The wall doesn't allows us to fall into the pit, and we safely reach 277 units/s at angle
u
about 27°:
Unfortunately futher magnification of
u
forces us to descend into the area of lower speed, but reaching the maximum prestrafe with so little effort is really astonishing.
Of course we can have the same result not with
W only. For instance, simultaneously pressed
W and
D give the same direction of
dV
if we look 45° to the left than just with
W.
WallSlide
This technique is also known as
kkz jump by the nick of
koukouz who actively used it in his world records. Nevertheless it was used before as well. The difference from WallRun is that movement takes place in the air, so we should press
D instead of
W (we still suppose the wall is located to the right). At that velocity is still projected to the plane of the wall every frame, hence we don't have to do fast mouse movements as we did with regular air strafes. It's enough just to keep angle
u
in the range that gives speed gain. In the article about LongJump physics we learned that this range is from
u > arccos(30 / V)
to
u < arccos(-12.5 / V)
with maximum gain at
u = arccos(5 / V)
. In case of WallSlide we maximize not the velocity
Vnew
, but its projection to the wall plane
Vx = Vnew * cos(x)
, where
x
is the angle between
Vnew
and
V
:
Growth of
Vx
also starts at
u > arccos(30 / V)
, but stops already at
u = 90°
, which is clear from the picture. At
u
from
arccos(5 / V)
to 90° growth of
Vx
is still present, but goes down. Therefore optimal
u
that maximizes
Vx
is somewhere between
arccos(30 / V)
and
arccos(5 / V)
. We can find it with help of cosine theorem as we did before, but this time we write it relative to the angle
x
:
dV^2 = V^2 + Vnew^2 - 2 * V * Vnew * cos(x)
Substitute here results from the article about LongJump physics:
dV = 30 - V * cos(u)
and
Vnew^2 = V^2 * sin(u)^2 + 900
:
900 - 60 * V * cos(u) + V^2 * cos(u)^2 = V^2 + V^2 * sin(u)^2 + 900 - 2 * V * Vnew * cos(x)
Vx = Vnew * cos(x) = -V * cos(u)^2 + 30 * cos(u) + 1
Replacement
z = cos(u)
leads us to the funtion
Vx(z) = -V * z^2 + 30 * z + 1
, which has maximum at
z = 15 / V
, hence optimal angle
u = arccos(15 / V)
.
As we did for air strafes let's find some specific values of
u
for a set of speeds
V
:
Actually since we don't use strafes switching we could make all reasoning not for the angle
u
between
dV
and
V
, but for the angle between line of view and plane of the wall, which is
90 - u
. For example, at the speed of
V = 250
units/s maximum gain happens when we are turned
90 - 86.56 = 3.44°
from the wall. If we turn away more then
90 - 83.11 = 6.89°
our velocity won't change. Angles are so small that layman may say that player just looks along the wall, but now we know what happens in fact.
WallSlide is not just an alternative to the LongJump, but may be the only way to perform a jump. Representative situation is when you need to jump in a narrow long corridor that has no space for a winding trajectory of lj. As an example let's examine 2 jumps by
throttle from his demo on
prochallenge2_mix (you can download the demo
here). On the last climb stage throttle has 19:14 on timer and he's jumping 230 block, sandwitched between two walls. Width of model is 32 units, while the distance between walls is 36 units, so trying lj is very problematic there. That's why throttle uses right wall firstly for WallRun with
W and
D, and then for WallSlide with
D.
GIF 2.23MB
Note that he turned mouse to the right before the jump so in the air he's already in the range of
u
which gives a speed gain for WallSlide. Of course he paid with speed losses for it at the end of WallRun. During the flight throttle didn't take risks and kept mouse static, so angle
u
was remaining the same.
Literally 10 seconds later throttle does another jump which is way more harder. It's located above 230 block, so aperture is the same. However one cannot do WallRun here, so he had to jump around the corner and then cling to the right wall:
GIF 1.80MB
As we can see during the flight throttle by inertia touched the left wall first, which gave him a gray sector on the left chart (within these frames velocity vector didn't change either magnitude or direction). Next not yet touching the right wall he turned mouse to the left, so another gray sector here. And finally after touch he has stable speed gain with the help of WallSlide.
Another good example is Stand-Up CountJump in a narrow corridor on
qcg_to_chichin. Its mapper
Qicg recorded for us this jump (you can download demo
here).
GIF 3.68MB
The aperture here is just 34 units. Qicg also uses right wall, accelerates with
W and
D, then performs double duck with squat, releases duck right before landing, spends 6 frames on the ground, jumps and implements Wallslide with held
D. So many
FOG (frames on the ground) were made not by chance, it allowed to significantly diminish jumpoff, i.e. to jump closer to the edge of small block. At that with regular Stand-Up CountJump Qicg would lost a lot of speed on the ground, but here he preferred to turn mouse towards the right wall yet after double duck, so during 6 frames on the ground he actually continued to do WallRun, gaining the speed. With more FOG jumpoff would be even less, although then it would be difficult to call it Stand-Up CountJump.
And one more demonstration of active WallSlide use is a demo by
fykseN on
sn_beachcliff (you can download demo
here ). There are a lot of closely spaced blocks along the rocks, where WallSlide is useful both for single jumps and for bhop.
Slide
In the article about EdgeBug and JumpBug we learned from function
PM_CategorizePosition that slope becomes slide when tilt angle
a
is more then
arccos(0.7) = 45.573°
. Game engine processes slide as air movement, but unlike it was with WallSlide the gravity is very important element here. Funtions
PM_AddCorrectGravity and
PM_FixupGravityVelocity from the article about bhop physics showed that every frame the gravity subtracts from vertical speed 8 units/s. We will represent it as addition of vector
dVz
which is 8 units long and directed straight down. Resulting velocity will be found as a sum of current velocity
V
, vertical increment from gravity
dVz
and horizontal increment
dV
from function
PM_AirAccelerate. The remarkable thing is that magnitude of
dV
depends only on horizontal part of current velocity, so
dVz
(which is added in code before
dV
) doesn't affect it. After addition the resulting vector is projected onto the plane of slide by function
PM_ClipVelocity. Already here we can make an important conclusion that for slide it doesn't matter you look up or down, changing of velocity is entirely defined only by turning in horizontal plane, i.e. right-left.
Vertical movement
Let's begin from a simple case – come to the slide (not too steep) and start ascending with held
W (look straight towards the slide to avoid sideways movement):
At first speed is low, hence increment
dV
is at a peak of 25. If projection of
dV
onto the plane of slide is more then projection of
dVz
, then resulting speed increases. In fact it immediately gives us a condition under which the rise is possible:
dVz * sin(a) < dV * cos(a)
8 * sin(a) < 25 * cos(a)
a < arctg(25 / 8) = 72.255°
If
a >= 72.255°
we deal with so called
Steep Slide, where sliding down is inevitable. On the other hand on a regular slide our speed keeps growing and soon
dV
is calculated already as
30 - V * cos(a)
and starts to decline. As soon as
dV
is equal to
dVz * sin(a)
, changing of speed stops, and we will continue to crawl up the slide steadily. We could use another way – run and jump to the slide holding
W, then at first there won't be any speed increase, but soon it will reaching the value of
dVz * sin(a)
, and finally we will have the same constant speed while sliding up.
But can we slide up in duck? In the article about CountJump physics we found out that in duck variables
pmove->cmd.forwardmove
and
pmove->cmd.sidemove
are multiplied by 0.333, hence in
PM_AirAccelerate accelspeed = 10 * 0.01 * (250 * 0.333) * 1 = 8.325
, i.e. maximum increment
dV = 8.325
. It means that slide in duck possible at
a < arctg(8.325 / 8) = 46.141°
. And since slide starts at
a > 45.573°
, mapper should get into a range of less then 1°, that's why such slides are quite rare to meet. Anyhow, required angle may be not even on the slide itself, but at the junction of slides.
Here are representative sizes of slide blocks on some maps:
Be aware that on
b2j_slide_longjumps, which is a logical follow-up of
slide_gs_longjumps, block sizes are a bit different – the height of start platform is 257, not 256 units, which suggests that tilt angle is
a = 48.925°
. Similar situation happens on
qcg_longslides, which can be considered by block sizes as continuation of
slide_svn_longslides – horizontal dimension of slide here is 129, not 128 units, hence tilt angle is
a = 45.659°
.
Also notice that slide on
kz-endo_slide_svn_duckslides is placed 64 units above the ground. But we already know that maximum height we can jump on is 63 units! Strange right? We will solve this puzzle in the next article, while now let's move on.
Horizontal movement
Another special case is when we move along the slide holding
D
and having strictly horizontal velocity in the plane of slide:
Velocity
V
and increment
dV
lay in horizontal plane, while increment
dVz
is directed vertically down. We'll try to understand how real is to maintain this state without sliding up or down. In other words after addition of
V
,
dV
and
dVz
and projecting the result onto the slide plane we need to receive strictly horizontal velocity. Sounds difficult but if we split
dV
into two parts (along velocity
V
and perpendicular to it), then things clear up. Component along
V
will give an augment to horizontal velocity, while perpendicular component should balance
dVz
:
dVz * sin(a) = dV * sin(u) * cos(a)
In the range of
u
from
acrcos(5 / V)
to
90°
(i.e.
cos(u)
from
0
to
5 / V
) increment
dV = 25
, and this condition looks like
8 * tg(a) = 25 * sin(u)
After calculating
u
at various
а
we find out that condition
V < 5 / cos(u)
leads to limiting the speed down to 5-6 units/s. However since speed
V
constantly grows at
u < 90°
, we cannot maintain this state.
Thus
u
should be in the range from
acrcos(30 / V)
to
acrcos(5 / V)
, where increment
dV = 30 - V * cos(u)
. Substitute this increment into the balance condition:
8 * tg(a) = (30 - V * cos(u)) * sin(u)
We won't try to solve this equation for
u
, we'll just mention that along with growth of
V
angle
u
should be enlarged (means we should turn towards the slide little by little).
Turning towards slide
If during the horizontal movement along slide we start to turn mouse towards slide (angle of turning away from horizontal direction of slide will be denoted as
y
), then velocity will turn in the same direction, staying in slide plane:
Magnitude of
dV
still depends on angle
u
, which is still counted from horizontal component of velocity (violet vector on the picture), directed inside the slide block. It means that if we want to keep
dV
nonzero, we should continue to turn towards the slide in next frames, which is very similar to logic of air strafes.
In order to understand what's going on with velocity
V
we decompose it into two components in slide plane (dark red vectors on the picture). Also we decompose Increment
dV
in horizontal plane and thus we can see that one part of
dV
will slow down horizontal movement along the slide, while the other part will try to balance gravitional increment
dVz
. Unless angle
y
is too big we are slowing down in horizontal direction of slide and accelerate up the slide.
As an example examine the demo by
BuTaMuH on
b2j_slide_longjumps with 241 slide block (you can download it
here). Follow the change of horizontal speed and angle
u
from the moment of jump to the landing:
GIF 3.84MB
You can clearly see how red vector of horizontal velocity bounces at the moment of slide touch – the whole velocity is projected to the slide plane. After the touch BuTaMuH continues to turn mouse towards the slide increasing horizontal speed and slowing slide down at the same time. Thereby at the lowest point speed reaches 749.3 units/s. During slide up horizontal speed is steadily decreasing while vertical speed is growing, which can be seen on this graph:
Here we have gain of vertical speed starting from the lowest point and up to the last frame on the slide. The angle of turing towards the slide was changing from
y = 0°
to
y = 50°
. Taking the maximum increment
dV = 25
at
y = 0°
we find that gain of vertical speed is
dV * cos(y) * cos(a) * sin(a) = 25 * cos(0) * cos(48.925°) * sin(48.925°) = 7.84
units/s, while at
y = 50°
we have 4.53 units/s. In case of BuTaMuH one could already see from animation that angle
u
firstly deviated from
arccos(5 / V)
downwards, leading to decrease of
dV
and a little pit at the beginning of the graph. Futher angle
u
became more than
arccos(5 / V)
, so BuTaMuH had maximum gain of vertical speed, but at the same time he started to lose speed into horizontal direction of slide. Before leaving the slide BuTaMuH turned mouse away from the slide in advance, so increment
dV
plummeted, and gravitation outweighed. At the last frame on slide horizontal speed was 83.3 untis/s, while vertical one was 387 units/s.
Note: values of speed are stored in demo file with an error of 0.125 units/s, thereby graph calculated as differences of such values has error of 0.25 units/s. In this regard graph hit the level of 8.0 while the maximum possible gain is 7.84 units/s.
Turning away from slide
In this article we've aleady get acquainted with steep slide, and now it's time to explore the last block on
slide_svn_steepslides_h performed during the run by
.script (you can download the demo
here):
GIF 3.43MB
After air flight and touching the slide .script carries out familiar procedure – he turns towards the slide losing speed and ascending. But after passing the top point a curious thing happens – as he continues to slide he gradually turns away from the slide. It is a necessary thing cause after passing the top point he begins to slide down more and more (as we remember gravity always wins on steep slide). Increasing vertical velocity is projected onto the plane of the slide and becomes a horizontal one, hence resulting horizontal velocity turnes away from the slide. And since .script wants to maintain speed gain, he's turing his mouse to the left trying to keep angle
u
in the required range.
Conclusion
When we tried to assess human possibilities for lj we've already had hard times, but in case of slide it's close to impossible. The reason is that we face simultaneous changes in horizontal and vertical velocities, and even when considering a specific jump as we just did, the result will greatly depend on the initial and final heights on the slide, as well as on how the player will manage the gained speed after the slide. In random case both sizes and tilt angle of slide vary, so the final goal may be to fly as high as possible, or gain high horizontal speed, or something average like we saw on
b2j_slide_longjumps. That is why you can meet maps in kreedz which are almost entirely dedicated to slide. Despite the fact that we consider the slide as just one of the techniques, it may act as an independent direction, while its boundaries of the possible remain quite blurred.
You can recall how in the article about LongJump physics we discussed the existance of special servers with setting
sv_airaccelerate changed from 10 to 100. In case of slide this at first glance small difference led to the formation of entire communities dedicated to surf (this is how slide with
sv_airaccelerate 100 was called). This is due to the fact that firstly maximum increment
dV
becomes equal to 30 instead of 25, which affects gaining of both horizontal and vertical velocities. The longer we stay on surf the more
sv_airaccelerate difference plays a role, allowing to reach huge speeds. Secondly the range of angle
u
that gives gain of horizontal speed is wider, which lets surfers to be more maneuverable in flight.
That's it for now, but we'll back to the theme of slide later.