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 L44 | Code |
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 L637 | Code |
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 L1 | Code |
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–229 | Code |
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–853 | Code |
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 L2015 | Code |
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–275 | Code |
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 L840 | Code |
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–1918 | Code |
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 L179 | Code |