• v3.1.0 8421da7557

    v3.1.0
    All checks were successful
    ci / ci (push) Successful in 21s
    release / release (push) Successful in 2s
    Stable

    yuris released this 2026-08-22 05:12:38 +00:00 | 9 commits to main since this release

    Gzip frames are decoded, and connect asks the server for them. Additive: nothing
    a caller writes changes, and the only new option, inflate, defaults to the
    ambient builtin.

    Features

    Gzip frames on the v2 BSATN wire

    The server compresses any message over 1KiB and its default scheme is brotli,
    which is why connect had always pinned ?compression=None - an omitted
    parameter is a wire no Defold build can read. It now appends
    ?compression=Gzip when a gunzip is in reach and ?compression=None when it is
    not, so a session that cannot inflate still gets a readable wire instead of a
    broken one; the parameter is never omitted. On the v1 JSON wire it changes
    nothing at all - measured identical across None, Brotli and Gzip - so v1
    passes no gunzip.

    Decoding lives in decode_server(data, inflate) in stdb/protocol_v2.lua. The
    compression byte replaces the message's leading byte rather than prefixing the
    stream, so the gzip magic sits at byte 2 and the plaintext is the
    ServerMessage from its sum tag. The gunzip arrives as an argument instead of a
    reach for the zlib global, which keeps the module free of engine APIs;
    stdb/init.lua resolves the ambient zlib.inflate the same way the builder
    resolves json, and opts.inflate substitutes for it. Brotli raises by name
    (brotli frame; Defold has no brotli decoder) rather than behind a generic
    "compressed frame" message: the engine ships zlib and no brotli, so it is a wire
    this client cannot read, not a feature nobody got round to.

    zlib.inflate only learned to sniff the 1f 8b wrapper and strip it in Defold
    1.12.4 (engine/dlib/src/dlib/zlib.cpp); 1.12.3 has no gzip path at all, so
    1.12.4 is the floor this release documents. Bandwidth, measured against 2.8.2 on
    the v2 wire: a 33 KiB subscription readback arrives in 14,526 B of 33,338 B, a
    479 KiB one in 203,745 B of 478,921 B. Below the 1KiB threshold nothing changes,
    so the ordinary per-transaction update is untouched - this earns its keep on the
    initial subscription and nowhere else.

    What's Changed

    • docs: point the install URLs at v3.1.0 in #108
    • decode gzip frames, and ask the server for them in #107
    • patches: carry upstream PR 68 instead of our narrower fix in #106
    • README: state, not usage, in the features table; drop the 2.x migration guide in #105

    Full Changelog: v3.0.0...v3.1.0

    Use as a Defold library

    Add to game.project dependencies:

    https://git.nokopia.com/yuris/spacetimedb-defold/archive/v3.1.0.zip
    https://github.com/defold/extension-websocket/archive/refs/tags/4.2.3.zip
    

    extension-websocket is required: Defold does not resolve dependencies
    transitively, so without it connect fails at runtime.

    Targeting HTML5? 4.2.3 drops the subprotocol there, so it needs the
    patch in patches/ AND the remote dependency above removed - keeping
    both puts two websocket extensions in one build and the link fails.
    The README has the four commands.

    Private repo? Append ?token=<access-token> to the URL, the same
    shape Defold documents for GitLab. Basic auth in the URL
    (https://user:token@...) is not a substitute: the archive endpoint
    ignores URL credentials - a real account with a wrong password still
    gets 200 on a public repo - while ?token= is validated and a bad
    one gets a plain 401.

    Downloads