A Slow Frame Shouldn't Move You Back
Fewer movement corrections at low frame rates, better recovery from stalled connections, visible download progress, and a performance pass that gives Firefox more room to breathe.
A Slow Frame Was Becoming a Wrong Step
If the browser struggled to draw the fight, the server could make moving through it harder too.
The client sends its movement commands in a burst once per rendered frame. The server accepted at most four new commands per tick. Below about 30 FPS, that was not enough: at 25 FPS, a fifth of a player's movement was silently dropped. Each dropped command became a correction on the player's screen.
The flood guard now accepts up to 64 commands per tick. The simulation still consumes one command per tick, so sending faster does not let a player gain time. It lets a slower browser deliver the movement it already recorded.
When the Connection Pauses
A stalled connection used to produce a particularly unpleasant double act. The server repeated your last input while waiting, then trimmed the commands that arrived late. Your own prediction and the server's guesses could push you forward and pull you back.
After the first two ticks without input, a server guess now stands in for the next client command and acknowledges it. If that command arrives late, it is discarded instead of being played again. What remains to correct is where the guess differed from what you actually did.
The input buffer grows from six to 12 commands. A queue that stays deep for a full second sheds one command, so a brief stall does not leave a permanent delay. The client also keeps up to 250 ms of frame time for command generation, up from 100 ms, to ride out ordinary shader or garbage-collection hitches.
The Fight Had a Spare Renderer
Opening the kit picker could race two builds of its weapon preview. Closing it disposed only one. The other kept drawing to a detached canvas throughout the match: another WebGL context, another scene, every frame.
That renderer is gone. In the measured six-bot Firefox match, this fix alone reduced frame intervals from about 41 ms to 34 ms.
The rest of the pass removes repeated work:
- Lightmapped map materials stop re-deriving their shader settings on every draw, while still responding to changing gameplay lights.
- Projectile trails update their existing geometry and share materials instead of creating hundreds of temporary vectors per frame.
- Explosions reuse prepared shapes; spawning one costs about half as much script time.
- Finished rocket, grenade and plasma shots are reused whole, including their models and trails. Their measured lifetime script cost falls to about a twelfth.
Across the live six-bot Firefox check, heavy-combat frame rate rose from about 24 to 40 FPS. That is the result of this test, not a promise for every machine. Firefox still has more per-frame script overhead than Chromium.
Tell Me What Is Downloading
Startup and map-loading screens now show active package transfers above the main loading bar: the filename, received and total megabytes, transfer speed, and a separate progress bar.
Concurrent downloads, waiting for a response, retries and archive preparation are visible too. If the server does not supply a file size, the screen shows received bytes instead of inventing a percentage.
One Input Fix Still Needs a Linux Check
Under mouse capture, movement events that change no button no longer overwrite the held-button state. A platform reporting an empty button mask could otherwise end aiming or Voltaic fire on the first mouse flick.
That fits the reported Linux behavior, but the fix has not yet been confirmed on a Linux machine. The standalone crowd benchmark's package path is fixed as well; the investigation notes retain the measurements and remaining work.