How accurate are the presets?¶
The four engine presets were built by reading the original engine source, not by copying numbers from wikis. Some of the values look like mistakes until you see where they come from.
Every citation below is a file and line in the published source for that engine.
Quake 2 is not "Quake 1 but newer"¶
Three values differ from what almost every reference says:
| Commonly quoted | Actually in the source | |
|---|---|---|
| Max speed | 320 | 300 (qcommon/pmove.c:54) |
| Friction | 4 | 6 (qcommon/pmove.c:59) |
| Ducked view height | 4 | -2 (qcommon/pmove.c:1020) |
The ducked view height is a mix-up: 4 is the ducked hull's top (maxs[2], line 1019).
The eye height on the next line is -2.
The friction difference is the one you feel. Quake 2 at 6 is stickier than Quake or Half-Life at 4.
Quake 2 cannot air-strafe, by design¶
pm_airaccelerate defaults to 0 (qcommon/pmove.c:57), and the server forces it to
0 outside deathmatch regardless of the cvar (server/sv_init.c:197-205). Single-player
Quake 2 has no strafe-jumping at all.
But 0 doesn't mean "no air control". When air acceleration is off, Quake 2 falls through
to ordinary ground-style acceleration with a coefficient of 1
(qcommon/pmove.c:654-657):
if (pm_airaccelerate)
PM_AirAccelerate (wishdir, wishspeed, pm_accelerate);
else
PM_Accelerate (wishdir, wishspeed, 1);
Those two functions differ by one line: PM_AirAccelerate clamps the target to 30
units and PM_Accelerate does not. That clamp is what makes strafe-jumping possible
(why), so without it you get weak air
steering that dies at full speed.
SUCC returns early once its air cap is reached, so air_acceleration = 0.0 would give
zero air control, stricter than the real game. The preset uses 1.0 with the air cap
raised to full max_speed instead, reproducing what Quake 2 actually does.
Half-Life 2 walks at 190, not 320¶
sv_maxspeed is 320 in Source, and that's the number usually cited. It's only a ceiling.
CHL2_Player::SetupMove picks the real speed from one of three cvars
(game/server/hl2/hl2_player.cpp:86-88):
hl2_walkspeed, 150hl2_normspeed, 190hl2_sprintspeed, 320
then CheckParameters takes the smaller of that and sv_maxspeed
(game/shared/gamemovement.cpp:996-999). So HL2 walks at 190, and 320 is what holding
sprint gets you.
Two more HL2 values worth noting:
- Gravity is 600, not 800 (
game/shared/movevars_shared.cpp:19-20). This is why HL2 feels floaty. - The jump impulse is a hardcoded
160.0(game/shared/gamemovement.cpp:2435), not thesqrt(2 * gravity * 21)the surrounding code implies, which would be 158.745.
source.tres encodes all three: max_speed 190 units, sprint_speed_modifier 1.6842 so
sprint lands exactly on 320, gravity 600, jump 160. The 150-unit slow walk has no SUCC
equivalent.
QuakeWorld's air acceleration setting does nothing¶
QuakeWorld registers sv_airaccelerate with a default of 0.7
(QW/server/sv_phys.c:49) and even sends it to clients over the network. Nothing ever
reads it. PM_AirMove passes the ground acceleration value instead
(QW/client/pmove.c:548):
Quake 2 has the same bug (qcommon/pmove.c:655). Source is the only one of the four that
genuinely uses its own air acceleration cvar. quake.tres therefore uses 10, the ground
value, because that's what the engine really applies.
Contrary to a common claim, NetQuake does have the 30-unit air clamp
(WinQuake/sv_user.c:207-226). Strafe-jumping is not a QuakeWorld addition. The only
difference is the unused cvar.
GoldSrc values come from the engine, not the SDK¶
The Half-Life engine is closed source. Only two movement values are set by the game DLL
(dlls/world.cpp:482-483): gravity 800 and step size 18.
sv_maxspeed, sv_accelerate, sv_airaccelerate, sv_friction and sv_stopspeed are
read through pmove->movevars->* and have no default anywhere in the published SDK. The
320 / 10 / 10 / 4 / 100 in goldsrc.tres are the well-known engine defaults, not values
from this source tree.
Two GoldSrc specifics goldsrc.tres does not model:
PM_PreventMegaBunnyJumpingcrops your velocity to 65% once you exceed 1.7× max speed (pm_shared/pm_shared.c:2436-2466). Half-Life actively punishes bunnyhopping; SUCC doesn't reproduce that.PLAYER_DUCKING_MULTIPLIERof 0.333 is applied to the move input rather than the speed cap (pm_shared/pm_shared.c:123).
Everything is measured in inches¶
All four engines use 1 unit ≈ 1 inch, though only two places in the source say so
outright: halflife/dlls/world.cpp:482 comments gravity 800 as "67ft/sec", and
source-sdk-2013/src/game/shared/shareddefs.h:409-410 writes a fall speed as
sqrt(2 * gravity * 60 * 12), the * 12 being inches to the foot.
SUCC uses 39.37 units per metre, Source's own approximation. The exact value is 39.3701, a 0.03% difference, and Valve's number is what the original cvars were tuned against.
The origin sits in a different place¶
Quake, QuakeWorld, Quake 2 and GoldSrc put the player's origin at mid-body, so their hull minimums are negative. Source moved it to the feet.
SUCC's collision box is anchored at the feet like Source, so eye heights for the older
engines are converted: view_offset + abs(hull_min_z). GoldSrc's 28 becomes 64; Quake's
22 becomes 46. If you compare quake.tres against a Quake source dump and the eye
heights look wrong, that's why.
Jump heights are back-solved¶
SUCC's config takes a jump height and works out the impulse as
sqrt(2 * gravity * jump_height). The engines specify the impulse directly. So each
preset's jump_height is solved backwards from the real impulse rather than copied from
the engine's nominal jump-height constant:
| Preset | Real impulse | Back-solved height |
|---|---|---|
goldsrc.tres |
268.33 (sqrt(2*800*45)) |
45 units |
quake.tres |
270 | 45.5625 units |
quake2.tres |
270 | 45.5625 units |
source.tres |
160 | 21.333 units |
Note the last row: HL2's hardcoded 160 does not correspond to its own
GAMEMOVEMENT_JUMP_HEIGHT of 21, so the real height is 21.33.
Checking it yourself¶
Every preset's values round-trip back to these engine numbers exactly. If you want to
verify, load a config and multiply by SUCCConfig.SOURCE_MULT: