Back to Devlog
    v0.9.23
    NetcodeSeptember 22, 2026Release notes

    Ping, Which Had Read Zero

    Moving geometry, lag-compensated hit registration, a menu that became the front door, player accounts opened by key, and the first matches that count.

    Ping, Measured

    LagCompensation had existed since v0.9.0 — and was wired only into a CLI harness. Every shot on the live server resolved against the present.

    It now rewinds to the view the shooter actually had, using a tick the client was already reporting and the server was already throwing away. 100ms maxCompensationMs.

    Two instruments came with it:

    text
    npm run test:lifts    walks every lift on every installed map and fails if one
                          cannot be called  -> found four dead lifts on wctf6
    
    npm run net:viewlag   holds frames in both directions over a real socket
                          -> found the interpolation assumption double-counting

    And ping, which had read 0 for every player since the field was introduced, is measured.

    Movable Geometry

    func_plat and vertical func_door are simulated, collided, predicted, heard, and crush whoever blocks them — one fixed-step system shared by server, client prediction and single-player, so "a rider is carried by the same code everywhere".

    A Networking Audit, Not A Feature

    Snapshots never said which state they were deltaed against, so a dropped datagram — or merely an ACK still in flight — could leave a component silently wrong until it happened to change again. Fixed at the protocol level. Snapshots are now message 0x0B; 0x04 is the old envelope, kept only for reading old data.

    One shape behind a family of replay bugs:

    something that should have been a function of which simulation step this is was
    instead counted per call, and reconciliation counts the same steps more than once.

    Knockback drag never ran on a live client at all.

    Drawing Less

    World culled by compiled PVS, players culled and quieted with it, autosprites stop rewriting vertices nothing moved.

    Spatial batching was cut. It removes a third to a half of the triangles and costs about 20% more frame time, so r_bsp_cellsize stays off — with 36 captures behind the decision.

    One thing was added rather than trimmed: tiered impact sparks, so a machinegun round stays quiet and the flourish is kept for weapons that hit once and hard.

    The Menu Became The Front Door

    A gold rail, one stage beside it, and rooms you can actually get into.

    Player accounts opened by a key rather than a password, so a name belongs to somebody. Rooms can be private, with an invite only a link carries. Rooms have their own chat.

    Amphi arrives as the mode the lobby leads with: 1v1, three rounds, a kit you pick and live with.

    Matches that count. A seat is a signed ticket, the child server signs the result it reports, the lobby stores it once, and the leaderboard counts only matches most of whose room was people.

    The Seven-Bot Bug Hunt

    docs/research/v0.9.23-bughunt.md — mostly about other players. They were the only bodies in the map exempt from culling, dead-reckoned through walls when a packet arrived late, shared a single skeleton between them, and the trail on the rocket you fired at them collapsed to a flat sliver "in the one case that matters — shooting along the axis you are looking down."

    Known Unverified Items

    Long, and mostly unflattering, so here is the shape of it:

    • The lobby has never been used by two people at once, and no ranked result

    between two humans has ever appeared on the board in front of anyone.

    • The menu has had no accessibility or real-display pass.
    • The placement bug is "believed fixed, not proven fixed" — no controlled

    reproduction was ever built. cl_remotehitbox 1 is the cheap discriminating test still worth running.

    • Two fixes failed to hold: the lower-floor rocket launcher and the tab-return

    camera were both reported still broken. "Each fix closed a real defect … but neither was the cause of what was reported."

    • A player froze mid-match while the server ran on and "What stalls the connection is

    not known."

    • Only hitscan is rewound — projectiles still spawn against the present.
    • Bots do not use ladders; ladder climbing is unreachable on 35 of 39 installed

    maps.

    • Client presentation is frame-rate dependent; uncapped frame rates are not a

    supported configuration.

    • Babylon's per-frame CPU counters cannot be trusted as totals. 9.17

    PerfCounter.endMonitoring(false) assigns its current duration rather than accumulating; cpuRenderMs reads 0-0.1ms and activeMeshes reads zero.

    One Deliberate Choice

    Under-compensating a jittery connection is intentional, "since erring high punishes the player who took cover."