8. Surfing and wallstrafing
Surfing is a very specialised technique in Half-Life that is crucial in surf maps. The act of surfing involves accelerating against a sloped wall, thereby allowing some control over the vertical position of the player that is not possible by pure strafing alone. On the other hand, wallstrafing refers to the act of accelerating against a vertical wall, ideally with as much horizontal acceleration as possible.
While these two techniques are seemingly different, at least in their objectives, wallstrafing can be considered a degenerative case where the wall is perfectly vertical rather than sloped. The techniques for analysis is somewhat similar for the two cases, at least for the simplest cases, therefore we will discuss the two techniques in the same chapter.
8.1. Wallstrafing
The collision equation is
π―π=π―β²βπ(π―β²β
Λπ§)Λπ§
where π―β² is the velocity produced by the FME. Assuming π =1, the speed is given by
βπ―πβ2=π―πβ
π―π=βπ―β²β2β(π―β²β
Λπ§)2
On the other hand, from the FME we have
π―β²=π―+πΛπ―π
(π)
where π
(π) is the rotation matrix. Performing dot product with the plane normal Λπ§ gives
π―β²β
Λπ§=π―β
Λπ§+πΛπ―π
(π)β
Λπ§
Assuming the initial velocity π― lies on the plane, we have π― β
Λπ§ =0. On the other hand, Λπ―π
(π) β
Λπ§ β 0 because Λπ― is being rotated out of the collision plane by π radians. It follows that the angle between the rotated Λπ― and Λπ§ must be π/2 +π, or
π―β²β
Λπ§=πcosβ‘(π2+π)=βπsinβ‘π
As usual, the speed as a result of the FME is given by
βπ―β²β2=βπ―β2+π2+2βπ―βπcosβ‘π
Substituting back to the collision equation and simplifying yields
βπ―πβ2=βπ―β2+π2cos2β‘π+2βπ―βπcosβ‘π
Let π =πΎ1, then we can see that the speed is strictly decreasing in 0 β€π β€π.
Similarly, let π =πΎ2, setting the derivative to zero and simplifying, we obtain,
0=(πΏβ2βπ―βcosβ‘π)(βπ―βcos2β‘πβπΏcosβ‘πββπ―β)
It can be shown that
cosβ‘π=πΏ2βπ―β
gives the maximum of the function.
Note
TODO: more commentary
8.2. Pure sliding
Pure sliding turns out to be one of the fastest ways to gain horizontal speed down a sloped wall. One gains horizontal speed much faster asymptotically than strafing. This is not surprising when we consider the fact that the horizontal speed due to strafing increases roughly in proportion to the square root of time. By sliding down a plane, however, both the horizontal and vertical speed can potentially increase linearly with time, or constant acceleration.
Recall from the general collision equation (GCE) (see Player collision) that
π―π=π―β²βπ(π―β²β
Λπ§)Λπ§
where π―β² is the speed due to strafing and gravity and π =1 is the assumed bounce coefficient. If no strafing is performed, we simply have
π―β²=π―ββ¨0,0,ππππβ©
where ππ is 1/2 in the first frame and 1 for subsequent frame, to account for the leapfrog integrated gravitational field, as described in Gravity. To compute the GCE, we need to compute the dot product π―β² β
Λπ§. Assuming the initial velocity π― lies on the plane, then π― β
Λπ§ =0. If the plane normal makes an angle of 0 β€πΌ β€π/2 with the horizontal plane, then we can write ππ§ =sinβ‘πΌ. What remains is therefore
π―β²β
Λπ§=ππππcosβ‘(π2+πΌ)=βππππsinβ‘πΌ
Eliminating the dot product and π―β² from the GCE yields
π―π=π―ββ¨0,0,ππππβ©+Λπ§ππππsinβ‘πΌ
Here we can see that
π£π,π§=π£π§βππππcos2β‘πΌ
while the horizontal speed is
ββ¨π£π,π₯,π£π,π¦β©β=βπ΄2+π΄π΅cosβ‘π½+14π΅2
where π΄ =βπ£2π₯+π£2π¦, π΅ =ππππsinβ‘2πΌ, and π½ is the angle between the projected velocity on the horizontal plane β¨π£π₯,π£π¦β© and the projected plane normal β¨ππ₯,ππ¦β©. In the worst case where π½ =π/2, the horizontal speed increases roughly square root with time, but not for long, because π½ gradually decreases over time as the component of velocity in the direction of the plane normal accelerates. In the best case where π½ =0, the expression simplifies to
ββ¨π£π,π₯,π£π,π¦β©β=π΄+12π΅
That is, the horizontal speed accelerates linearly with time. This is also the steady state expression as π½ drifts towards zero over time.
8.3. Vertical balance surfing
Before tackling the harder issues on surfing, letβs tackle a basic movement strategy. When surfing on a slope, one can move vertically up or down depending on the strafing angle π. There must exist a critical π such that the vertical velocity will remain zero throughout, resulting in no vertical movement. As we shall see later, the horizontal speed would usually increase as usual, though at a lower acceleration than pure strafing.
In the GCE, the velocity π―β² is due to the fundamental movement equation (FME) (described in detail in Air and ground movements) added to the gravitational step. Namely,
π―β²=ββ
β
β
ββπ―+ππ―βπ£2π₯+π£2π¦π
π§(π)ββ
β
β
ββ diagβ‘(1,1,0)+β¨0,0,π£π§βππππβ©
A few notes to be made here. First, π― is a three-dimensional vector here, unlike the vectors in a typically written FME. Therefore, the rotation matrix is specifically a rotation about the π§ axis, written as π
π§(π). Second, diagβ‘(π1,β¦,ππ) means a diagonal matrix with entries π1,β¦,ππ. By multiplying a vector with diagβ‘(0,0,1), for example, we effectively zero out the π₯ and π¦ components. Indeed, the horizontal acceleration portion is multiplied by diagβ‘(1,1,0) because the vertical component of the velocities are ignored in strafing and horizontal acceleration in general. Third, the gravity time step has a ππ, which has a value of ππ =1/2 for the first frame and ππ =1 for subsequent frames.
We now substitute π―β² into the GCE. To compute the GCE, we perform the dot product π―β² β
Λπ§. The first term from the product may be written as
ββ
β
β
ββπ―+ππ―βπ£2π₯+π£2π¦π
π§(π)ββ
β
β
ββ diagβ‘(1,1,0)β
Λπ§
Assume that the initial velocity π― lies on the plane, which makes π― β
Λπ§ =0. Now π―π
π§(π)diagβ‘(1,1,0) β
Λπ§ β 0 because the velocity vector is being rotated away or into the plane. It follows that the angle between the two vectors is π/2 +|π| when projected onto the horizontal plane. The absolute value of π must be taken because the strafing angle can be negative. On the other hand, note that the plane normal projected onto the horizontal plane is no longer a unit vector, but rather, a vector of length cosβ‘πΌ where πΌ is the angle between the plane normal and the horizontal plane.
Using these observations, we find that the first term is equivalent to
πcosβ‘(π2+|π|)cosβ‘πΌ=βπsinβ‘|π|cosβ‘πΌ
The second term is easier to find. It is simply
(π£π§βππππ)sinβ‘πΌ
From the GCE, the final vertical velocity is given by
π£π,π§=π£β²π§β(π―β²β
Λπ§)ππ§=π£π§βππππβ(βπsinβ‘|π|cosβ‘πΌ+(π£π§βππππ)sinβ‘πΌ)sinβ‘πΌ
Assume that π£π§ =π£π,π§ =0, which is the steady state where no vertical movement occurs, the equation simplifies to
πsinβ‘|π|sinβ‘πΌβππππcosβ‘πΌ=0
This assumes πΌ β π/2, which holds as long as the plane is not horizontal. Here, the usual analysis can be performed by assuming π =πΎ1 or π =πΎ2 and proceed to solve the equation. Empirical observations indicate that π =πΎ2 is most frequently the admissible solution. Unfortunately, as is common in surfing analysis, writing down the solutions analytically is very difficult because it requires finding the roots of a quartic polynomial. It is much more practical to use a robust numerical method such as Brentβs method to find a solution, or by computing the eigenvalues of the associated companion matrix.
8.4. Maximum per-frame horizontal acceleration
This section describes an attempt to optimise the horizontal acceleration on a surf plane. This approach involves maximising the horizontal acceleration on a per-frame basis. That is, this approach only considers the current frame without accounting for the acceleration in future frames. In isolation, as it turns out, it does not give us a global optimum. This serves to illustrate the danger of thinking in per-frame terms as is common in pure strafing, where, by luck, per-frame optimisations happen to also yield a global optimum. Attempting to maximise the accelerate per frame is a greedy algorithm, which in general is not guaranteed to give the most optimal configurations.
To illustrate this point, we will not derive an analytical expression for per-frame maximum acceleration. It suffices to use a numerical algorithm on a common Half-Life configuration, which consists of π΄ =100, π =0.01 (for 100 fps), π =320, and a surf plane of πΌ =30β such that β¨ππ₯,ππ¦,ππ§β© =β¨0,cosβ‘πΌ,sinβ‘πΌβ©. Assume an initial velocity of π― =β¨500,0,0β©. One can check that the velocity and the plane normal are perpendicular.