Cite as
id-Software/Quake-III-Arena
Original
https://github.com/id-Software/Quake-III-Arena
Pinned
id-Software/Quake-III-Arena @ dbe4ddb10315479fc00086f08e25d968b4b43c49
Accessed
2026-10-22
Licence
GPL-2.0 (README.txt: “See COPYING.txt for the GNU GENERAL PUBLIC LICENSE”; COPYING.txt is the GNU General Public License, version 2, and each game source file's header reads “Copyright (C) 1999-2005 Id Software, Inc.” under GPL version 2 or later). The README lists code it says is “not covered by the GPL” (zlib's zip reading, MD4, and others), none of it in the files read here.
Credit
id Software's source for Quake III Arena, as released under the GPL.
Notes
The release holds the engine, the game code, the tools, and Q3Radiant, but no game data. `q_shared.h` names the version “Q3 1.32b”, commented “1.32 released 7-10-2002”, so every claim describes the 1.32 point release, not the 1999 retail build. Player movement is shared code (`bg_pmove.c`, “both games”: the server's game module and the client's prediction run the same Pmove). `paths` keeps the fetch to the root texts and the movement, game-rule, and input files the claims read.

Cited on

Claims (10)

On the ground, Quake II's Pmove runs PM_Friction, which lowers the speed by step time × 6 (pm_friction) × the larger of the speed and 100 (pm_stopspeed) on any ground that isn't slick, and then PM_Accelerate with pm_accelerate 10: if the speed along the wish direction is under the wish speed, it adds 10 × step time × wish speed, no more than the shortfall. The wish velocity's length is capped at 300 (pm_maxspeed), or 100 ducked. These are the numbers Quake III keeps (friction 6, acceleration 10), where Quake's friction is 4. Computed, not measured: since 10 outpaces 6, a run settles at exactly 300 units/s. The movement constants are C globals, not cvars.code/game/bg_pmove.c L39code/game/bg_pmove.c L44Code
In the air, Quake II's PM_AirMove calls the ground's PM_Accelerate with an acceleration of 1 while pm_airaccelerate is 0: the push is 1 × step time × wish speed (up to 300), and it stops only when the velocity's component along the wish direction reaches the full wish speed. Quake III keeps this rule, with pm_airaccelerate 1 and a PM_Accelerate commented "q2 style". In deathmatch the server copies its latched cvar sv_airaccelerate (default 0) into pm_airaccelerate, and any nonzero value switches to PM_AirAccelerate, which is Quake's air rule: the wish speed capped at 30 for the shortfall, the push from the uncapped wish speed × pm_accelerate (10) × step time. The server's movement code uses the value only as a nonzero test, so it acts as an on-off switch; outside deathmatch it is forced to 0. The server also sends the value to clients as the CS_AIRACCEL config string, for their prediction, in code not read here.code/game/bg_pmove.c L40code/game/bg_pmove.c L240–242code/game/bg_pmove.c L637Code
id Software's GPL source release of Quake III Arena names its version "Q3 1.32b" (Q3_VERSION in q_shared.h), commented "1.32 released 7-10-2002", so the code read here is the 1.32 point release rather than the 1999 retail build.code/game/q_shared.h L29–30README.txt L1Code
On the ground, Quake III's PM_Friction takes the horizontal speed and lowers it by step time × pm_friction × the larger of the speed and pm_stopspeed, scaling all three velocity axes by the same factor, with pm_friction 6 and pm_stopspeed 100 set in the code; it skips ground friction in water deeper than level 1, on a slick surface, and while the knockback timer runs, and it has no edge friction. Quake's ground friction is the same rule with friction 4 (sv_friction) and the same stop speed, doubled over a ledge (quake/ground-friction).code/game/bg_pmove.c L34code/game/bg_pmove.c L44code/game/bg_pmove.c L180–229Code
Quake III's PM_WalkMove runs friction and then PM_Accelerate with pm_accelerate 10, which is Quake's rule (Quake III's PM_Accelerate comment says "q2 style"): if the speed along the wish direction is under the wish speed, it adds 10 × step time × wish speed along that direction, no more than the shortfall. The full wish speed is the player's speed, set before each move from g_speed (320, × 1.3 with Haste). Computed, not measured: since 10 outpaces the friction of 6, a run settles at exactly 320, as Quake's does at 10 against 4; at 8 ms steps it reaches 320 from rest in 19 steps (0.15 s) and stops from 320 in 45 (0.36 s). These figures leave out the rounding trap_SnapVector applies to the velocity after each step, engine code the atlas hasn't read.code/game/bg_pmove.c L39code/game/bg_pmove.c L240–258code/game/bg_pmove.c L720code/game/bg_pmove.c L772–778code/game/g_main.c L142code/game/bg_pmove.c L2015code/game/g_active.c L843–853Code
Quake III's keyboard moves are 127 per axis at a run (the speed key or cl_run, one but not both) and 64 at a walk, and PM_CmdScale scales the wish so its length is the player's speed × the largest of the forward, side, and up moves ÷ 127, which a comment says avoids "a sqrt(2) distortion in speed": at a run, forward, a strafe, and both together each wish 320, so a strafe adds no ground speed, where Quake's walk with a strafe wishes 320 against 200 (quake/move-speeds). The up move counts too: computed, holding the jump key (up move 127) in the air with forward and a strafe wishes 320 × √2/√3 ≈ 261. On the ground PM_CheckJump zeroes a held jump's up move, and Pmove lowers it to 20 for the later steps of a command it splits. The figures leave out the rounding trap_SnapVector applies to the velocity after each step, engine code the atlas hasn't read.code/client/cl_input.c L317–345code/game/bg_pmove.c L285–308code/game/bg_pmove.c L627–634code/game/bg_pmove.c L369–373code/game/bg_pmove.c L2061–2062code/game/bg_pmove.c L2015Code
In the air, Quake III's PM_AirMove runs friction (no ground friction, which needs the walking flag), builds a flat wish velocity, and calls the same PM_Accelerate as the ground with pm_airaccelerate 1: the push is 1 × step time × wish speed (2.56 units/s per 8 ms step at 320), and it stops only when the velocity's component along the wish direction reaches the full wish speed. Quake's air rule is the reverse: a push ten times as strong (10 × 320 × frame time), cut off when that component reaches 30 (quake/air-accelerate). An #else branch left out by #if 1 would push the velocity toward the wish velocity instead, commented "proper way (avoids strafe jump maxspeed bug), but feels bad". The figures leave out the rounding trap_SnapVector applies to the velocity after each step, engine code the atlas hasn't read.code/game/bg_pmove.c L40code/game/bg_pmove.c L610–637code/game/bg_pmove.c L197code/game/bg_pmove.c L2015code/game/bg_pmove.c L240–275Code
Quake III's jump is in the shared movement code: PM_CheckJump, called from PM_WalkMove (so only on walkable ground), needs an up move of at least 10 and the jump-held flag clear, which PmoveSingle clears only on a step whose up move is under 10, so holding the key never jumps twice; it then sets the vertical velocity to JUMP_VELOCITY (270), where Quake's QuakeC adds 270 to it (quake/jump). Gravity is g_gravity, 800, as in Quake. A landing from a fall faster than 200 units/s sets a land timer of 250 ms that a comment says is to "not allow another jump for a little while", but PM_CheckJump never tests it.code/game/bg_local.h L29code/game/bg_pmove.c L359–393code/game/bg_pmove.c L1916–1918code/game/bg_pmove.c L1988–1990code/game/bg_pmove.c L710code/game/bg_pmove.c L1183–1187code/game/g_main.c L143code/game/g_active.c L840Code
Quake III checks the jump before friction: each step, PmoveSingle traces for ground before the move, PM_WalkMove calls PM_CheckJump before PM_Friction, and a jump clears the walking flag and hands the step to PM_AirMove, whose friction call skips ground friction without that flag. So a hop on the first step that starts on the ground loses no speed to friction, as in QuakeWorld (quake/qw-hop-friction), where WinQuake's takes one frame of it, 5.6% at 72 frames a second (quake/hop-friction). The hop needs the jump key released and pressed again in the air, as in both.code/game/bg_pmove.c L1962–1963code/game/bg_pmove.c L1165–1166code/game/bg_pmove.c L710–720code/game/bg_pmove.c L377code/game/bg_pmove.c L610code/game/bg_pmove.c L196–201code/game/bg_pmove.c L1916–1918Code
Computed from PM_Accelerate with pm_airaccelerate 1, not measured: at a wish speed W of 320 (forward and a strafe at a run, the jump key up, no Haste) the air push is W × step time, a = 2.56 per 8 ms step, and the cap leaves room for all of it while the velocity's component c along the wish direction is at most W − a; the new speed √(v² + 2ca + a²) is then largest at c = W − a, with the wish 7° off a 320 motion, 37° off 400, and 51° off 500. Each 8 ms step adds 2.54 units/s at 320 and 1.63 at 500, about 317 and 204 units/s each second, close to W²/v at any step length (316 at 1/72 s). Quake's gain is fixed per frame instead, about 101 units/s each second at 320 at 72 frames a second (quake/air-strafe-gain). The figures leave out the rounding trap_SnapVector applies to the velocity after each step, engine code the atlas hasn't read.code/game/bg_pmove.c L246–254code/game/bg_pmove.c L40code/game/bg_pmove.c L637code/game/bg_pmove.c L1909code/game/bg_pmove.c L2015code/game/g_main.c L179Code