Skip to content

Fix world border speed: varlong, not varint (regressed in 1.19)#1200

Open
atiweb wants to merge 1 commit into
PrismarineJS:masterfrom
atiweb:fix/world-border-speed-varlong
Open

Fix world border speed: varlong, not varint (regressed in 1.19)#1200
atiweb wants to merge 1 commit into
PrismarineJS:masterfrom
atiweb:fix/world-border-speed-varlong

Conversation

@atiweb

@atiweb atiweb commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Problem

packet_initialize_world_border and packet_world_border_lerp_size both define their speed field (the border lerp time) as varint. In the vanilla client/server it is a VarLong:

// ClientboundInitializeBorderPacket / ClientboundSetBorderLerpSizePacket
private final long lerpTime;
this.lerpTime = buf.readVarLong();   // decode
buf.writeVarLong(this.lerpTime);     // encode

This is a regression. minecraft-data had speed correct as varlong in 1.17–1.18.2, but it was changed to varint in 1.19 and never corrected, so it has been wrong for every version from 1.19 through 1.21.11:

versions minecraft-data speed vanilla jar
1.17 – 1.18.2 varlong VarLong
1.19 – 1.21.11 varint VarLong

Impact

A VarInt and a VarLong encode to identical bytes for values below 2^28 (~74h expressed in ms), which is why this seldom surfaces. But a long border interpolation — a slow multi-day border shrink (/worldborder set <size> <seconds> with a large duration) — emits a VarLong that needs 5+ bytes, which a VarInt reader mis-parses (wrong value, then stream desync). These packets are clientbound, so it affects any consumer decoding them.

Verification

readVarLong/writeVarLong confirmed against the official Mojang server jars for 1.19.4 (where the regression begins) and 1.21.3 / 1.21.5 / 1.21.6 / 1.21.8 / 1.21.9; 1.17–1.18 already shipped the correct varlong.

Change

speed: varintspeed: varlong in both packets, for 1.19 → 1.21.11. proto.yml edited and protocol.json regenerated with npm run build (32 files, +64/−64; no other content touched). node compileProtocol.js validate passes for all versions.

ClientboundInitializeBorderPacket and ClientboundSetBorderLerpSizePacket encode the
border lerp time as a VarLong in vanilla (long lerpTime, writeVarLong/readVarLong).
minecraft-data had speed correct as varlong in 1.17-1.18.2, but it regressed to varint
in 1.19 and was never fixed - wrong for every version from 1.19 to 1.21.11.

VarInt and VarLong encode identically below 2^28 ms (~74h), so this only breaks on long
(multi-day) border interpolations, where the multi-byte VarLong mis-parses as a VarInt.
Verified readVarLong/writeVarLong against the Mojang server jars for 1.19.4 and 1.21.3-1.21.9.

1.19 and 1.19.2 also needed varlong re-declared as a native type (it had been dropped when
the field regressed to varint and nothing else used it); later versions already declare it.

proto.yml edited, protocol.json regenerated with npm run build.
@atiweb
atiweb force-pushed the fix/world-border-speed-varlong branch from 300231e to 964d484 Compare June 18, 2026 04:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant