Skip to content

Fix enchant_item button id: varint, not i8 (1.21 container rework)#1201

Open
atiweb wants to merge 1 commit into
PrismarineJS:masterfrom
atiweb:fix/enchant-item-button-varint
Open

Fix enchant_item button id: varint, not i8 (1.21 container rework)#1201
atiweb wants to merge 1 commit into
PrismarineJS:masterfrom
atiweb:fix/enchant-item-button-varint

Conversation

@atiweb

@atiweb atiweb commented Jun 18, 2026

Copy link
Copy Markdown

Problem

packet_enchant_item (vanilla ServerboundContainerButtonClickPacket) defines its enchantment field — the container button id — as i8. Since the 1.21 container rework the vanilla codec encodes it as a VarInt:

// ServerboundContainerButtonClickPacket, 1.21+
StreamCodec.composite(
  ByteBufCodecs.CONTAINER_ID, ::containerId,   // varint (plain VAR_INT in 1.21.1)
  ByteBufCodecs.VAR_INT,      ::buttonId,      // varint  <-- mcdata still has i8
  ::new)

minecraft-data already updated windowId to ContainerID (varint) for 1.21+, but left enchantment as i8 — an incomplete update of the same packet.

versions windowId enchantment (mcdata) jar button id
≤ 1.20.5 i8 i8 byte
1.21.1 – 1.21.11 ContainerID i8 VarInt

Before 1.21 both fields were a single byte (readByte/writeByte), so i8 is correct there — this only affects 1.21.1 – 1.21.11.

Impact

A VarInt and a byte encode identically for button ids below 128, so it seldom surfaces. But a button id ≥ 128 — e.g. a stonecutter or loom recipe index on a server with a large recipe set — needs a 2-byte VarInt that an i8 writer cannot represent. The packet is serverbound, so this affects any client encoding it.

Verification

Decompiled the official Mojang server jars: readByte/writeByte for both fields in 1.19.4 (pre-rework), and a VAR_INT button id in 1.21.1 (where the rework lands) and 1.21.3 / 1.21.5 / 1.21.6 / 1.21.8 / 1.21.9.

Change

enchantment: i8enchantment: varint in packet_enchant_item, for 1.21.1 → 1.21.11. proto.yml edited and protocol.json regenerated with npm run build (16 files, +16/−16; nothing else touched). node compileProtocol.js validate passes for all versions.

ServerboundContainerButtonClickPacket (minecraft-data packet_enchant_item) was reworked
in 1.21 to encode the button id as a VarInt. The vanilla codec is
StreamCodec.composite(CONTAINER_ID/VAR_INT, ::containerId, VAR_INT, ::buttonId). mcdata
updated windowId to ContainerID (varint) for 1.21+ but left enchantment (the button id)
as i8.

Before 1.21 both fields were a single byte (readByte/writeByte), so i8 is correct there;
this only affects 1.21.1-1.21.11.

A VarInt and a byte encode identically for button ids below 128, so it seldom breaks, but
a button id >= 128 (e.g. a stonecutter/loom recipe index on a server with many recipes)
needs a 2-byte VarInt that an i8 writer cannot represent. Serverbound.

Verified against the Mojang server jars: byte/byte in 1.19.4, VAR_INT button id in 1.21.1
and 1.21.3-1.21.9.

proto.yml edited, protocol.json regenerated with npm run build.
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