3. Player fundamentals

The player refers to the self. Specifically it is not necessarily you, but rather the self in the Half-Life universe.

3.1. Input

All player movements can be controlled through commands. In the default game setup, pressing down the “W” key usually results in the +forward command being issued. Releasing the same key will cause -forward to be issued. This is because the “W” key is bound to the +forward command with the bind command, usually issued from config.cfg. The -forward command need not be explicitly bound.

There are many similar commands available. It is beyond the scope of this documentation to provide a detailed description for all commands and indeed all cvars. The reader is invited to generate a list of all commands with the cmdlist command and study the SDK code for each of them.

There are, however, a few points to note about command issuing that are of concern to speedrunning. One of them is the impulse down phenomena. This affects primarily the viewangles (see Viewangles) and the FSU (see Forwardmove, sidemove, and upmove) computations. For example, the viewangles are typically changed by one of the viewangles commands such as +left for yawing left. This is done by adding to subtracting the viewangles by the value

The “key state” is the state of the command being issued (+left for example). The key state is typically 1, but in the first frame in which the command is being issued the value is 0.5. In other words, the change in viewangles is half of what it normally is in the first frame of the active command.

This is not limited to the viewangles. The FSU values (which is crucial to player movement as will be described in Forwardmove, sidemove, and upmove) are also affected by the impulse down. For example, by issuing +forward, the following value will be added to :

Again, the key state here is typically 1, except the first frame of the +forward command. This can result in a noticeably drop in player acceleration.


The reader is advised to perform a detailed study of cl_dlls/input.cpp to understand the processes and computations involved to greater depths.

3.2. Viewangles

The term viewangles is usually associated with the player entity. The viewangles refer to a group of three angles which describe the player’s view orientation. We call these angles yaw, pitch and roll. Mathematically, we denote the yaw by

and the pitch by

Note that these are different from and . We do not have a mathematical symbol for roll as it is rarely used. In mathematical discussions, the viewangles are assumed to be in radians unless stated otherwise. However, do keep in mind that they are stored in degrees in the game.


Fig. 3.1. Illustration of the geometric meaning of and , with the camera’s view represented by and is the projection of on the horizontal plane. Note that since the sign convention of in-game differs from that of standard trigonometry, a negative sign is needed.

One way to change the yaw and pitch is by moving the mouse. This is not useful for tool-assisted speedrunning, however. A better method for precise control of the yaw and pitch angles is by issuing the commands +left, +right, +up, or +down. When these commands are active, the game increments or decrements the yaw or pitch by a certain controllable amount per frame. The amounts can be controlled by adjusting the variables cl_yawspeed and cl_pitchspeed. For instance, when +right is active, the game multiplies the value of cl_yawspeed by the frame time, then subtracts the result from the yaw angle.

3.2.1. Anglemod

When the viewangles are sent to the server, their values in degrees are rounded slightly using the anglemod function, which will be denoted . The degrees-anglemod function may be mathematically written as

where denotes the integer part of . Similarly, the radians-anglemod function may be written as

Observe that and , regardless of . To see this, first assume . Then, the AND operation extracts only the lower 16 bits of the first integer argument. This is mathematically equivalent to modulo . Now if , then recall from the two’s complement representation that the signed integer representing some negative value (with ) has a positive value of if interpreted as an unsigned integer. Now,

To proceed further, write where and are integers and is the integer remainder when is divided by (remember that ). Then

Since , this simplifies to

Anglemod introduces a loss of precision in setting angles. This can result in a loss of optimality in strafing. There are two ways to reduce the effects of anglemod, namely by the simple anglemod compensation and the more advanced vectorial compensation. These techniques will be described in Vectorial compensation.

3.3. View vectors

There are two vectors associated with the player’s viewangles. These are called the view vectors. For discussions in 3D space, they are defined to be

We will refer to the former as the unit forward vector and the latter as the unit right vector. The negative sign for is an idiosyncrasy of the GoldSrc engine inherited from Quake. This is the consequence of the fact that looking up gives negative pitch angles and looking down gives positive pitch angles.

We sometimes restrict our discussions to the horizontal plane, such as in the description of strafing. In this case we assume and define

Such restriction is equivalent to projecting the vector onto the plane, provided the original vector is not vertical.

The above definitions are not valid if the roll is nonzero. Nevertheless, the roll is very rarely nonzero in practice, and so it rarely affects the physics described in this document, if at all.

3.4. Punchangles

The punchangles can refer to the client side or the server side values. The client side punchangles are usually affected by weapon recoil and are cosmetic in nature. Namely, they do not affect the aiming viewangles of the player. The player may be aiming with zero pitch while the camera appears to point elsewhere. The server side punchangles, on the other hand, affects the viewangles and therefore the aiming. The server side punchangles are affected by certain types of damage (see Health and damage) and punches from monsters (which are different from the purely damage itself).

The punchangles may be denoted as , consisting of punch pitch, punch yaw, and punch roll. When the punchangles are nonzero, the game will smoothly decrease the angles until all of them become zero. In each frame, the game calculates

The punchangles are rarely big issues except when the punch yaw and punch roll are nonzero. In these cases, strafing (Strafing) can be affected. Though this very rarely happens.

When a saveload is performed, the punchangles will be added to the viewangles permanently, while the punchangles will be set to zero. When this happens, the viewangles will not be reduced gradually like the case when punchangles are nonzero.

3.5. Forwardmove, sidemove, and upmove

When the movement keys are held, there exists three values, , , and , that are set. These values are called the forwardmove, sidemove, and upmove respectively, or FSU for short, and are used in player movement physics (see Player movement basics). In the beginning of player movement physics, the FSU values are computed in the following way. First, define client side analogues of , , and . Then,

+forward and +back
Assigns the positive or negative cl_forwardspeed to
+moveright and +moveleft
Assigns the positive or negative cl_sidespeed to
+moveup and +movedown
Assigns the positive or negative cl_upspeed to

This is done at client side. Before sending these values to the server, however, they will be truncated to integers and clamped to . Let the value of sv_maxspeed. Then, PM_CheckParamters [sic] computes the final server side FSU values such that, assuming not all of FSU are zero,

If all of FSU are zero, then nothing is done and they remain zero.