A gameplay update asked for by the owner: A/D strafing up, W-only air control down, quick dash as a shorter cooldown, a super dash hop that scales with the look angle, a lighter sniper body shot. It also fixes the six gameplay and visual bugs the 1.18.0 performance audit found and left for the owner's call (five fixed here; the frame-rate-dependent view-model kick was already fixed in 1.18.0).
- Network protocol unchanged (42). Nothing on the wire changed, so 1.18.x games and servers can connect to each other. But movement runs on both ends (client prediction, server authority), so an older 1.18 client on a 1.18.2 server, or the other way round, mispredicts A/D strafing, the quick-dash cooldown and the super dash hop, and gets corrected (rubber-banding) by the server. Balance changes have never bumped the protocol (rocket gravity, rifle damage, the 1.17 W-only air-control change); dedicated servers move to the new version when it reaches production.
- Demos are unaffected.
Movement (src/game/pmove.cpp)
A/D air strafing: cap +10%, acceleration +15% (owner)
- Owner: "increase ad strafing limit by 10% and increase rate of speed increase from ad strafing by 15%".
- Cap: the Quake-style air wish-speed cap
kAirSpeedCap(2.3) is multiplied by a newkStrafeCapAD = 1.1while a strafe key is held (cmd.side != 0): 2.53. W-only keeps 2.3. - Acceleration: a new
kStrafeAccelAD = 1.15multiplies air acceleration while a strafe key is held, on top of the existingkStrafeBoostramp (+10%, ramping in from 12.65 m/s). - Together the push square to your momentum is 1.265x what it was (1.1 x 1.15): 0.0506 to 0.0640 m/s per ms below 12.65 m/s, 0.0557 to 0.0704 at full boost. The turn rate this gives at a given speed: 5.06 to 6.40 rad/s at 10 m/s, 3.48 to 4.40 at 16, 1.74 to 2.20 at 32.
- The point where the A/D boost starts (
cross, 12.65 m/s) is still worked out from the base cap 2.3 and the unscaled air control 4, so neither change moves it. - Measured with the game's movement code (1 ms steps, the best of 181 yaws each ms, starting at run speed 9.5 m/s):
| Perfect strafe-jumping | Before | After |
|---|---|---|
| after 1 s | 18.18 m/s | 20.70 m/s |
| after 2 s | 24.11 m/s | 27.87 m/s |
| after 4 s | 32.88 m/s | 38.35 m/s |
| after 8 s | 45.56 m/s | 53.39 m/s |
- At fixed turn rates (D + jump, 2 s): 30 deg/s 12.10 to 12.38 m/s; 90 deg/s 16.73 to 17.49; 180 deg/s 19.70 to 24.56; 360 deg/s 9.15 to 10.70. Overstrafing hard (720 deg/s) costs a little more: 6.65 to 6.30, because the bigger push also brakes harder past the window.
W-only air control 10% slower (owner)
- Owner: "reduce w strafing by 10%".
- A new
kAirControlW = 0.9multiplies the CPM-style forward/back air control rate (the turn toward where you look, speed kept, used only while no strafe key is held): min(4, 38 / speed) rad/s becomes 0.9 x that. So 4.0 to 3.6 rad/s under 9.5 m/s, 3.80 to 3.42 at 10 m/s, 2.375 to 2.138 at 16, 1.19 to 1.07 at 32. Measured toward a target 30 degrees off at 16 m/s: 68.1 to 61.3 deg/s. crossagain uses the unscaled 4, so the A/D boost ramp doesn't move.
Quick dash: a shorter cooldown instead of a third charge (owner)
- Asked whether quick dash should get its shorter cooldown back, the owner said: "quick dash should reduce dash cooldown".
- Before 1.17 quick dash recharged the dash 3x faster; 1.17 changed it to a third charge with the normal 1.2 s cooldown. Now it's back to a third of the cooldown: a new
kQuickDashCooldown = 1/3gives 400 ms (times a custom mode's DASH COOLDOWN multiplier), and charges are the normal 2. - On the floor, pressing dash repeatedly for 4 s: the cooldown allows a dash every ~1.2 s plus the dash itself (unchanged); quick dash about twice as many (was the third charge with 1.2 s). (Corrected in 1.18.7: holding dash gives one dash, since a dash needs a fresh press.) In the air from full charges: 2 dashes either way, then none until you land.
dashCooldownMs()takes the player's movement modifiers now, so the HUD's dash pips fill over 0.4 s with quick dash (they filled to a third, then lit).- The BLADES arena rule reads "KNIVES ONLY - DASH COOLDOWN 0.4 S" (was "A THIRD DASH CHARGE").
Super dash: the hop rises the further down you look (owner)
- Owner: "in the hyper dash the lower you look (more directly into the ground) the higher you should bounce".
- The hop was always half a jump (
kSuperDashJump = 0.5, 0.31 m). Now its share of the jump speed is 0.5 + 0.5 x t, with t going linearly from 0 at the super-dash threshold (the dash aimed 0.25 of the way down, 14.5 degrees) to 1 looking straight down (a newkSuperDashJumpMax = 1.0, a full 1.22 m jump). t is in terms of the dash's vertical share (the sine of the look angle). A custom mode's SUPER DASH JUMP multiplier scales both ends. Speed is unchanged.
| Look down | Hop speed | Hop height |
|---|---|---|
| 14.5 deg (threshold) | 3.67 m/s | 0.31 m (as before) |
| 20 deg | 4.12 m/s | 0.39 m |
| 30 deg | 4.89 m/s | 0.54 m |
| 45 deg | 5.91 m/s | 0.79 m |
| 60 deg | 6.68 m/s | 1.02 m |
| 88.8 deg (the mouse's limit) | 7.34 m/s | 1.22 m |
- Prediction matches: the dash's vertical share (
dashUp) is already in the own movement state while a dash runs, the only time a super dash can happen. - The map report's take-off envelope (the worst-case reach the map checks use) now super dashes at 88.8 degrees, where the hop is highest.
docs/MAP_REPORT.mdis regenerated: its movement envelope had not been rebuilt since the dash cooldown came back in 1.17.0, so its reach numbers drop to what the movement really allows (e.g. rise at 9.5 m/s 8.9 to 4.2 m). Every map still passes. - The in-game tip says the hop gets higher the further down you look (it said "a low hop").
Weapons (src/game/gamedefs.h)
Sniper body shot 40 (owner)
- Owner: "make sniper body shot do 40". Body 50 to 40; headshot stays 50 (
kSniperHeadDamage; the server takes the larger of body and head damage, so a headshot is exactly 50). Instagib still kills with any hit (it sets damage to health + 1). - Time to kill from 100 hp with perfect aim: 3 body shots in 3.0 s (was 2 in 1.5 s), or 2 headshots in 1.5 s. DPS against the laser's 40: 0.83 to 0.67 on the body, 0.83 on the head.
Fixes (the 1.18.0 audit's gameplay bugs; owner: fix all six)
- Tag knockouts carried into the next match:
Server::tagOut_was only ever added to, so in a second tag match on the same server everyone knocked out earlier was out at once. It is now cleared instartMatch(which covers a forcestart mid-match too) and inrulesReset. Test:rules tagplays a match out and starts another, then knocks someone out and forcestarts; everyone is back in both times. - Payload cart collision box at the wrong end (Railyard, team B's rounds on maps without staged spawns): the server's
updateCartSolidand the client's prediction (NetClient::reconcile) placed the box with the cart's distance but not the track direction for the attacking team, 48.8 m from the drawn cart. Both now place it throughMap::cartTrack, like everything else that places the cart. Test:rules cartboxchecks both boxes are within 5 cm of the visible cart in rounds 1 and 2, and a shot onto the visible cart hits it. - Cart shadow baked into the cached lighting: the light bake copied the map with the cart's collision box, so its shadow where the cart was at join time stayed in the cache. The bake copy now drops moving solids;
kBakeVersion11 to 12, so each map re-bakes once. - Translucent parts of custom weapon models never drawn in first person: the view model now collects its translucent triangles into their own list, uploaded with the world's translucent ones in the same single upload, and drawn after the gun's opaque parts (blended, no depth writes, with the view model's projection). Without translucent parts the only extra work is one size check per frame. Checked with headless screenshots with no overrides, partly translucent and fully translucent models.
- An announcer line could be cut when 64 sounds played: dropping "the oldest" took the first voice in the list, but the mixer's swap-and-pop removal scrambles the order. Each voice now records when it started; when the mixer is full one pass over the 64 drops the oldest sound effect, and an announcer line only if every voice is one. Nothing changes until the mixer is full. Test:
assetsfills the mixer, lets a short sound end so the announcer line moves to the front, overflows it, and checks the line keeps playing. - View-model kick frame-rate dependent: already fixed in 1.18.0 (it recovers 8 per second), no change.
- HUD dash pips with quick dash: see Quick dash above.