On this page
  1. Related
  2. Mechanics
  3. References
  4. Sources

The atlas reads Quake through the engine source id Software released under the GPL, WinQuake’s version 1.091,1, and through the 1.01 QuakeC, the game code that holds the jump2. The 1996 DOS executable is not in the release, so every claim here describes WinQuake, and QuakeWorld only where a claim names it.

Movement runs once per host frame, at most 72 frames/s3,3. On the ground, an acceleration of 10 outpaces a friction of 4, so a run settles at the 320 cap4,5,6. In the air the push stops once the speed along the wish direction reaches 30, but a velocity pointing elsewhere still takes it; turning the view to keep a strafe at right angles to the motion adds speed every frame, the root of air strafing7,8. A jump adds 270 units/s2,2 against a gravity of 800 units/s²9,9. Friction runs before the jump in each frame, so a bunny hop loses one frame of ground friction per landing, which QuakeWorld’s reordered code avoids10,11.

Mechanics

MechanicKindHow
RunningMomentumacceleration 10 against friction 4 settles a run at exactly the 320 cap, reached in about a seventh of a second
Strafe-runningAir strafeon the ground a strafe only helps a walk; in the air the push along the wish direction stops at 30, so turning into the strafe keeps adding speed
Bunny hoppingLanding frictionfriction runs before the jump in each frame, so every hop spends one frame under ground friction, which QuakeWorld's movement code skips
JumpOne speedthe QuakeC adds 270 units/s upward, and only after the button has been released since the last jump
GravityOne gravity800 units/s² every frame out of water, 100 on E1M8
Air controlMomentumthe move keys push against the speed carried, but only up to 30 along the wish direction, with no friction in the air
Demo playbackRecorded statethe server's messages with the client's view angles, read in place of the network; no server runs
Every claim about this game, by concept (18)
generalid Software's released Quake engine source numbers its single-player engine, WinQuake, as version 1.09 (VERSION in quakedef.h); the readme calls the release "the complete source code for winquake, glquake, quakeworld, and glquakeworld" and says the original DOS version "should also be buildable from these sources, but we didn't bother trying".Code
Quake's host runs a frame only once at least 1/72 second has passed since the last, so the game steps at most 72 times a second; each frame's time step (host_frametime) is the real time since the last frame, clamped to 0.001–0.1 second, unless host_framerate fixes it, and a time demo skips the 1/72 wait.Code
Each Quake server frame reads every client's move and runs SV_ClientThink, which applies friction and acceleration, before SV_Physics, which runs the QuakeC PlayerPreThink (where the jump is), then gravity and the move; SV_ClientThink reads the on-ground flag the last move left, does nothing for a dead player or one with movetype none, and hands a water jump and a player at water level 2 or more (unless noclipping) to the water code.Code
Bunny hoppingBecause Quake runs friction in SV_ClientThink before the QuakeC jump in PlayerPreThink, and the on-ground flag is set by the walking move when it ends on a floor, a jump can come no sooner than the frame after landing, and that frame takes ground friction first: computed, a hop loses 4/72 of its horizontal speed (5.6%) at 72 frames a second above 100 units/s, or 8/72 (11.1%) when no floor lies within 34 units below a point 16 units ahead.Code
QuakeWorld's pmove.c checks the jump before friction: PlayerMove calls JumpButton, which clears onground, and then PM_Friction, whose ground friction runs only while onground is set, so a QuakeWorld hop on its first ground frame loses no speed to friction, where WinQuake's takes one frame of it (quake/hop-friction). Both still need the button released between jumps, and both add 270.Code
Demo playbackA Quake demo (.dem, WinQuake source) opens with a line of text, the CD track to force or -1, and then holds one block for each message the server sent, except one-byte keepalives (svc_nop), which are dropped: its length in 4 bytes, the client's three view angles as 4-byte floats, and the message itself. stop ends the recording with one last block holding a disconnect message.Code
A Quake demo records what the server told the client, not the player's inputs. Playing one first disconnects from any server, shutting down a local one, and the client then reads its server messages from the file instead of the network and parses them as live ones; the file's view angles set the view. No server runs during playback; the world arrives as the recorded messages.Code
Playback reads the next block only once the client's clock passes the time stamped in the last message (svc_time), so a demo plays at its recorded speed; timedemo instead reads one block a frame and reports frames, seconds, and frames per second. The file's closing disconnect ends the game, and while the attract loop runs the next demo of the startdemos list, up to 8, starts.Code
GravityQuake's gravity is the cvar sv_gravity, defaulting to 800, and each level's QuakeC worldspawn sets it to 800 again, or to 100 on E1M8; every frame a walking player is not in water (water level 2 or more) or a water jump, SV_AddGravity takes the entity's gravity field (1 when unset) × sv_gravity × frame time off its vertical velocity, on the ground as well as in the air.Code
JumpQuake's jump is QuakeC (1.01's client.qc): each frame PlayerPreThink calls PlayerJump while the jump button is held and otherwise sets FL_JUMPRELEASED; on land (water level under 2, not in a water jump), PlayerJump acts only when the player is on the ground and has released the button since the last jump, then clears both flags and adds 270 to the vertical velocity. Holding the button never jumps twice.Code
Computed from the jump and gravity, ignoring frame steps: a Quake jump from flat ground at the default gravity of 800 rises 270² / (2 × 800) ≈ 45.6 units and lands after 2 × 270 / 800 = 0.675 seconds.Code
RunningOn the ground, Quake's SV_UserFriction takes the horizontal speed and lowers it by frame time × friction × the larger of the speed and sv_stopspeed, to no less than 0, scaling all three velocity axes by the same factor; sv_friction defaults to 4 and sv_stopspeed to 100, and when a trace 16 units ahead along the motion finds no floor within 34 units below the feet, the friction is multiplied by edgefriction (default 2). A standing player is left alone.Code
Quake builds the wish velocity from the forward and side moves along the view's forward and right vectors (zero vertical for a walking player), caps its length at sv_maxspeed (default 320), and on the ground runs friction and then SV_Accelerate: if the speed along the wish direction is under the wish speed, it adds sv_accelerate (default 10) × frame time × wish speed along that direction, no more than the shortfall.Code
Computed from the friction and acceleration rules, not measured: because acceleration (10) outpaces friction (4), a Quake player on flat ground settles at exactly the wish speed, 320 units/s at a run; at the 72-frame rate a run from rest reaches it on frame 10 (0.14 s), and letting go from 320 comes to rest after 39 frames (0.54 s).Code
Strafe-runningQuake's keyboard moves are cl_forwardspeed and cl_backspeed 200 and cl_sidespeed 350, doubled by the run key (cl_movespeedkey 2.0), and the menu's "always run" sets forward and back to 400. Computed from these and the 320 cap: walking forward wishes 200, while a strafe alone (350), a walk with a strafe (√(200² + 350²) ≈ 403), and any run all wish 320.Code
In the air, Quake's SV_AirAccelerate takes the wish velocity's direction and length, caps that length at 30, and adds speed along the wish direction only while the velocity's component along it is under 30: the push is sv_accelerate × the uncapped wish speed (up to 320) × frame time, cut to the shortfall below 30. There is no friction in the air.Code
Computed from SV_AirAccelerate, not measured: with a wish speed of 320 the push can reach 10 × 320 × frame time (44.4 at 1/72 s, more at longer frames), so a frame lifts the velocity's component c along the wish direction to 30 whenever c is between −14.4 and 30, and the new speed is √(v² + 900 − c²) for speed v. That is largest with the wish at 90° to the motion: each frame then adds √(v² + 900) − v, 1.40 units/s at 320 and 0.90 at 500, and turns the motion by atan(30/v), 5.4° per frame at 320. At 72 frames a second that is about 101 units/s gained per second at 320.Code
QuakeWorld's PM_AirAccelerate keeps WinQuake's air rule unchanged: the wish speed capped at 30 for the shortfall test, and the push from the uncapped wish speed × acceleration × frame time; it adds only an early return for a dead player or a water jump.Code

References

  1. ^ abid Software's released Quake engine source numbers its single-player engine, WinQuake, as version 1.09 (VERSION in quakedef.h); the readme calls the release "the complete source code for winquake, glquake, quakeworld, and glquakeworld" and says the original DOS version "should also be buildable from these sources, but we didn't bother trying".Codeid-Software/Quake
    How we know
    26#define	VERSION				1.09
    
    WinQuake/quakedef.h line 26 at bf4ac42 · upstream ↗
    2This is the complete source code for winquake, glquake, quakeworld, and 
    3glquakeworld.
    
    readme.txt lines 2–3 at bf4ac42 · upstream ↗
    13The original dos version of Quake should also be buildable from these 
    14sources, but we didn't bother trying.
    
    readme.txt lines 13–14 at bf4ac42 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  2. ^ abcQuake's jump is QuakeC (1.01's client.qc): each frame PlayerPreThink calls PlayerJump while the jump button is held and otherwise sets FL_JUMPRELEASED; on land (water level under 2, not in a water jump), PlayerJump acts only when the player is on the ground and has released the button since the last jump, then clears both flags and adds 270 to the vertical velocity. Holding the button never jumps twice.Codeid-Software/Quake-Tools
    How we know
    972	if (self.button2)
    ⋮
    974		PlayerJump ();
    ⋮
    976	else
    977		self.flags = self.flags | FL_JUMPRELEASED;
    
    qcc/v101qc/client.qc lines 972–977 at c0d1b91 · upstream ↗
    773	if (self.flags & FL_WATERJUMP)
    774		return;
    ⋮
    776	if (self.waterlevel >= 2)
    
    qcc/v101qc/client.qc lines 773–776 at c0d1b91 · upstream ↗
    798	if (!(self.flags & FL_ONGROUND))
    799		return;
    ⋮
    801	if ( !(self.flags & FL_JUMPRELEASED) )
    802		return;		// don't pogo stick
    ⋮
    804	self.flags = self.flags - (self.flags & FL_JUMPRELEASED);
    ⋮
    806	self.flags = self.flags - FL_ONGROUND;	// don't stairwalk
    ⋮
    811	self.velocity_z = self.velocity_z + 270;
    
    qcc/v101qc/client.qc lines 798–811 at c0d1b91 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  3. ^ abQuake's host runs a frame only once at least 1/72 second has passed since the last, so the game steps at most 72 times a second; each frame's time step (host_frametime) is the real time since the last frame, clamped to 0.001–0.1 second, unless host_framerate fixes it, and a time demo skips the 1/72 wait.Codeid-Software/Quake
    How we know
    503	realtime += time;
    ⋮
    505	if (!cls.timedemo && realtime - oldrealtime < 1.0/72.0)
    506		return false;		// framerate is too high
    ⋮
    508	host_frametime = realtime - oldrealtime;
    ⋮
    511	if (host_framerate.value > 0)
    512		host_frametime = host_framerate.value;
    ⋮
    515		if (host_frametime > 0.1)
    516			host_frametime = 0.1;
    517		if (host_frametime < 0.001)
    518			host_frametime = 0.001;
    
    WinQuake/host.c lines 503–519 at bf4ac42 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  4. ^Quake builds the wish velocity from the forward and side moves along the view's forward and right vectors (zero vertical for a walking player), caps its length at sv_maxspeed (default 320), and on the ground runs friction and then SV_Accelerate: if the speed along the wish direction is under the wish speed, it adds sv_accelerate (default 10) × frame time × wish speed along that direction, no more than the shortfall.Codeid-Software/Quake
    How we know
    167cvar_t	sv_maxspeed = {"sv_maxspeed", "320", false, true};
    168cvar_t	sv_accelerate = {"sv_accelerate", "10"};
    
    WinQuake/sv_user.c lines 167–168 at bf4ac42 · upstream ↗
    342		wishvel[i] = forward[i]*fmove + right[i]*smove;
    ⋮
    344	if ( (int)sv_player->v.movetype != MOVETYPE_WALK)
    345		wishvel[2] = cmd.upmove;
    346	else
    347		wishvel[2] = 0;
    ⋮
    350	wishspeed = VectorNormalize(wishdir);
    351	if (wishspeed > sv_maxspeed.value)
    ⋮
    353		VectorScale (wishvel, sv_maxspeed.value/wishspeed, wishvel);
    354		wishspeed = sv_maxspeed.value;
    ⋮
    361	else if ( onground )
    ⋮
    363		SV_UserFriction ();
    364		SV_Accelerate ();
    
    WinQuake/sv_user.c lines 341–365 at bf4ac42 · upstream ↗
    190void SV_Accelerate (void)
    ⋮
    195	currentspeed = DotProduct (velocity, wishdir);
    196	addspeed = wishspeed - currentspeed;
    197	if (addspeed <= 0)
    198		return;
    199	accelspeed = sv_accelerate.value*host_frametime*wishspeed;
    200	if (accelspeed > addspeed)
    201		accelspeed = addspeed;
    ⋮
    204		velocity[i] += accelspeed*wishdir[i];	
    
    WinQuake/sv_user.c lines 190–204 at bf4ac42 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  5. ^On the ground, Quake's SV_UserFriction takes the horizontal speed and lowers it by frame time × friction × the larger of the speed and sv_stopspeed, to no less than 0, scaling all three velocity axes by the same factor; sv_friction defaults to 4 and sv_stopspeed to 100, and when a trace 16 units ahead along the motion finds no floor within 34 units below the feet, the friction is multiplied by edgefriction (default 2). A standing player is left alone.Codeid-Software/Quake
    How we know
    42cvar_t	sv_friction = {"sv_friction","4",false,true};
    43cvar_t	sv_stopspeed = {"sv_stopspeed","100"};
    
    WinQuake/sv_phys.c lines 42–43 at bf4ac42 · upstream ↗
    27cvar_t	sv_edgefriction = {"edgefriction", "2"};
    
    WinQuake/sv_user.c line 27 at bf4ac42 · upstream ↗
    132	speed = sqrt(vel[0]*vel[0] +vel[1]*vel[1]);
    133	if (!speed)
    134		return;
    ⋮
    136// if the leading edge is over a dropoff, increase friction
    137	start[0] = stop[0] = origin[0] + vel[0]/speed*16;
    ⋮
    140	stop[2] = start[2] - 34;
    ⋮
    144	if (trace.fraction == 1.0)
    145		friction = sv_friction.value*sv_edgefriction.value;
    146	else
    147		friction = sv_friction.value;
    ⋮
    150	control = speed < sv_stopspeed.value ? sv_stopspeed.value : speed;
    151	newspeed = speed - host_frametime*control*friction;
    ⋮
    
    WinQuake/sv_user.c lines 132–159 at bf4ac42 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  6. ^Computed from the friction and acceleration rules, not measured: because acceleration (10) outpaces friction (4), a Quake player on flat ground settles at exactly the wish speed, 320 units/s at a run; at the 72-frame rate a run from rest reaches it on frame 10 (0.14 s), and letting go from 320 comes to rest after 39 frames (0.54 s).Codeid-Software/Quake
    How we know
    150	control = speed < sv_stopspeed.value ? sv_stopspeed.value : speed;
    151	newspeed = speed - host_frametime*control*friction;
    
    WinQuake/sv_user.c lines 150–151 at bf4ac42 · upstream ↗
    195	currentspeed = DotProduct (velocity, wishdir);
    196	addspeed = wishspeed - currentspeed;
    ⋮
    199	accelspeed = sv_accelerate.value*host_frametime*wishspeed;
    200	if (accelspeed > addspeed)
    201		accelspeed = addspeed;
    
    WinQuake/sv_user.c lines 195–201 at bf4ac42 · upstream ↗
    42cvar_t	sv_friction = {"sv_friction","4",false,true};
    43cvar_t	sv_stopspeed = {"sv_stopspeed","100"};
    
    WinQuake/sv_phys.c lines 42–43 at bf4ac42 · upstream ↗
    167cvar_t	sv_maxspeed = {"sv_maxspeed", "320", false, true};
    168cvar_t	sv_accelerate = {"sv_accelerate", "10"};
    
    WinQuake/sv_user.c lines 167–168 at bf4ac42 · upstream ↗
    505	if (!cls.timedemo && realtime - oldrealtime < 1.0/72.0)
    
    WinQuake/host.c line 505 at bf4ac42 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  7. ^In the air, Quake's SV_AirAccelerate takes the wish velocity's direction and length, caps that length at 30, and adds speed along the wish direction only while the velocity's component along it is under 30: the push is sv_accelerate × the uncapped wish speed (up to 320) × frame time, cut to the shortfall below 30. There is no friction in the air.Codeid-Software/Quake
    How we know
    207void SV_AirAccelerate (vec3_t wishveloc)
    ⋮
    212	wishspd = VectorNormalize (wishveloc);
    213	if (wishspd > 30)
    214		wishspd = 30;
    215	currentspeed = DotProduct (velocity, wishveloc);
    216	addspeed = wishspd - currentspeed;
    217	if (addspeed <= 0)
    218		return;
    219//	accelspeed = sv_accelerate.value * host_frametime;
    220	accelspeed = sv_accelerate.value*wishspeed * host_frametime;
    221	if (accelspeed > addspeed)
    222		accelspeed = addspeed;
    ⋮
    
    WinQuake/sv_user.c lines 207–225 at bf4ac42 · upstream ↗
    361	else if ( onground )
    ⋮
    363		SV_UserFriction ();
    364		SV_Accelerate ();
    ⋮
    366	else
    367	{	// not on ground, so little effect on velocity
    368		SV_AirAccelerate (wishvel);
    
    WinQuake/sv_user.c lines 361–368 at bf4ac42 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  8. ^Computed from SV_AirAccelerate, not measured: with a wish speed of 320 the push can reach 10 × 320 × frame time (44.4 at 1/72 s, more at longer frames), so a frame lifts the velocity's component c along the wish direction to 30 whenever c is between −14.4 and 30, and the new speed is √(v² + 900 − c²) for speed v. That is largest with the wish at 90° to the motion: each frame then adds √(v² + 900) − v, 1.40 units/s at 320 and 0.90 at 500, and turns the motion by atan(30/v), 5.4° per frame at 320. At 72 frames a second that is about 101 units/s gained per second at 320.Codeid-Software/Quake
    How we know
    212	wishspd = VectorNormalize (wishveloc);
    213	if (wishspd > 30)
    214		wishspd = 30;
    215	currentspeed = DotProduct (velocity, wishveloc);
    216	addspeed = wishspd - currentspeed;
    ⋮
    220	accelspeed = sv_accelerate.value*wishspeed * host_frametime;
    221	if (accelspeed > addspeed)
    222		accelspeed = addspeed;
    
    WinQuake/sv_user.c lines 212–224 at bf4ac42 · upstream ↗
    168cvar_t	sv_accelerate = {"sv_accelerate", "10"};
    
    WinQuake/sv_user.c line 168 at bf4ac42 · upstream ↗
    505	if (!cls.timedemo && realtime - oldrealtime < 1.0/72.0)
    
    WinQuake/host.c line 505 at bf4ac42 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  9. ^ abQuake's gravity is the cvar sv_gravity, defaulting to 800, and each level's QuakeC worldspawn sets it to 800 again, or to 100 on E1M8; every frame a walking player is not in water (water level 2 or more) or a water jump, SV_AddGravity takes the entity's gravity field (1 when unset) × sv_gravity × frame time off its vertical velocity, on the ground as well as in the air.Codeid-Software/Quake · id-Software/Quake-Tools
    How we know
    44cvar_t	sv_gravity = {"sv_gravity","800",false,true};
    
    WinQuake/sv_phys.c line 44 at bf4ac42 · upstream ↗
    196	if (self.model == "maps/e1m8.bsp")
    197		cvar_set ("sv_gravity", "100");
    198	else
    199		cvar_set ("sv_gravity", "800");
    
    qcc/v101qc/world.qc lines 196–199 at c0d1b91 · upstream ↗
    381	eval_t	*val;
    ⋮
    383	val = GetEdictFieldValue(ent, "gravity");
    384	if (val && val->_float)
    385		ent_gravity = val->_float;
    386	else
    387		ent_gravity = 1.0;
    ⋮
    389	ent->v.velocity[2] -= ent_gravity * sv_gravity.value * host_frametime;
    
    WinQuake/sv_phys.c lines 381–389 at bf4ac42 · upstream ↗
    1089		if (!SV_CheckWater (ent) && ! ((int)ent->v.flags & FL_WATERJUMP) )
    1090			SV_AddGravity (ent);
    
    WinQuake/sv_phys.c lines 1089–1090 at bf4ac42 · upstream ↗
    858	return ent->v.waterlevel > 1;
    
    WinQuake/sv_phys.c line 858 at bf4ac42 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  10. ^Because Quake runs friction in SV_ClientThink before the QuakeC jump in PlayerPreThink, and the on-ground flag is set by the walking move when it ends on a floor, a jump can come no sooner than the frame after landing, and that frame takes ground friction first: computed, a hop loses 4/72 of its horizontal speed (5.6%) at 72 frames a second above 100 units/s, or 8/72 (11.1%) when no floor lies within 34 units below a point 16 units ahead.Codeid-Software/Quake · id-Software/Quake-Tools
    How we know
    612	SV_RunClients ();
    ⋮
    617		SV_Physics ();
    
    WinQuake/host.c lines 612–617 at bf4ac42 · upstream ↗
    387	onground = (int)sv_player->v.flags & FL_ONGROUND;
    
    WinQuake/sv_user.c line 387 at bf4ac42 · upstream ↗
    361	else if ( onground )
    ⋮
    363		SV_UserFriction ();
    364		SV_Accelerate ();
    
    WinQuake/sv_user.c lines 361–364 at bf4ac42 · upstream ↗
    1069	PR_ExecuteProgram (pr_global_struct->PlayerPreThink);
    
    WinQuake/sv_phys.c line 1069 at bf4ac42 · upstream ↗
    970	oldonground = (int)ent->v.flags & FL_ONGROUND;
    971	ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND;
    
    WinQuake/sv_phys.c lines 970–971 at bf4ac42 · upstream ↗
    284			if (trace.ent->v.solid == SOLID_BSP)
    ⋮
    286				ent->v.flags =	(int)ent->v.flags | FL_ONGROUND;
    
    WinQuake/sv_phys.c lines 284–287 at bf4ac42 · upstream ↗
    1033	if (downtrace.plane.normal[2] > 0.7)
    ⋮
    1035		if (ent->v.solid == SOLID_BSP)
    ⋮
    1037			ent->v.flags =	(int)ent->v.flags | FL_ONGROUND;
    
    WinQuake/sv_phys.c lines 1033–1037 at bf4ac42 · upstream ↗
    798	if (!(self.flags & FL_ONGROUND))
    799		return;
    
    qcc/v101qc/client.qc lines 798–799 at c0d1b91 · upstream ↗
    144	if (trace.fraction == 1.0)
    145		friction = sv_friction.value*sv_edgefriction.value;
    ⋮
    151	newspeed = speed - host_frametime*control*friction;
    
    WinQuake/sv_user.c lines 144–151 at bf4ac42 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  11. ^QuakeWorld's pmove.c checks the jump before friction: PlayerMove calls JumpButton, which clears onground, and then PM_Friction, whose ground friction runs only while onground is set, so a QuakeWorld hop on its first ground frame loses no speed to friction, where WinQuake's takes one frame of it (quake/hop-friction). Both still need the button released between jumps, and both add 270.Codeid-Software/Quake
    How we know
    889	if (pmove.cmd.buttons & BUTTON_JUMP)
    890		JumpButton ();
    891	else
    892		pmove.oldbuttons &= ~BUTTON_JUMP;
    ⋮
    894	PM_Friction ();
    
    QW/client/pmove.c lines 889–894 at bf4ac42 · upstream ↗
    674	if (onground == -1)
    675		return;		// in air, so no effect
    ⋮
    677	if ( pmove.oldbuttons & BUTTON_JUMP )
    678		return;		// don't pogo stick
    ⋮
    680	onground = -1;
    681	pmove.velocity[2] += 270;
    
    QW/client/pmove.c lines 674–681 at bf4ac42 · upstream ↗
    366	else if (onground != -1) // apply ground friction
    ⋮
    368		control = speed < movevars.stopspeed ? movevars.stopspeed : speed;
    369		drop += control*friction*frametime;
    
    QW/client/pmove.c lines 366–369 at bf4ac42 · upstream ↗
    1460	PlayerMove ();
    
    QW/server/sv_user.c line 1460 at bf4ac42 · upstream ↗
    361	else if ( onground )
    ⋮
    363		SV_UserFriction ();
    364		SV_Accelerate ();
    
    WinQuake/sv_user.c lines 361–364 at bf4ac42 · upstream ↗
    1069	PR_ExecuteProgram (pr_global_struct->PlayerPreThink);
    
    WinQuake/sv_phys.c line 1069 at bf4ac42 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

Sources

Code