1. Game fundamentals¶
This page describes the notations that we will use throughout this documentation. We will also introduce some basic concepts that will be used and assumed in all our discussions.
1.1. Tracing¶
Tracing is one of the most important computations done by the game. Tracing is done countless times per frame, and it is vital to how entities interact with one another.
Note
expansion needed
1.2. Randomness¶
The Half-Life universe is full of uncertainties, much like our universe at the level of quantum mechanics. Randomness in Half-Life is sourced in two ways: by means of the shared RNG and the non-shared RNG. These are custom written pseudo-RNGs that are powered by vastly different algorithms. The shared RNG is so named because it is computed by the game server and shared with the game clients, while the non-shared RNG is computed independently by the game server and clients without any kind of sharing or synchronisation between them.
1.3. Frame rate¶
When we think of the concept of frame rate, or sometimes somewhat incorrectly referred to by its unit of measurement frames per second or fps, we think of the refresh rate of the screen when playing Half-Life. However, it is crucial to distinguish between three different types of frame rate:
- rendering frame rate
This is the real-time rate at which graphics are painted on the screen, denoted as . This definition maps to what is normally thought of as the frame rate. The rendering frame rate is usually limited by
fps_max
in normal gameplay, though ifhost_framerate
is set, thenfps_max
is ignored. Other factors can also limit the maximum frame rate, including, but not limited to, the “vertical sync” setting (in-game or otherwise) andfps_override
.- game frame rate
This is the virtual rate at which the majority (with player movement being the important exception) of the game physics are run, denoted as . The game frame rate is typically in sync with the rendering frame rate, though not always. For example, suppose a computer is not able to render the graphics beyond a rendering frame rate of 500 fps, but
host_framerate
is set to 0.001. This forces the physics to run at a virtual 1000 fps, though because the screen does not update that frequently, the game appears to run twice as slow in real time.- player frame rate
The player frame rate is the virtual frame rate at which the majority of the player movement physics (see Player movement basics) are run, denoted as . The player frame rate roughly corresponds to the game frame rate. Depending on the engine version, whether the game is paused, and the value of the game frame rate itself, the player frame time may oscillate between different values, stay at zero, or be rounded towards zero to the nearest 0.001.
1.3.1. Slowdown on older engines¶
Suppose the game frame rate is higher than 20 fps. On older game engines, roughly before build 6027, the player frame rate equals the game frame rate rounded towards zero to the nearest 0.001, as mentioned above. Namely, we have
The slowdown factor is then defined as
When the slowdown factor is less than one, the actual movement speed of the player will be lower. The player’s position update described in Position update uses but runs at the rate of Hz. Indeed, the real velocity of the player is directly proportional to :
For instance, a trick known as the “501 fps slowdown” was implemented in Half-Life 21 (see Half-Life 21 (2014) by quadrazid et al.) to permit opening and passing through doors in the Questionable Ethics chapter without stopping dead by the doors before they could be opened fully. The slowdown factor at 501 fps is , implying the real velocity is roughly half the intended player velocity. On pre-Steam versions of Half-Life and its expansions, the default frame rate is 72 fps (and some speedrunners believe it should not be exceeded), which would give a slowdown factor of .
It is a well known fact that the slowdown factor if and only if is an integer. This is because as seen in (1.1), if we must have
which is only possible if is an integer.
1.4. Savestates¶
1.5. DELTA¶
The DELTA mechanism is one of the ways Half-Life uses to save bandwidth in client-server communication.
TODO
1.6. Walking through a frame¶
This section attempts to outline some of the major events relevant to speedrunning that happen in a frame. Extreme detail on how each part of the game engine works is beyond the scope of this documentation. In fact, some believe that code is documentation! Until Valve releases the source code of Half-Life, one can study the Xash3D engine source or the disassembly of Half-Life.
Footnotes
We omit any mention of the integer version of the shared RNG,
UTIL_SharedRandomLong
, because no code is calling this function in the SDK. It also behaves very similarly to the floating point version with only minor differences.