Claim set · data/claims/quake3.yaml

Quake III Arena (id Software's GPL source release, 1.32)

Game: Quake III Arena.

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. quake3/source-version

Value: 1.32

CodeQuake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/q_shared.h#L29-L30#define Q3_VERSION "Q3 1.32b" // 1.32 released 7-10-2002Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · README.txt#L1Quake III Arena GPL source releaseChecked by claude, 2026-10-22 — read the version define and its comment in code/game/q_shared.h and the README's title at the pinned commit

The date in the comment is id's, written month first. Player movement is in bg_pmove.c, which the file's own header calls "both games player movement code": the server's game module and the client's prediction run the same code.

Cited by: Quake III Arena

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). quake3/ground-friction

About: Quake III Arena Running

Value
{
 "pm_friction": 6,
 "pm_stopspeed": 100
}
CodeQuake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L34float pm_stopspeed = 100.0f;Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L44float pm_friction = 6.0f;Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L180-L229VectorCopy( vel, vec ); if ( pml.walking ) { vec[2] = 0; // ignore slope movement … speed = VectorLength(vec); … if ( pm->waterlevel <= 1 ) { if ( pml.walking && !(pml.groundTrace.surfaceFlags & SURF_SLICK) ) { // if getting knocked back, no friction if ( ! (pm->ps->pm_flags & PMF_TIME_KNOCKBACK) ) { control = speed < pm_stopspeed ? pm_stopspeed : speed; drop += control*pm_friction*pml.frametime; …Quake: the engine source release (id-Software/Quake: WinQuake and QuakeWorld) · WinQuake/sv_phys.c#L42-L43cvar_t sv_friction = {"sv_friction","4",false,true}; cvar_t sv_stopspeed = {"sv_stopspeed","100"};Quake: the engine source release (id-Software/Quake: WinQuake and QuakeWorld) · WinQuake/sv_user.c#L27cvar_t sv_edgefriction = {"edgefriction", "2"};Quake: the engine source release (id-Software/Quake: WinQuake and QuakeWorld) · WinQuake/sv_user.c#L144-L151if (trace.fraction == 1.0) friction = sv_friction.value*sv_edgefriction.value; else friction = sv_friction.value; … control = speed < sv_stopspeed.value ? sv_stopspeed.value : speed; newspeed = speed - host_frametime*control*friction;Checked by claude, 2026-10-22 — read PM_Friction (L172-L230) and the movement parameters at the top of bg_pmove.c, against WinQuake's SV_UserFriction

The movement parameters are C globals in the shared movement code, not cvars, so a server can't change them. Water, flight, and spectator friction add to the same drop in the lines between (L206-L218). Under 1 unit/s the horizontal velocity is zeroed outright.

Cited by: Quake III Arena, Running

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. quake3/ground-accelerate

About: Quake III Arena Running

Value
{
 "pm_accelerate": 10,
 "g_speed": 320
}
CodeQuake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L39float pm_accelerate = 10.0f;Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L240-L258static void PM_Accelerate( vec3_t wishdir, float wishspeed, float accel ) { #if 1 // q2 style … currentspeed = DotProduct (pm->ps->velocity, wishdir); addspeed = wishspeed - currentspeed; if (addspeed <= 0) { return; } accelspeed = accel*pml.frametime*wishspeed; if (accelspeed > addspeed) { accelspeed = addspeed; …Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L720PM_Friction ();Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L772-L778if ( ( pml.groundTrace.surfaceFlags & SURF_SLICK ) || pm->ps->pm_flags & PMF_TIME_KNOCKBACK ) { accelerate = pm_airaccelerate; } else { accelerate = pm_accelerate; } … PM_Accelerate (wishdir, wishspeed, accelerate);Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/g_main.c#L142{ &g_speed, "g_speed", "320", 0, 0, qtrue },Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L2015trap_SnapVector( pm->ps->velocity );Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/g_active.c#L843-L853client->ps.speed = g_speed.value; … if ( client->ps.powerups[PW_HASTE] ) { client->ps.speed *= 1.3;Quake: the engine source release (id-Software/Quake: WinQuake and QuakeWorld) · WinQuake/sv_user.c#L195-L201currentspeed = DotProduct (velocity, wishdir); addspeed = wishspeed - currentspeed; … accelspeed = sv_accelerate.value*host_frametime*wishspeed; if (accelspeed > addspeed) accelspeed = addspeed;Quake: the engine source release (id-Software/Quake: WinQuake and QuakeWorld) · WinQuake/sv_user.c#L167-L168cvar_t sv_maxspeed = {"sv_maxspeed", "320", false, true}; cvar_t sv_accelerate = {"sv_accelerate", "10"};Checked by claude, 2026-10-22 — read PM_WalkMove (L692-L809), PM_Accelerate's live branch, g_speed, and the speed setup in ClientThink_real; stepped friction then acceleration at 8 ms from rest and from 320 with no input, in a short script; at speed W friction removes 6·dt·W and acceleration can restore up to 10·dt·W, so each step returns to W

A step's time is the user command's own milliseconds (clamped to 1–200 and split into pieces of at most 66 ms, or of pmove_msec under pmove_fixed), so the step counts depend on the client's frame rate; the settled speed and the times in seconds barely do (0.15 and 0.36 s at 8, 13.9, or 33 ms by the same stepping). On a slick surface or while knocked back the ground push uses the air value, 1. The Mission Pack's Scout powerup multiplies the speed by 1.5 instead of Haste's 1.3.

Cited by: Air control, Quake III Arena, Running

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. quake3/cmd-scale

About: Quake III Arena Strafe-running

Value: 320 units/s

CodeQuake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/client/cl_input.c#L317-L345if ( in_speed.active ^ cl_run->integer ) { movespeed = 127; … movespeed = 64; … side += movespeed * CL_KeyState (&in_moveright); side -= movespeed * CL_KeyState (&in_moveleft); … up += movespeed * CL_KeyState (&in_up); … forward += movespeed * CL_KeyState (&in_forward); … …Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L285-L308Returns the scale factor to apply to cmd movements This allows the clients to use axial -127 to 127 values for all directions without getting a sqrt(2) distortion in speed. … max = abs( cmd->forwardmove ); if ( abs( cmd->rightmove ) > max ) { max = abs( cmd->rightmove ); } if ( abs( cmd->upmove ) > max ) { max = abs( cmd->upmove ); … total = sqrt( cmd->forwardmove * cmd->forwardmove …Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L627-L634for ( i = 0 ; i < 2 ; i++ ) { wishvel[i] = pml.forward[i]*fmove + pml.right[i]*smove; } wishvel[2] = 0; … VectorCopy (wishvel, wishdir); wishspeed = VectorNormalize(wishdir); wishspeed *= scale;Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L369-L373// must wait for jump to be released if ( pm->ps->pm_flags & PMF_JUMP_HELD ) { // clear upmove so cmdscale doesn't lower running speed pm->cmd.upmove = 0;Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L2061-L2062if ( pmove->ps->pm_flags & PMF_JUMP_HELD ) { pmove->cmd.upmove = 20;Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L2015trap_SnapVector( pm->ps->velocity );Quake: the engine source release (id-Software/Quake: WinQuake and QuakeWorld) · WinQuake/cl_input.c#L213-L215cvar_t cl_forwardspeed = {"cl_forwardspeed","200", true}; cvar_t cl_backspeed = {"cl_backspeed","200", true}; cvar_t cl_sidespeed = {"cl_sidespeed","350"};Quake: the engine source release (id-Software/Quake: WinQuake and QuakeWorld) · WinQuake/sv_user.c#L351-L354if (wishspeed > sv_maxspeed.value) { VectorScale (wishvel, sv_maxspeed.value/wishspeed, wishvel); wishspeed = sv_maxspeed.value;Checked by claude, 2026-10-22 — read CL_KeyMove, PM_CmdScale, the wish velocity in PM_AirMove (PM_WalkMove's at L742-L750 is the same with the ground plane's tilt), PM_CheckJump, and Pmove's loop; with forward and side 127 the wish is 127√2 × 320/(127√2) = 320, and with up 127 too it is 127√2 × 320/(127√3)

Mouse and joystick moves add to the same command (cl_input.c) and go through the same scale. The walk (64) gives 320 × 64/127 ≈ 161.

Cited by: Quake III Arena, Strafe-running

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. quake3/air-accelerate

About: Quake III Arena Strafe-running

Value
{
 "pm_airaccelerate": 1
}
CodeQuake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L40float pm_airaccelerate = 1.0f;Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L610-L637PM_Friction(); … wishvel[i] = pml.forward[i]*fmove + pml.right[i]*smove; } wishvel[2] = 0; … wishspeed = VectorNormalize(wishdir); wishspeed *= scale; … // not on ground, so little effect on velocity PM_Accelerate (wishdir, wishspeed, pm_airaccelerate);Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L197if ( pml.walking && !(pml.groundTrace.surfaceFlags & SURF_SLICK) ) {Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L2015trap_SnapVector( pm->ps->velocity );Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L240-L275static void PM_Accelerate( vec3_t wishdir, float wishspeed, float accel ) { #if 1 … currentspeed = DotProduct (pm->ps->velocity, wishdir); addspeed = wishspeed - currentspeed; if (addspeed <= 0) { return; } accelspeed = accel*pml.frametime*wishspeed; if (accelspeed > addspeed) { accelspeed = addspeed; … …Quake: the engine source release (id-Software/Quake: WinQuake and QuakeWorld) · WinQuake/sv_user.c#L212-L224wishspd = VectorNormalize (wishveloc); if (wishspd > 30) wishspd = 30; currentspeed = DotProduct (velocity, wishveloc); addspeed = wishspd - currentspeed; … accelspeed = sv_accelerate.value*wishspeed * host_frametime; if (accelspeed > addspeed) accelspeed = addspeed;Checked by claude, 2026-10-22 — read PM_AirMove (L601-L658), PM_Friction's ground test, and both branches of PM_Accelerate; against WinQuake's SV_AirAccelerate

The famous air acceleration of 1 is the multiplier on the push, not a cap. Because the cap is the full wish speed, the best wish direction in Quake III lies close to the motion at run speed and swings wider as the speed grows (quake3/strafe-jump-gain), where Quake's 30 cap puts it at right angles. In water above level 1 the move goes to PM_WaterMove instead.

Cited by: Air control, Quake III Arena, Strafe-running

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. quake3/jump

About: Quake III Arena Jump

Value: 270 units/s

CodeQuake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_local.h#L29#define JUMP_VELOCITY 270Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L359-L393static qboolean PM_CheckJump( void ) { if ( pm->ps->pm_flags & PMF_RESPAWNED ) { return qfalse; // don't allow jump until all buttons are up } … if ( pm->cmd.upmove < 10 ) { // not holding jump return qfalse; } … if ( pm->ps->pm_flags & PMF_JUMP_HELD ) { … …Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L1916-L1918if ( pm->cmd.upmove < 10 ) { // not holding jump pm->ps->pm_flags &= ~PMF_JUMP_HELD;Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L1988-L1990} else if ( pml.walking ) { // walking on ground PM_WalkMove();Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L710if ( PM_CheckJump () ) {Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L1183-L1187// don't do landing time if we were just going down a slope if ( pml.previous_velocity[2] < -200 ) { // don't allow another jump for a little while pm->ps->pm_flags |= PMF_TIME_LAND; pm->ps->pm_time = 250;Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/g_main.c#L143{ &g_gravity, "g_gravity", "800", 0, 0, qtrue },Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/g_active.c#L840client->ps.gravity = g_gravity.value;Quake: the QuakeC source and compiler (id-Software/Quake-Tools, qcc/v101qc) · qcc/v101qc/client.qc#L811self.velocity_z = self.velocity_z + 270;Checked by claude, 2026-10-22 — read PM_CheckJump whole (L359-L393), its one call site (grep: L710 in PM_WalkMove), PmoveSingle's jump-held test and move dispatch, and PM_GroundTrace's landing branch; PMF_TIME_LAND appears in bg_pmove.c only where PM_GroundTrace sets and clears it

Setting rather than adding means a jump takes off at 270 whatever the vertical velocity was. The land timer's flag is defined in bg_public.h as "pm_time is time before rejump"; in the files read only PM_DropTimers' count-down (through PMF_ALL_TIMES) touches it besides. Gravity is applied in the slide move (bg_slidemove.c), not read for this claim.

Cited by: Jump, Quake II, Quake III Arena

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. quake3/hop-friction

About: Quake III Arena Bunny hopping

CodeQuake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L1962-L1963// set groundentity PM_GroundTrace();Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L1165-L1166pml.groundPlane = qtrue; pml.walking = qtrue;Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L710-L720if ( PM_CheckJump () ) { // jumped away if ( pm->waterlevel > 1 ) { PM_WaterMove(); } else { PM_AirMove(); } return; } … PM_Friction ();Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L377pml.walking = qfalse;Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L610PM_Friction();Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L196-L201if ( pm->waterlevel <= 1 ) { if ( pml.walking && !(pml.groundTrace.surfaceFlags & SURF_SLICK) ) { … control = speed < pm_stopspeed ? pm_stopspeed : speed; drop += control*pm_friction*pml.frametime;Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L1916-L1918if ( pm->cmd.upmove < 10 ) { // not holding jump pm->ps->pm_flags &= ~PMF_JUMP_HELD;Quake: the engine source release (id-Software/Quake: WinQuake and QuakeWorld) · QW/client/pmove.c#L889-L894if (pmove.cmd.buttons & BUTTON_JUMP) JumpButton (); else pmove.oldbuttons &= ~BUTTON_JUMP; … PM_Friction ();Quake: the engine source release (id-Software/Quake: WinQuake and QuakeWorld) · QW/client/pmove.c#L674-L683if (onground == -1) return; // in air, so no effect … if ( pmove.oldbuttons & BUTTON_JUMP ) return; // don't pogo stick … onground = -1; … pmove.oldbuttons |= BUTTON_JUMP; // don't jump again until releasedQuake: the engine source release (id-Software/Quake: WinQuake and QuakeWorld) · QW/client/pmove.c#L366-L369else if (onground != -1) // apply ground friction { control = speed < movevars.stopspeed ? movevars.stopspeed : speed; drop += control*friction*frametime;Quake: the QuakeC source and compiler (id-Software/Quake-Tools, qcc/v101qc) · qcc/v101qc/client.qc#L972-L977if (self.button2) { PlayerJump (); } else self.flags = self.flags | FL_JUMPRELEASED;Quake: the QuakeC source and compiler (id-Software/Quake-Tools, qcc/v101qc) · qcc/v101qc/client.qc#L798-L811if ( !(self.flags & FL_JUMPRELEASED) ) return; // don't pogo stickQuake: the engine source release (id-Software/Quake: WinQuake and QuakeWorld) · WinQuake/sv_user.c#L361-L364else if ( onground ) { SV_UserFriction (); SV_Accelerate ();Quake: the engine source release (id-Software/Quake: WinQuake and QuakeWorld) · WinQuake/sv_phys.c#L1069PR_ExecuteProgram (pr_global_struct->PlayerPreThink);Checked by claude, 2026-10-22 — traced a landing: the air step's slide move reaches the floor and the trace after the move (L1999) sets the ground entity; pml is zeroed at the next step's start (L1892), whose trace (L1963) sets walking, so PM_WalkMove runs and its jump test comes before any ground friction; the jump's PM_AirMove friction sees walking cleared; read QuakeWorld's PlayerMove order, JumpButton, and PM_Friction's ground test, and the 1.01 QuakeC's release flag

Water friction still applies in shallow water (level 1), since it doesn't test the walking flag. On a slick surface there is no ground friction in any case. The landing itself is an air step, so a well-timed hop chain in Quake III never runs ground friction at all.

Cited by: Bunny hopping, Quake III Arena

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. quake3/strafe-jump-gain

About: Quake III Arena Strafe-running

Value: 317 units/s per second at 320

CodeQuake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L246-L254currentspeed = DotProduct (pm->ps->velocity, wishdir); addspeed = wishspeed - currentspeed; if (addspeed <= 0) { return; } accelspeed = accel*pml.frametime*wishspeed; if (accelspeed > addspeed) { accelspeed = addspeed;Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L40float pm_airaccelerate = 1.0f;Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L637PM_Accelerate (wishdir, wishspeed, pm_airaccelerate);Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L1909pml.frametime = pml.msec * 0.001;Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/bg_pmove.c#L2015trap_SnapVector( pm->ps->velocity );Quake III Arena: the GPL source release (id-Software/Quake-III-Arena, 1.32b) · code/game/g_main.c#L179{ &pmove_msec, "pmove_msec", "8", CVAR_SYSTEMINFO, 0, qfalse},Quake: the engine source release (id-Software/Quake: WinQuake and QuakeWorld) · WinQuake/sv_user.c#L212-L222wishspd = VectorNormalize (wishveloc); if (wishspd > 30) wishspd = 30; currentspeed = DotProduct (velocity, wishveloc); addspeed = wishspd - currentspeed; … accelspeed = sv_accelerate.value*wishspeed * host_frametime;Checked by claude, 2026-10-22 — with push a along unit ŵ, |v + aŵ|² = v² + 2ca + a², increasing in c, and a is the full W·dt while c ≤ W − a, so the best is c = W − a (needs v ≥ W − a); evaluated at v = 320, 400, 500 with dt 8 ms and 1/72 s in a short script; per second ≈ (2Wa − a²)/(2v·dt) ≈ W²/v

The 8 ms step is pmove_msec's default, used when pmove_fixed is on; otherwise a step is the client's own command time. trap_SnapVector hands the velocity to the engine to snap after every step; that rounding is engine code outside the files read. With the jump key held in the air the wish speed drops to about 261 (quake3/cmd-scale) and the gain at 320 to about 212 units/s per second.

Cited by: Quake III Arena, Strafe-running