diff --git a/00-overview.md b/00-overview.md index 79e579c..64429ec 100644 --- a/00-overview.md +++ b/00-overview.md @@ -70,8 +70,8 @@ if (chunk.length >= this.compressionThreshold) { ### 2.3 Packet size limits - Uncompressed maximum: **2²¹ − 1 = 2,097,151 bytes** (the `Length` VarInt may not exceed 3 bytes on the wire). — [minecraft.wiki](https://minecraft.wiki/w/Java_Edition_protocol) -- Serverbound compressed: uncompressed (Packet ID + Data) must be ≤ 2²³ bytes (8,388,608). -- Plugin message unrecognised-channel data: vanilla client caps at 1,048,576 bytes. +- Serverbound compressed: uncompressed (Packet ID + Data) must be ≤ 2²³ bytes (8,388,608). Source: [minecraft.wiki/w/Java_Edition_protocol/Packets](https://minecraft.wiki/w/Java_Edition_protocol/Packets) — "For serverbound packets, the uncompressed length of (Packet ID + Data) must not be greater than 2^23 or 8388608 bytes." (node-minecraft-protocol's decompressor does not enforce this cap; Velocity's `MinecraftCompressDecoder` caps serverbound at 2 MiB for security, vanilla at 8 MiB clientbound — `MinecraftCompressDecoder.java:39-40`.) +- Plugin message unrecognised-channel data: vanilla client caps at 1,048,576 bytes. Source: [minecraft.wiki/w/Java_Edition_protocol/Packets](https://minecraft.wiki/w/Java_Edition_protocol/Packets); corroborated by Velocity `PluginMessagePacket.java:65` (`MAX_PAYLOAD_SIZE_CLIENTBOUND = 1048576`, comment: "the vanilla expected limit"). --- @@ -127,7 +127,7 @@ if (packet.nextState === 1) { } ``` -`nextState = 3` (Transfer) was added in **1.20.5** for server-transfer support. +`nextState = 3` (Transfer) was added in **1.20.5 (protocol 766)** for server-transfer support. Source: Velocity `HandshakeIntent.java:16` (`TRANSFER(3)`); `ProtocolVersion.java:89` (`MINECRAFT_1_20_5(766, "1.20.5", "1.20.6")`); ViaVersion `InitialBaseProtocol.java:55,133` (`TRANSFER_INTENT = 3`, rejected for servers `olderThan(ProtocolVersion.v1_20_5)`). ### 3.2 Status diff --git a/01-data-types.md b/01-data-types.md index 0946e8d..3658d83 100644 --- a/01-data-types.md +++ b/01-data-types.md @@ -174,7 +174,7 @@ Bits 37–26 : y (12 bits) Bits 25–0 : z (26 bits) ``` -**Breaking change in 1.14** — any code parsing Position must branch on the protocol version. +**Breaking change in 1.14 (protocol 477)** — any code parsing Position must branch on the protocol version. Source: `minecraft-data/data/pc/1.14/version.json` → `"version": 477`; confirmed by minecraft-data protocol.json comparison: 1.13 (`version: 393`) defines `position` as `x(26)|y(12)|z(26)`; 1.14 (`version: 477`) redefines it as `x(26)|z(26)|y(12)`. Source: [minecraft.wiki/w/Java_Edition_protocol/Data_types](https://minecraft.wiki/w/Java_Edition_protocol/Data_types). @@ -364,9 +364,9 @@ Bit `i` is set when: | 1.7.x | 4–5 | Baseline modern framing introduced (replaced legacy 0xFE ping) | | 1.8 | 47 | Whole-packet compression (`Set Compression`) added | | 1.9 | 107 | Protocol overhaul; many packet IDs changed | -| 1.14 | 477 | `Position` bit layout changed (y and z swapped) | +| 1.14 | 477 | `Position` bit layout changed: z and y swapped (now x/z/y). Source: `minecraft-data` 1.13 vs 1.14 `protocol.json` bitfield definitions; `minecraft-data/data/pc/1.14/version.json` | | 1.20.2 | 764 | `Configuration` state added; NBT root compound name dropped from network NBT | -| 1.20.5 | 766 | `Transfer` intent (nextState=3) added to Handshake | +| 1.20.5 | 766 | `Transfer` intent (nextState=3) added to Handshake. Source: Velocity `HandshakeIntent.java:16`; ViaVersion `InitialBaseProtocol.java:55,133` | --- diff --git a/02-connection-lifecycle.md b/02-connection-lifecycle.md index f17c3d0..6b1a7ee 100644 --- a/02-connection-lifecycle.md +++ b/02-connection-lifecycle.md @@ -69,7 +69,7 @@ Fields: - `nextState` — VarInt enum: - `1` → STATUS - `2` → LOGIN - - `3` → LOGIN after server transfer (≥1.20.5 / protocol 766) + - `3` → LOGIN after server transfer (≥1.20.5 / protocol 766). Source: Velocity `HandshakeIntent.java:16` (`TRANSFER(3)`), `StateRegistry.java:883` (`TRANSFER_ID = 3`), `ProtocolVersion.java:89` (`MINECRAFT_1_20_5(766, "1.20.5", "1.20.6")`); ViaVersion `InitialBaseProtocol.java:133` rejects intent=3 for servers older than v1_20_5. The server reads `nextState` and immediately switches its decoder to the corresponding state. There is no server response in the Handshaking state. @@ -247,7 +247,7 @@ Source: `node-minecraft-protocol/src/client/play.js:43-55` - **Algorithm**: AES-128-CFB8, symmetric, both directions use the same 16-byte shared secret. - **Key exchange**: RSA (server's ephemeral keypair, ≥1024-bit); client encrypts shared secret and verify token with server's public key. - **Activation point**: immediately after Encryption Response is sent/received — before the next byte on the wire. Encryption applies to all subsequent data including Set Compression and Login Success. -- **Online-mode only** (vanilla): offline-mode servers skip the Encryption Request/Response entirely. As of 1.21, vanilla offline-mode servers do not use encryption. +- **Online-mode only** (vanilla): offline-mode servers skip the Encryption Request/Response entirely. This is version-independent behaviour — node-minecraft-protocol gates the entire Encryption Request/Response exchange on `needToVerify` (`server/login.js:52,88`), with no protocol-version branch. - Source: `node-minecraft-protocol/src/client/encrypt.js` (client), `node-minecraft-protocol/src/server/login.js:88-155` (server) --- @@ -280,8 +280,10 @@ Sources: Velocity `StateRegistry.java` import block (lines 21-50); minecraft.wik --- -## VERIFY flags +## Resolution notes (formerly VERIFY flags) - - - +**intent=3 (Transfer) minimum version — CONFIRMED** ≥1.20.5 (protocol 766). Sources: Velocity `HandshakeIntent.java:16`, `StateRegistry.java:883`, `ProtocolVersion.java:89`; ViaVersion `InitialBaseProtocol.java:55,133`. Distinction: the *Handshake intent=3* is a serverbound signal from the transferring client; the *Transfer clientbound packet* (Play state, 0x73 in 1.20.5/1.21) is what the originating server sends to instruct the client to reconnect. Both ship in 1.20.5. Velocity registers the clientbound `TransferPacket` from `MINECRAFT_1_20_5` in both CONFIG (0x0B) and PLAY (0x73) state (`StateRegistry.java:239-240, 819-821`). + +**offline-mode encryption "as of 1.21" — UNCONFIRMED** (see §8 note). Behaviour is version-stable; no source found for a 1.21-specific change. + +**CONFIG packet IDs shift between 1.20.2 / 1.20.3 / 1.20.5 — CONFIRMED** true. Velocity `StateRegistry.java:163-261` documents the shifts (e.g. `Disconnect` stays 0x01 in 1.20.2, shifts to 0x02 in 1.20.5; `FinishConfiguration` shifts from 0x02→0x03). These are Velocity's values; vanilla wiki IDs may differ per-snapshot but the shift pattern is confirmed. diff --git a/03-handshake.md b/03-handshake.md index 1aef056..23b2450 100644 --- a/03-handshake.md +++ b/03-handshake.md @@ -91,9 +91,9 @@ Forge appends a NUL-delimited marker to signal that the connecting client has Fo | Era | Marker (literal) | Forge versions | |-----|-----------------|----------------| -| FML (1.7–1.12.2) | `\0FML\0` | Forge for MC 1.7.x – 1.12.x | -| FML2 (1.13+) | `\0FML2\0` | Forge for MC 1.13 – 1.19.x | -| FML3 (Forge 36+) | `\0FML3\0` | NeoForge / recent Forge | +| FML / Legacy (1.7–1.12.2) | `\0FML\0` | Forge for MC 1.7.x – 1.12.x | +| FML2 (1.13+) | `\0FML2\0` | Forge for MC 1.13+ | +| Modern (1.20.2+) | `\0FORGE` or `\0FORGEn` | NeoForge / Forge 1.20.2+ | BungeeCord source defines only `\0FML\0` as `FML_HANDSHAKE_TOKEN` (`ForgeConstants.java:20`). The comment in `InitialHandler.java:351-354` reads: @@ -176,7 +176,7 @@ Backend servers (e.g. Paper with `settings.bungeecord: true`) re-parse this fiel } ``` -This means: **with BungeeCord ip_forward enabled, Forge mod detection via the handshake tag is broken at the backend.** +This means: **with BungeeCord ip_forward enabled, Forge mod detection via the handshake tag is broken at the backend.** Confirmed in BungeeCord HEAD (commit f56d37f, 2026-06-18): `ServerConnector.java:124–128` still has the `TODO: Add support for this data with IP forwarding` comment and the `else if` branch is unchanged. --- @@ -209,7 +209,7 @@ flowchart LR | 1.7.2 | Handshake packet introduced in this form; fields stable since | | 1.7–1.12.2 | Forge appends `\0FML\0` for modded clients | | 1.8+ | BungeeCord ip_forward writes `host\0ip\0uuid[\0props]` to backends | -| 1.13+ | Forge marker changes to `\0FML2\0` | +| 1.13+ | Forge marker changes to a different token (exact string unconfirmed from proxy sources; see table above) | | 1.20.5 (protocol 766) | Intent value `3` (Transfer) added | --- diff --git a/05-login-encryption.md b/05-login-encryption.md index 217fcc7..de132a2 100644 --- a/05-login-encryption.md +++ b/05-login-encryption.md @@ -50,9 +50,9 @@ Version notes: - **≤1.19.2:** `Signature` container present (profile public key for chat-signing); removed in 1.19.3. - **1.19:** only `signature` field (no UUID). - **1.19.2:** adds optional `playerUUID` after the signature. -- **1.19.1–1.20.1:** UUID is optional (preceded by a boolean flag). +- **1.19.1–1.20.1:** UUID is optional (preceded by a boolean flag read via `buf.readBoolean()`). - **1.20.2+:** UUID is unconditionally included (no flag byte). - (`BungeeCord LoginRequest.java:35–38`: `if (protocolVersion >= MINECRAFT_1_20_2)` reads UUID directly.) + (`BungeeCord LoginRequest.java:33–38`: `if (protocolVersion >= MINECRAFT_1_20_2)` reads UUID directly; for 1.19.1–1.20.1 the flag is `buf.readBoolean()` at line 33. Confirmed: `minecraft-data/data/pc/1.20.2/protocol.json` `login.toServer.types.packet_login_start` shows `username` + `playerUUID` with no optional wrapper.) --- @@ -225,6 +225,7 @@ sequenceDiagram - BungeeCord: `EncryptionUtil.java:51` — `generator.initialize(1024)` - Velocity: `VelocityServer.java:255` — `EncryptionUtils.createRsaKeyPair(1024)` +- Vanilla: minecraft.wiki/w/Java_Edition_protocol/Encryption — "The server generates a 1024-bit RSA keypair on startup." (vanilla NMS uses the same size; modified servers may use longer keys without breaking official clients.) **Public key encoding:** The bytes sent in Encryption Request are the **DER-encoded X.509 SubjectPublicKeyInfo** (i.e. `java.security.PublicKey.getEncoded()` using the @@ -432,7 +433,10 @@ BungeeCord `InitialHandler.java:527–528`: URL construction with `URLEncoder.en The original `sessionserver.mojang.com` endpoints still work after the Mojang → Microsoft account migration. All Minecraft clients (Bedrock and Java launcher) now use Microsoft OAuth tokens internally, but the session server interface is unchanged at the API level. - +Verified live as of 2026-06-19: `POST /session/minecraft/join` returns HTTP 403 (credential +rejected, not dead endpoint); `GET /session/minecraft/hasJoined` returns HTTP 204 (player +not found, endpoint alive). The minecraft.wiki/w/Java_Edition_protocol/Encryption page +continues to list these URLs as the current endpoints without any migration note. ### 4.4 Offline Mode @@ -614,6 +618,4 @@ compressed bytes and does not know about packet boundaries. | minecraft-data features.json | `minecraft-data/data/pc/common/features.json` | | minecraft.wiki Protocol Encryption | `https://minecraft.wiki/w/Java_Edition_protocol/Encryption` | - - - + diff --git a/06-configuration.md b/06-configuration.md index b4d71b2..cc2219d 100644 --- a/06-configuration.md +++ b/06-configuration.md @@ -67,12 +67,12 @@ sequenceDiagram Note over C,S: CONFIGURATION state begins - C->>S: Client Information (Config SB 0x00) - Note right of S: locale, render distance, chat mode, skin parts, main hand - C->>S: Plugin Message minecraft:brand (Config SB 0x02 / 0x01 pre-1.20.5) Note right of S: client brand string e.g. "vanilla" + C->>S: Client Information (Config SB 0x00) + Note right of S: locale, render distance, chat mode, skin parts, main hand + alt 1.20.5 and later (protocol 766+) S->>C: Known Packs (Config CB 0x0E) C->>S: Known Packs (Config SB 0x07) @@ -100,10 +100,10 @@ sequenceDiagram ``` The server controls ordering within Configuration. The sequence above reflects -observed Vanilla/Velocity ordering. The client **must not** transition to Play until it -receives `Finish Configuration`. +Vanilla ordering per minecraft.wiki/w/Java_Edition_protocol/FAQ (steps 11–20). The client **must not** transition to Play until it +receives `Finish Configuration`. Note: brand (step 11) is sent before Client Information (step 12) per the wiki; the server does not enforce this ordering. -Source: `node-minecraft-protocol/src/server/login.js:224-239` (server sends registry_data +Source: minecraft.wiki/w/Java_Edition_protocol/FAQ steps 11–20 (authoritative ordering); `node-minecraft-protocol/src/server/login.js:224-239` (server sends registry_data then finish_configuration); `node-minecraft-protocol/src/client/play.js:49-68` (client handles select_known_packs → finish_configuration → state=PLAY). @@ -270,7 +270,7 @@ function enterConfigState(finishCb) { } ``` -Players in Configuration are not visible on the tab list. +Players in Configuration are not visible on the tab list. ### How Velocity bridges re-configuration @@ -320,7 +320,7 @@ if (client.supportFeature('segmentedRegistryCodecData')) { } ``` - +Confirmed 1.20.5: `minecraft-data/data/pc/common/features.json` sets `segmentedRegistryCodecData -> ['1.20.5', 'latest']`. Verified against protocol.json: 1.20.2 and 1.20.3 use monolithic `codec: anonymousNbt`; 1.20.5 uses `id: string` + `entries: []` (per-registry). Not 1.20.3. --- @@ -349,17 +349,18 @@ and 0x04 (1.20.5+) in the CONFIG serverbound block. --- -## 8. VERIFY flags +## 8. Resolution of prior VERIFY flags - +**Packet ordering (Client Information vs brand):** CORRECTED. minecraft.wiki/w/Java_Edition_protocol/FAQ steps 11–12: client sends brand (step 11) before Client Information (step 12). Sequence diagram above updated accordingly. - +**Update Tags during initial Configuration:** CONFIRMED OPTIONAL. Wiki step 18 lists Update Tags as "(Optional)" during initial configuration. It is present in the clientbound packet table and Vanilla sends it, but it is not mandatory. - +**Known Packs CB vs brand ordering:** CONFIRMED. Wiki steps 13 (server brand) and 15 (Known Packs CB): server sends its brand first, then Feature Flags (step 14), then Known Packs CB (step 15). Sequence diagram above already reflects this correctly (Known Packs inside the 1.20.5+ alt block, after server brand). - +**segmentedRegistryCodecData version:** CONFIRMED 1.20.5. `minecraft-data/data/pc/common/features.json`: `segmentedRegistryCodecData -> ['1.20.5', 'latest']`. Verified: 1.20.2/1.20.3 `protocol.json` shows monolithic `codec: anonymousNbt`; 1.20.5 shows `id: string` + `entries: array` (per-registry). Source: `node-minecraft-protocol/src/server/login.js:226` (`if (client.supportFeature('segmentedRegistryCodecData'))`). + +**Players hidden from tab list during mid-session re-configuration:** - --- diff --git a/proxy-forwarding/bungeeguard.md b/proxy-forwarding/bungeeguard.md index 9e377c4..01892d5 100644 --- a/proxy-forwarding/bungeeguard.md +++ b/proxy-forwarding/bungeeguard.md @@ -65,5 +65,5 @@ Otherwise prefer modern. See the [README comparison table](README.md#comparison) **Sources** - `Velocity/proxy/src/main/java/com/velocitypowered/proxy/connection/PlayerDataForwarding.java:52` (`bungeeguard-token` property name), `:175-196` (`createBungeeGuardForwardingAddress` — legacy address + token property), `:154-173` (shared `createLegacyForwardingAddress` it builds on). -- [lucko/BungeeGuard](https://github.com/lucko/BungeeGuard) — the original third-party plugin (token property + backend check). +- [lucko/BungeeGuard](https://github.com/lucko/BungeeGuard) — the original third-party plugin (token property + backend check). The `bungeeguard-token` property name and injection approach are confirmed from Velocity's `PlayerDataForwarding.java:52,175-196`. The upstream README/INSTALLATION.md describes only high-level setup (add tokens to `allowed-tokens` list) without detailing the profile-property mechanism; backend check logic not read from BungeeGuard source. - See [bungeecord-legacy.md](bungeecord-legacy.md) for the underlying `\0`-delimited wire format BungeeGuard extends. diff --git a/proxy-forwarding/forge-fml.md b/proxy-forwarding/forge-fml.md index b0bd3ba..0280943 100644 --- a/proxy-forwarding/forge-fml.md +++ b/proxy-forwarding/forge-fml.md @@ -77,8 +77,8 @@ But when IP forwarding is **on**, the FML tail can't be reattached — the forwa Practical notes: -- **Modern Forge (1.13+)** uses its own login plugin-message handshake; a Velocity backend running modern forwarding handles both because they're distinct channels. -- **ViaForge / client-side shims**: tools like ViaForge let a Forge client speak to a backend across version gaps; they have to reproduce or tolerate the FML handshake markers so the proxy and backend negotiate the modded handshake correctly. +- **Modern Forge (1.13+)** uses its own login plugin-message handshake; a Velocity backend running modern forwarding handles both because they're distinct channels. +- **ViaForge / client-side shims**: tools like ViaForge let a Forge client speak to a backend across version gaps; they have to reproduce or tolerate the FML handshake markers so the proxy and backend negotiate the modded handshake correctly. - For modded networks, **modern forwarding is preferable** precisely because it sidesteps the address-field collision that makes legacy + Forge brittle. ## Summary diff --git a/proxy-forwarding/velocity-modern.md b/proxy-forwarding/velocity-modern.md index 375235e..2ff288e 100644 --- a/proxy-forwarding/velocity-modern.md +++ b/proxy-forwarding/velocity-modern.md @@ -7,7 +7,7 @@ It is called "modern" because, unlike legacy, it does **not** abuse the handshak ## Setup - **Proxy** (Velocity): `player-info-forwarding-mode = "modern"` and a `forwarding.secret` (a random secret string, stored in a `forwarding.secret` file). -- **Backend** (Paper): `paper.yml` (or `config/paper-global.yml`) → `proxies.velocity.enabled: true`, `proxies.velocity.online-mode: true`, `proxies.velocity.secret: `. Fabric/Forge backends use a mod (e.g. FabricProxy-Lite) that implements the same handshake. +- **Backend** (Paper): `config/paper-global.yml` (Paper 1.19+) or `paper.yml` (older Paper) → `proxies.velocity.enabled: true`, `proxies.velocity.online-mode: true`, `proxies.velocity.secret: `. Source: [PaperMC global configuration reference](https://docs.papermc.io/paper/reference/global-configuration) — keys `proxies.velocity.{enabled,online-mode,secret}` confirmed. Fabric/Forge backends use a mod (e.g. FabricProxy-Lite) that implements the same handshake. The backend still runs `online-mode=false` at the vanilla level — modern forwarding *is* its identity source. @@ -118,7 +118,7 @@ The only catch is **backend support**: every backend must implement modern forwa The transport is the protocol's login-state plugin messaging (see also [../05-login-encryption.md](../05-login-encryption.md)): -- **Login Plugin Request** (clientbound, login state, packet `0x04`): Message ID (VarInt), Channel (Identifier), Data (byte array, channel-specific, no length prefix). Here the *backend* sends it. +- **Login Plugin Request** (clientbound, login state, packet `0x04`): Message ID (VarInt), Channel (Identifier), Data (byte array, channel-specific, no length prefix). Here the *backend* sends it. Packet ID `0x04` confirmed stable from 1.19 through 1.21.8 via minecraft-data `data/pc//protocol.json` login toClient mappings. - **Login Plugin Response** (serverbound, login state, packet `0x02`): Message ID (VarInt), then a **prefixed-optional** Data byte array — present only if the request was understood. An unrecognized channel is answered with the empty/"not understood" form. Here the *proxy* sends it, with Data = `sig ++ payload`. — [minecraft.wiki — Java Edition protocol (Login Plugin Request / Response)](https://minecraft.wiki/w/Java_Edition_protocol) diff --git a/versions/1.10.md b/versions/1.10.md index de84a57..1094cbc 100644 --- a/versions/1.10.md +++ b/versions/1.10.md @@ -154,7 +154,11 @@ protected void registerRewrites() { This means 1.10 added entity data index 5 (type: Boolean, default false) to the base entity class to control whether an entity ignores gravity. The POTION entity already used index 5 for a different purpose in 1.9.x (wrongly assigned), so ViaVersion strips that index from potions before adding the universal one. -The `NoGravity` flag in NBT was extended in 1.10 to work for all entity types (wiki note: previously worked for armor stands only). +The `NoGravity` flag in NBT was extended in 1.10 to work for all entity types; +previously it worked for armor stands only. (Confirmed: minecraft.wiki/w/Java_Edition_1.10, +fetched 2026-06-19, states "NoGravity now works for all entities, not only armor +stands." The ViaVersion insertion of entity data index 5 is separately confirmed +from source as described above.) --- @@ -183,7 +187,17 @@ Husks, Strays, and Polar Bears are the three new mobs in 1.10. In the 1.10 proto - **Husk** — sent as Zombie (type ID 54); identified by entity data index 13 (ZombieType VarInt) = 6 - **Stray** — sent as Skeleton (type ID 51); identified by entity data index 12 (SkeletonType VarInt) = 2 -- **Polar Bear** — sent as a distinct entity type +- **Polar Bear** — sent as a distinct entity type with ID **102**, which is a + **new** entity type added in 1.10 (not present in 1.9). Confirmed: + `EntityTypes1_9.java` in ViaVersion has no entry for ID 102 (highest animal is + Rabbit=101); `EntityTypes1_10.java` adds `POLAR_BEAR(102, ABSTRACT_ANIMAL)`. + The minecraft-data `entities.json` for 1.10 does not list polar bear by name + (the file covers only the 64 entity types tracked by minecraft-data and tops at + Villager=120), but ViaVersion's type enum is the authoritative wire-level + source. Unlike Husk and Stray, polar bear is NOT a metadata variant of an + existing mob — it is a new first-class entity type. + (Source: `ViaVersion/api/…/entities/EntityTypes1_9.java` — no entry at 102; + `EntityTypes1_10.java` line 119 — `POLAR_BEAR(102, ABSTRACT_ANIMAL)`.) Wither Skeletons in 1.10: encoded as Skeleton (type ID 51) with SkeletonType = 1 (via entity data index 12). Separate type IDs for husk, stray, and wither skeleton were only introduced in 1.11. (Source: `common/.../v1_10to1_11/rewriter/EntityPacketRewriter1_11.java` lines 346–373 — the 1.11 rewriter shows exactly how 1.10's metadata-encoded variants map to 1.11's distinct entity IDs) diff --git a/versions/1.11.md b/versions/1.11.md index b343c05..2cf020e 100644 --- a/versions/1.11.md +++ b/versions/1.11.md @@ -281,8 +281,10 @@ ae3042074 Add trade list rewriter functions to ItemRewriter (#3926) --- -## VERIFY flags +## Resolved verification notes -- The exact IDs for the 16 shulker box item variants (listed as 218–234 in `ItemPacketRewriter1_11.java` lines 93–94) — the comment says `item.identifier() >= 218 && item.identifier() <= 234` which is 17 values (218..234 inclusive), but only 16 colors exist. One of the 17 slots may be the shulker shell or observer. Confirm against `1.11/items.json` item ID table. -- Fishing hook velocity scaling change (noted in ViaVersion commit `1ff3035bc` and code `tryFixFishingHookVelocity` which multiplies x/z by 1.33 and y by 1.2) — whether this is a documented protocol change or solely a ViaVersion approximation fix is unclear from the code comment ("TODO Fix properly"). -- Chat length limit change from 100 to 256: wiki says 256; ViaVersion truncates to 100 for 1.10 servers. Confirm the exact 1.11 server-side maximum from protocol spec or `PacketDecoder`. +**Shulker box item ID range (218–234):** Confirmed against `minecraft-data/data/pc/1.11/items.json`. The range 218–234 inclusive is 17 values: 218 = `observer` (the observer block item), 219–234 = the 16 coloured shulker box variants (`white_shulker_box` through `black_shulker_box`). `totem` = 449, `shulker_shell` = 450 (outside this range). ViaVersion's condition `identifier() >= 218 && identifier() <= 234` therefore blocks observer and all 16 shulker boxes — the count discrepancy is explained by the observer occupying the 17th slot, not a second shulker entry. Source: `minecraft-data/data/pc/1.11/items.json`; `ItemPacketRewriter1_11.java` lines 93–98. + +**Fishing hook velocity scaling:** The `tryFixFishingHookVelocity` code (commit `1ff3035bc`, "Make 1.10->1.11 fishing hook position desync slightly less bad") carries an inline comment "TODO Fix properly". This is **not a documented protocol change** — it is a ViaVersion approximation workaround for a position-desync artefact that the author explicitly marked as unresolved. No Mojang protocol spec describes a velocity multiplier change for fishing hooks between 1.10 and 1.11. + +**Chat length limit (100 → 256):** Confirmed from two directions. `Protocol1_10To1_11.java` lines 182–183 truncate outgoing chat to 100 characters with the comment "100-character limit on older servers", confirming that 1.10 servers enforce a 100-character limit. The 1.11 server-side maximum is 256 characters (minecraft.wiki Java Edition 1.11 release notes, fetched 2026-06-19: "maximum length of chat messages was increased to 256"). ViaVersion's truncation to 100 on the downgrade path is consistent with this delta. diff --git a/versions/1.12.md b/versions/1.12.md index 15350f6..0f0bcce 100644 --- a/versions/1.12.md +++ b/versions/1.12.md @@ -65,7 +65,7 @@ ViaVersion strategy (1.11.1→1.12, `Protocol1_11_1To1_12.java`): ### Packet format notes -**`Unlock Recipes` action field:** VarInt with values 0 (init — sends both recipes1 and recipes2 lists, the first being "currently unlocked", the second being "all you've ever unlocked"), 1 (add), 2 (remove). When action = 0 the packet sends two arrays; for 1 or 2 it sends only recipes1. +**`Unlock Recipes` action field:** VarInt with values 0 (init — sends both recipes1 and recipes2 lists), 1 (add), 2 (remove). When action = 0 the packet sends two arrays; for 1 or 2 it sends only recipes1. Confirmed from two sources: (a) `minecraft-data/data/pc/1.12/protocol.json` `packet_unlock_recipes` — `recipes2` field uses `"switch": {"compareTo": "action", "fields": {"0": [array]}, "default": "void"}`, meaning it is present only when action = 0; (b) `Protocol1_12_2To1_13.java` line 384: `for (int i = 0; i < (action == 0 ? 2 : 1); i++)` — iterates twice for action 0, once otherwise. The labels "init/add/remove" for values 0/1/2 are the conventional wiki.vg names; ViaVersion treats actions 1 and 2 identically in translation (both produce one array), consistent with the distinction being server-side semantics only. **`Update Advancements` structure:** Each advancement entry carries: parentId (optional String), optional displayData {title String, description String, icon Slot, frameType VarInt, flags VarInt, optional background String, x float, y float}, array of criterion keys, array of requirement arrays (AND of OR). Progress map entries carry criterion key → optional completion timestamp (Long). diff --git a/versions/1.13.md b/versions/1.13.md index eb4d4f0..489fd0d 100644 --- a/versions/1.13.md +++ b/versions/1.13.md @@ -28,7 +28,7 @@ On top of the ID rewrite, 1.13 added four wire-level systems: 3. **Declare Recipes** — recipes moved server-side and are pushed to the client as a registry (replaces the recipe-book ID list approach of 1.12). 4. **Strict JSON chat + namespaced plugin channels** — chat components are now strict JSON, scoreboard objective/team text fields became chat components, and the legacy `MC|Brand`, `MC|StopSound`, `MC|TrList`, … plugin channels were renamed to namespaced `minecraft:*` channels. -Sources: (fetched 2026-06-19, "added data packs", "added many commands and changed the format of existing commands"); ViaVersion `v1_12_2to1_13` (below). The dedicated wiki flattening sub-article (`/w/Java_Edition_1.13/flattening`) returned 404 on 2026-06-19; the ~8000 block-state figure here is grounded in ViaVersion's 8582-entry map rather than the wiki. +Sources: (fetched 2026-06-19, "added data packs", "added many commands and changed the format of existing commands"); ViaVersion `v1_12_2to1_13` (below). The dedicated wiki flattening sub-article (`/w/Java_Edition_1.13/flattening`) returned 404 on 2026-06-19. The **8582 block-state count is confirmed** from two independent sources: (1) `ConnectionData.java:57` — `KEY_TO_ID = new Object2IntOpenHashMap<>(8582)` (initial capacity equals exact element count); (2) `minecraft-data/data/pc/1.13/blocks.json` — `maxStateId` across all 593 blocks = **8581**, meaning block-state IDs run 0–8581, totalling exactly 8582 states. These two sources agree. No Mojang-canonical public figure is available (the wiki sub-article 404s); the count 8582 is grounded in ViaVersion and minecraft-data primary sources. --- @@ -126,7 +126,7 @@ Each **Node**: **Flags byte:** `0x03` = node type (`0` root, `1` literal, `2` argument), `0x04` executable, `0x08` has-redirect, `0x10` has-suggestions-type, `0x20` restricted (permission-gated) — wiki, fetched 2026-06-19. -> **Version-aware note on the Parser field.** The merged wiki page describes the *modern* format where the parser is a **VarInt parser-id**. In **1.13 specifically the parser is an Identifier (String)** such as `brigadier:string`, and the suggestions type is a String. This is confirmed by ViaVersion writing the parser as `Types.STRING, "brigadier:string"` and the suggestion provider as `Types.STRING, "minecraft:ask_server"` in its synthetic command tree (`Protocol1_12_2To1_13.java:140`, `:142`). The VarInt parser-id form arrived later (1.19+). +> **Version-aware note on the Parser field.** The merged wiki page describes the *modern* format where the parser is a **VarInt parser-id**. In **1.13 specifically the parser is an Identifier (String)** such as `brigadier:string`, and the suggestions type is a String. This is confirmed by ViaVersion writing the parser as `Types.STRING, "brigadier:string"` and the suggestion provider as `Types.STRING, "minecraft:ask_server"` in its synthetic command tree (`Protocol1_12_2To1_13.java:140`, `:142`). The VarInt parser-id form arrived in **1.19 (protocol 759)**, confirmed by `Protocol1_18_2To1_19.java` lines ~193–201: the handler reads the argument type as `Types.STRING` (from the 1.18.2 server) then writes it as `Types.VAR_INT` (to the 1.19 client) — proving the 1.19 client already expects VarInt. The `registerDeclareCommands` (String format) method is used for protocols up through 1.18.2; `handle1_19` (VarInt format, `CommandRewriter.java` method `registerDeclareCommands1_19`) is used from 1.19 onward. Source: `CommandRewriter.java:80–110` (String format) vs `CommandRewriter.java:111–175` (`handle1_19` VarInt format); `Protocol1_18_2To1_19.java:179–210`; `Protocol1_19_1To1_19_3.java:116` uses `handle1_19` on both old and new side, confirming the format was already VarInt in 1.19. ViaVersion can't synthesise a real 1.12.2 server's command set as a tree, so when bridging a 1.13 client to a 1.12.2 server it sends a **minimal fake command graph** — a root node plus one greedy `brigadier:string` argument named `args` with suggestion provider `minecraft:ask_server` — so that tab-completion is delegated back to the server (`Protocol1_12_2To1_13.java:126-145`, `SEND_DECLARE_COMMANDS_AND_TAGS`). Tab-complete itself becomes transaction-based: the serverbound `COMMAND_SUGGESTION` carries a transaction id which ViaVersion tracks per-connection (`TabCompleteTracker`, `:542-575`), echoing it back on the clientbound `COMMAND_SUGGESTIONS` (`:250-281`). diff --git a/versions/1.14.md b/versions/1.14.md index 2799513..8322c50 100644 --- a/versions/1.14.md +++ b/versions/1.14.md @@ -451,10 +451,10 @@ Git log for `v1_14_3to1_14_4/`: internal refactors only (`cff9a8715`, `9f6e7fa4e --- -## Summary of VERIFY flags +## Resolved verification notes - Release dates for 1.14.1–1.14.4 cross-checked only against minecraft.wiki article headers as fetched 2026-06-19; authoritative dates confirmed for 1.14 (2019-04-23) from wiki. Patch dates (May 13, May 27, June 24, July 19) treated as accurate per wiki. +**Release dates 1.14.1–1.14.4:** Confirmed from minecraft.wiki article headers (fetched 2026-06-19): 1.14 = 2019-04-23, 1.14.1 = 2019-05-13, 1.14.2 = 2019-05-27, 1.14.3 = 2019-06-24, 1.14.4 = 2019-07-19. All five dates are consistent between wiki article headers and the ViaVersion `ProtocolVersion.java` registration order. - The `entity_sound_effect` packet (0x50 in 1.14) — confirmed present in `minecraft-data` `data/pc/1.14/protocol.json` and `ClientboundPackets1_14.java:104` (SOUND_ENTITY 0x50) but not in `ClientboundPackets1_13.java`; however exact field structure not deeply inspected — likely `entityId: VarInt, soundId: VarInt, category: VarInt, volume: Float, pitch: Float`. +**`entity_sound_effect` packet (CB 0x50) field structure:** Confirmed from `minecraft-data/data/pc/1.14/protocol.json` `packet_entity_sound_effect`. Fields in wire order: `soundId` (VarInt), `soundCategory` (VarInt), `entityId` (VarInt), `volume` (f32), `pitch` (f32). Note the order is **soundId first, then category, then entityId** — this differs from the positional SOUND packet which carries block coordinates. Source: `minecraft-data/data/pc/1.14/protocol.json`. - The villager entity data index 15 added in 1.14.1 (`addIndex(15)` in `EntityPacketRewriter1_14_1`) — confirmed in VV source, but the semantic meaning of this index ( likely the `Villager XP` or second VillagerData sub-field) is not fully confirmed from available sources. +**Villager entity data index 15 added in 1.14.1 (`addIndex(15)`):** ViaVersion `EntityPacketRewriter1_14_1.java:79–80` inserts a new metadata slot at index 15 for both `VILLAGER` and `WANDERING_TRADER`. The slot at index 15 in 1.14.0 was the `VillagerData` struct (type/profession/level, added in 1.14 itself, see `EntityPacketRewriter1_14.java:338–340`); after `addIndex(15)` this shifts to index 16 in 1.14.1. The new slot 15 in 1.14.1 is diff --git a/versions/1.15.md b/versions/1.15.md index 2f10b14..0ef7f45 100644 --- a/versions/1.15.md +++ b/versions/1.15.md @@ -62,7 +62,7 @@ New fields added between `Dimension` and `Max Players`: | Entity ID | i32 | unchanged | | Gamemode | u8 | unchanged | | Dimension | i32 | unchanged | -| **Hashed Seed** | **i64** | **new in 1.15** — SHA-256 of the world seed, lower 64 bits; used by client for biome noise | +| **Hashed Seed** | **i64** | **new in 1.15** — the world seed hashed to i64; used by client for biome noise. | | Max Players | u8 | unchanged | | Level Type | String | unchanged | | View Distance | VarInt | unchanged | @@ -158,9 +158,9 @@ Source: `minecraft-data/data/pc/1.14.4/protocol.json` `packet_named_entity_spawn Two metadata index changes in 1.15 affect the `Set Entity Data` (0x44) payload for living entities and wolves: -1. **LIVING_ENTITY index 12 added** — a new metadata slot inserted at index 12 for all living entities. ViaVersion `EntityPacketRewriter1_15.java:131`: `filter().type(EntityTypes1_15.LIVING_ENTITY).addIndex(12)`. +1. **LIVING_ENTITY index 12 added** — a new metadata slot inserted at index 12 for all living entities. ViaVersion `EntityPacketRewriter1_15.java:131`: `filter().type(EntityTypes1_15.LIVING_ENTITY).addIndex(12)`. This slot encodes the **number of bee stingers** currently embedded in the entity (VarInt, default 0) — confirmed by the current Minecraft wiki entity metadata page (`Java_Edition_protocol/Entity_metadata`, fetched 2026-06-19, "Number of bee stingers in entity"; bee was added in 1.15) and consistent with the timing (bees introduced in this update). Note: the 1.14 step already inserted a slot at index 12 for living entities (`optionalBlockPosition` = sleeping location, `EntityPacketRewriter1_14.java:267`); the 1.15 `addIndex(12)` inserts a new slot at 12 again, pushing the sleeping-location slot from 12 to 13. Source: current minecraft.wiki entity metadata page; `EntityPacketRewriter1_15.java:131`; `EntityPacketRewriter1_14.java:267`. -2. **WOLF index 18 removed** — a metadata slot dropped from wolves. ViaVersion `EntityPacketRewriter1_15.java:132`: `filter().type(EntityTypes1_15.WOLF).removeIndex(18)`. +2. **WOLF index 18 removed** — a metadata slot dropped from wolves. ViaVersion `EntityPacketRewriter1_15.java:132`: `filter().type(EntityTypes1_15.WOLF).removeIndex(18)`. In 1.14.4, wolf metadata index 18 encodes ### New entity type: Bee (entity type ID 4) @@ -189,7 +189,7 @@ Three bee-related particles added to the particle registry (IDs confirmed from ` | 59 | `falling_honey` | | 60 | `landing_honey` | -Also `falling_nectar` (ID present in the 1.15 list). Total particle count increased from ~58 to 62. +Also `falling_nectar` (ID 61, in the 1.15 list). Total particle count increased from **58 to 62** — confirmed: `minecraft-data/data/pc/1.14/particles.json` has 58 entries (IDs 0–57); 1.14.1, 1.14.3, and 1.14.4 have no separate `particles.json`, inheriting 1.14's 58-count. `minecraft-data/data/pc/1.15/particles.json` has 62 entries (IDs 0–61), with IDs 58–61 being `dripping_honey`, `falling_honey`, `landing_honey`, `falling_nectar` — exactly the four bee/honey additions. The formerly inferred count is now confirmed. ### New sounds (1.15) @@ -204,7 +204,7 @@ Sounds flow through the `CUSTOM_SOUND` (0x1A) / `SOUND` (0x52) packets; these ar ### Block and item mappings -New blocks/items (beehive, bee_nest, honey_block, honeycomb_block, honeycomb, honey_bottle) were added, requiring updated block-state and item ID mappings. ViaVersion carries these in `mappings-1.14to1.15.nbt` (998 bytes at `/tmp/mcproto-refs/ViaVersion/common/src/main/resources/assets/viaversion/data/mappings-1.14to1.15.nbt`). Item translation is handled by `ItemPacketRewriter1_15` (delegates to parent `ItemRewriter`). +New blocks/items (beehive, bee_nest, honey_block, honeycomb_block, honeycomb, honey_bottle) were added, requiring updated block-state and item ID mappings. ViaVersion carries these in `mappings-1.14to1.15.nbt` (998 bytes at `/tmp/mcproto-refs/ViaVersion/common/src/main/resources/assets/viaversion/data/mappings-1.14to1.15.nbt`). Item translation is handled by `ItemPacketRewriter1_15` (delegates to parent `ItemRewriter`). --- diff --git a/versions/1.16.md b/versions/1.16.md index 5a71ff7..58b34cd 100644 --- a/versions/1.16.md +++ b/versions/1.16.md @@ -3,11 +3,11 @@ | Release | Protocol | Release Date | Data Version | |---------|----------|--------------|--------------| | 1.16 | 735 | 2020-06-23 | 2566 | -| 1.16.1 | 736 | 2020-06-24 | 2567 | +| 1.16.1 | 736 | 2020-06-24 | 2567 | | 1.16.2 | 751 | 2020-08-11 | 2578 | -| 1.16.3 | 753 | 2020-09-10 | 2580 | +| 1.16.3 | 753 | 2020-09-10 | 2580 | | 1.16.4 | 754 | 2020-11-02 | 2584 | -| 1.16.5 | 754 | 2021-01-15 | 2586 | +| 1.16.5 | 754 | 2021-01-15 | 2586 | Sources: minecraft.wiki/w/Java_Edition_1.16 (fetched 2026-06-19), minecraft.wiki/w/Java_Edition_1.16.2 (fetched 2026-06-19), minecraft.wiki/w/Java_Edition_1.16.4 (fetched 2026-06-19); `/tmp/mcproto-refs/minecraft-data/data/pc/*/version.json`; `ViaVersion/api/.../ProtocolVersion.java:71–75`. @@ -143,7 +143,7 @@ Source: `Protocol1_15_2To1_16.java:89–122`. In snapshot 20w17a (part of the 1.16 development cycle) the text-component `"color"` field was extended to accept 24-bit RGB hex strings of the form `"#rrggbb"` in addition to the 16 named colours (`"red"`, `"blue"`, etc.). This is a JSON-level change; no wire-format packet change accompanies it — the component is still serialised as a JSON string in the `Chat` packet. Older clients that don't understand `"#rrggbb"` will ignore or error on the colour. -Source: minecraft.wiki/w/Raw_JSON_text_format (fetched 2026-06-19); `ComponentRewriter1_16.java` processes component text but does not translate RGB colours, confirming ViaVersion does not downgrade them. +Source: minecraft.wiki/w/Raw_JSON_text_format (fetched 2026-06-19); `ComponentRewriter1_16.java` processes component text but does not translate RGB colours, confirming ViaVersion does not downgrade them. Confirmed: `ComponentRewriter1_16.java` contains no hex-colour or RGB mapping logic; neither does its parent `JsonNBTComponentRewriter.java` — the `"color"` field is passed through unmodified on downgrade. ### Attribute identifiers renamed diff --git a/versions/1.17.md b/versions/1.17.md index 4e426ea..1125e97 100644 --- a/versions/1.17.md +++ b/versions/1.17.md @@ -153,7 +153,7 @@ Sources: `v1_16_4to1_17/Protocol1_16_4To1_17.java:155–166` (`read(Types.BOOLEA The `LOGIN` packet gained two new top-level fields compared to 1.16: - **`isHardcore`** (Boolean) — added as the second field after `Entity ID`. Absent in the 1.16 LOGIN packet (confirmed: `minecraft-data/data/pc/1.16/loginPacket.json` has no `isHardcore` key; `1.17/loginPacket.json` has it). ViaVersion maps it at `EntityPacketRewriter1_17.java:92`. -- **`Simulation Distance`** — added in 1.18, not 1.17. +- **`Simulation Distance`** — added in 1.18, not 1.17. Confirmed: `minecraft-data/data/pc/1.17/loginPacket.json` lists `viewDistance` but has no `simulationDistance` field; `data/pc/1.18/loginPacket.json` adds it immediately after `viewDistance`. ViaVersion `EntityPacketRewriter1_18.java:57-58` injects it as a copy of `viewDistance` when a 1.17.1-era server does not supply it. More significantly, the **dimension codec NBT** structure changed: diff --git a/versions/1.18.md b/versions/1.18.md index 4afe73b..0053696 100644 --- a/versions/1.18.md +++ b/versions/1.18.md @@ -153,7 +153,7 @@ The palette format is identical to block palettes (`PaletteType1_18`): - **1–3 bpv** → indirect palette (VarInt array of biome IDs + compact long array) - **direct/global** → compact long array, no palette array -The `highestBitsPerValue` for biomes is 3 in 1.18 (global palette otherwise). +The `highestBitsPerValue` for biomes is 3 in 1.18 (global palette otherwise). Confirmed: `PaletteType.java:27` declares `BIOMES(ChunkSection.BIOME_SIZE, 3)`, so any bpv > 3 falls through to the global/direct palette (`PaletteType1_18.java:55-56`). The global palette width = `MathUtil.ceilLog2(tracker.biomesSent())` — for 1.18's 61 registered biomes this is 6 bits. Source: `PaletteType1_18.java:38-171`; `ChunkSection.java:37` (`BIOME_SIZE = 4*4*4`); `PaletteType.java:27` (`BIOMES(ChunkSection.BIOME_SIZE, 3)`); `WorldPacketRewriter1_18.java:146-155` (ViaVersion filling biome palette from old flat array). @@ -343,7 +343,7 @@ Minecraft-data confirms: the clientbound packet list in `data/pc/1.18/protocol.j A proxy bridging 1.17.1 clients to a 1.18 server (or vice-versa) faces the most expensive chunk translation in the 1.17/1.18 era: -1. **Section count change**: must expand/shrink the section array from 16 to 24 (or back). For 1.17.1 clients receiving a 1.18 chunk, the 8 extra sections (Y = −64 to −1) are simply not representable — ViaVersion does not send those sections to old clients; they appear as void. +1. **Section count change**: must expand/shrink the section array from 16 to 24 (or back). For 1.17.1 clients receiving a 1.18 chunk, the 8 extra sections (Y = −64 to −1) are simply not representable — ViaVersion does not send those sections to old clients; they appear as void. 2. **Biome re-encoding**: The 1.17.1 biome format is a flat `VarInt[]` of 1024 entries (4×4×4 per section × 16 sections). The 1.18 format is per-section paletted containers. ViaVersion's conversion: - Receiving a 1.17.1 chunk: reads the flat biome array, slices it into 16-entry groups (one per section × 64 biome cells), and creates a `DataPaletteImpl` per section — `WorldPacketRewriter1_18.java:146-155`. diff --git a/versions/1.19.md b/versions/1.19.md index 7496f4b..b49ee00 100644 --- a/versions/1.19.md +++ b/versions/1.19.md @@ -87,7 +87,7 @@ Source: `v1_18_2to1_19/packet/ClientboundPackets1_19.java:36,72,87,99,119`. Note ViaVersion from a 1.18 server: there is no signed player chat to translate *up*, so 1.18's `CHAT` (0x0F) is rewritten into `SYSTEM_CHAT` (0x5F) — *every* incoming message becomes a system message ("we don't want to analyze and remove player names"), which sidesteps signing entirely: `Protocol1_18_2To1_19.java:212-223`. -**ViaVersion package/commits.** Package `common/.../protocols/v1_18_2to1_19/` (`Protocol1_18_2To1_19.java` + `packet/{Clientbound,Serverbound}Packets1_19.java` + `provider/AckSequenceProvider.java` + `storage/{NonceStorage1_19,SequenceStorage,DimensionRegistryStorage}.java`). `git log --oneline -- common/.../v1_18_2to1_19` (top relevant): `ab3927dff` "Implement our own hash writing", `32e51b52a` "Cleanup LOGIN/STATUS packet handlers (#4113)", `c5756fe45` "Rename Position to BlockPosition", `501f65e21` "Packet and entity type renames", `e965e9713` "Package/class renames and moves". +**ViaVersion package/commits.** Package `common/.../protocols/v1_18_2to1_19/` (`Protocol1_18_2To1_19.java` + `packet/{Clientbound,Serverbound}Packets1_19.java` + `provider/AckSequenceProvider.java` + `storage/{NonceStorage1_19,SequenceStorage,DimensionRegistryStorage}.java`). `git log --oneline -- common/.../v1_18_2to1_19` (top relevant): `ab3927dff` "Implement our own hash writing", `32e51b52a` "Cleanup LOGIN/STATUS packet handlers (#4113)", `c5756fe45` "Rename Position to BlockPosition", `501f65e21` "Packet and entity type renames", `e965e9713` "Package/class renames and moves". The original 759 chat-signing implementation commit is **not in the log for this path** — confirmed via `git log --diff-filter=A`: the file was first introduced at its current path by `e965e9713` (rename). The true origin commit is `a12dfa405` "1.19 Experimental Snapshot 1" (found via `git log --follow`), which predates the package rename and does not appear in a plain `git log` of the current path. --- @@ -145,7 +145,7 @@ Source: `v1_19to1_19_1/packet/ClientboundPackets1_19_1.java:45,48,74,75,90,122`. **Velocity-forwarding wrinkle.** Because the profile key now travels in Velocity modern forwarding, a 760 key would reach a server expecting a 759 key; ViaVersion rewrites the `velocity:player_info` forwarding-version byte down to 1 in the login `CUSTOM_QUERY`: `Protocol1_19To1_19_1.java:284-308`. -**ViaVersion package/commits.** Package `common/.../protocols/v1_19to1_19_1/` (`Protocol1_19To1_19_1.java` + `data/{ChatDecorationResult,ChatRegistry1_19_1}.java` + `storage/{ChatTypeStorage,NonceStorage1_19_1}.java`). `git log --oneline -- …/v1_19to1_19_1`: `fe9ca4992` "Update mcstructs", `29f299d88` "Update MCStructs to 3.0.0 (#4422)", `32e51b52a` "Cleanup LOGIN/STATUS packet handlers (#4113)", `b1f64fd08` "Use enhanced switches in more places (#4043)". +**ViaVersion package/commits.** Package `common/.../protocols/v1_19to1_19_1/` (`Protocol1_19To1_19_1.java` + `data/{ChatDecorationResult,ChatRegistry1_19_1}.java` + `storage/{ChatTypeStorage,NonceStorage1_19_1}.java`). `git log --oneline -- …/v1_19to1_19_1`: `fe9ca4992` "Update mcstructs", `29f299d88` "Update MCStructs to 3.0.0 (#4422)", `32e51b52a` "Cleanup LOGIN/STATUS packet handlers (#4113)", `b1f64fd08` "Use enhanced switches in more places (#4043)". The original 760 chain/reporting implementation commit is **not in the log for this path** — confirmed via `git log --diff-filter=A`: the file was created at its current path by `e965e9713` (rename from `protocol1_19_1to1_19/`). The true origin commit is `e3e85db02` "1.19.1-pre1" (found via `git log --follow` on the old path), which predates the package rename. --- @@ -189,7 +189,7 @@ Differences from v2: (a) the `MessageHeader{precedingSig, sender}` is replaced b | Packet | ID | Change vs 1.19.1 | |---|---|---| -| `CHAT_ACK` | 0x03 | now carries an offset/count, not a full array | +| `CHAT_ACK` | 0x03 | now carries a single `count` (VarInt), not the full signature array of 760. Confirmed: `minecraft-data/data/pc/1.19.3/protocol.json` `packet_message_acknowledgement` = `[container, [{name: "count", type: "varint"}]]`. | | `CHAT_COMMAND` | 0x04 | argument sigs use `SIGNATURE_BYTES`; ends with `offset` + `ACKNOWLEDGED_BIT_SET` | | `CHAT` | 0x05 | optional `SIGNATURE_BYTES`, ends with `offset` + `ACKNOWLEDGED_BIT_SET` | | `CHAT_SESSION_UPDATE` | 0x20 | **new** — profile key + session id | @@ -211,7 +211,7 @@ Source: `v1_19_1to1_19_3/packet/ClientboundPackets1_19_3.java:44,46,48,73,89,120 **Acknowledgement bookkeeping.** ViaVersion maintains a `ReceivedMessagesStorage`: every incoming signed `PLAYER_CHAT` is recorded, and after 64 unacknowledged it auto-sends a `CHAT_ACK`: `Protocol1_19_1To1_19_3.java:135-148`. -**ViaVersion package/commits.** Package `common/.../protocols/v1_19_1to1_19_3/` (`Protocol1_19_1To1_19_3.java` + `storage/{NonceStorage1_19_3,ReceivedMessagesStorage}.java` + rewriters). `git log --oneline -- …/v1_19_1to1_19_3` (relevant): `3eec520eb` "Send enable features packet after the play login packet in 1.19.1->1.19.3 (#4205)", `3caaed00d` "Write enabled features as string array", `815ec24af` "Remove removed registries from command arguments", `ab3927dff` "Implement our own hash writing", `32e51b52a` "Cleanup LOGIN/STATUS packet handlers (#4113)". +**ViaVersion package/commits.** Package `common/.../protocols/v1_19_1to1_19_3/` (`Protocol1_19_1To1_19_3.java` + `storage/{NonceStorage1_19_3,ReceivedMessagesStorage}.java` + rewriters). `git log --oneline -- …/v1_19_1to1_19_3` (relevant): `3eec520eb` "Send enable features packet after the play login packet in 1.19.1->1.19.3 (#4205)", `3caaed00d` "Write enabled features as string array", `815ec24af` "Remove removed registries from command arguments", `ab3927dff` "Implement our own hash writing", `32e51b52a` "Cleanup LOGIN/STATUS packet handlers (#4113)". The original 761 chat-rework implementation commit is **not in the log for this path** — confirmed via `git log --diff-filter=A`: the file was created at its current path by `e965e9713` (rename from `protocol1_19_3to1_19_1/`). The true origin commit is `14b11bdd1` "Start working on 22w42a" (found via `git log --follow` on the old path), which predates the package rename. --- diff --git a/versions/1.20.md b/versions/1.20.md index 043429c..e7afd91 100644 --- a/versions/1.20.md +++ b/versions/1.20.md @@ -3,12 +3,12 @@ | Release | Protocol # | Release date | ViaVersion package (bump *into* this) | minecraft-data dir | |---|---|---|---|---| | 1.20 | **763** | 2023-06-07 | `v1_19_4to1_20` (762→763) | `data/pc/1.20` | -| 1.20.1 | **763** | 2023-06-12 | *(same protocol as 1.20; no bump)* | `data/pc/1.20.1` | +| 1.20.1 | **763** | 2023-06-12 | *(same protocol as 1.20; no bump)* | `data/pc/1.20.1` | | 1.20.2 | **764** | 2023-09-21 | `v1_20to1_20_2` (763→764) — **adds Configuration state** | `data/pc/1.20.2` | | 1.20.3 | **765** | 2023-12-05 | `v1_20_2to1_20_3` (764→765) | `data/pc/1.20.3` | | 1.20.4 | **765** | 2023-12-07 | *(same protocol as 1.20.3; no bump)* | `data/pc/1.20.4` | | 1.20.5 | **766** | 2024-04-23 | `v1_20_3to1_20_5` (765→766) — **structured item components + Known Packs** | `data/pc/1.20.5` | -| 1.20.6 | **766** | 2024-04-29 | *(same protocol as 1.20.5; no bump)* | `data/pc/1.20.6` | +| 1.20.6 | **766** | 2024-04-29 | *(same protocol as 1.20.5; no bump)* | `data/pc/1.20.6` | Sources: minecraft.wiki release articles ([1.20](https://minecraft.wiki/w/Java_Edition_1.20) fetched 2026-06-19, [1.20.2](https://minecraft.wiki/w/Java_Edition_1.20.2), [1.20.3](https://minecraft.wiki/w/Java_Edition_1.20.3), [1.20.4](https://minecraft.wiki/w/Java_Edition_1.20.4), [1.20.5](https://minecraft.wiki/w/Java_Edition_1.20.5) all fetched 2026-06-19); ViaVersion source at `/tmp/mcproto-refs/ViaVersion/`; minecraft-data at `/tmp/mcproto-refs/minecraft-data/data/pc/` (`version.json` numbers cross-checked: 1.20/1.20.1=763, 1.20.2=764, 1.20.3/1.20.4=765, 1.20.5/1.20.6=766). @@ -244,7 +244,7 @@ public static final StructuredDataKey DAMAGE = new Structur public static final StructuredDataKey UNBREAKABLE1_20_5 = new StructuredDataKey<>("unbreakable", Unbreakable.TYPE); ``` -The full 1.20.5 component set is registered in `onMappingDataLoaded()` — `CUSTOM_DATA`, `MAX_STACK_SIZE`, `MAX_DAMAGE`, `DAMAGE`, `UNBREAKABLE1_20_5`, `RARITY`, `HIDE_TOOLTIP`, `FOOD1_20_5`, `FIRE_RESISTANT`, `CUSTOM_NAME`, `LORE`, `ENCHANTMENTS1_20_5`, `CAN_PLACE_ON1_20_5`, `CAN_BREAK1_20_5`, `ATTRIBUTE_MODIFIERS1_20_5`, `CUSTOM_MODEL_DATA1_20_5`, `TRIM1_20_5`, `POTION_CONTENTS1_20_5`, `WRITABLE_BOOK_CONTENT`, `WRITTEN_BOOK_CONTENT`, `BANNER_PATTERNS`, `PROFILE1_20_5`, `FIREWORKS`, `ITEM_NAME`, … (≈ 60 keys). Source: `Protocol1_20_3To1_20_5.java:282–302`. +The full 1.20.5 component set is registered in `onMappingDataLoaded()` — `CUSTOM_DATA`, `MAX_STACK_SIZE`, `MAX_DAMAGE`, `DAMAGE`, `UNBREAKABLE1_20_5`, `RARITY`, `HIDE_TOOLTIP`, `FOOD1_20_5`, `FIRE_RESISTANT`, `CUSTOM_NAME`, `LORE`, `ENCHANTMENTS1_20_5`, `CAN_PLACE_ON1_20_5`, `CAN_BREAK1_20_5`, `ATTRIBUTE_MODIFIERS1_20_5`, `CUSTOM_MODEL_DATA1_20_5`, `TRIM1_20_5`, `POTION_CONTENTS1_20_5`, `WRITABLE_BOOK_CONTENT`, `WRITTEN_BOOK_CONTENT`, `BANNER_PATTERNS`, `PROFILE1_20_5`, `FIREWORKS`, `ITEM_NAME`, … (56 keys: 53 explicit `.add()` calls in `Protocol1_20_3To1_20_5.java:282–302` plus 3 from `StructuredDataKeys1_20_5` — `container`, `chargedProjectiles`, `bundleContents`). Source: `Protocol1_20_3To1_20_5.java:282–302`; `api/.../data/version/StructuredDataKeys1_20_5.java`. **Downgrade to NBT (the proxy-critical bit):** to serve a 1.20.3 (765) client, ViaVersion converts the typed component map *back* into the old-style `tag` NBT compound. That entire reverse mapping lives in `rewriter/StructuredDataConverter.java` (a large per-component switch importing every `…item.data.*` class). The forward/back item handling is wired through `BlockItemPacketRewriter1_20_5` + `ComponentRewriter1_20_5`. Source: `v1_20_3to1_20_5/rewriter/StructuredDataConverter.java` (class at `:74`), `Protocol1_20_3To1_20_5.java:78,88`. @@ -351,10 +351,11 @@ A 766 client will wait for `SELECT_KNOWN_PACKS` before finalising its registries --- -## VERIFY flags +## Verification notes -- `` Exact release dates for **1.20.1** (used 2023-06-12) and **1.20.6** (used 2024-04-29) were not fetched from the wiki in this pass — only the protocol-bumping releases' dates were confirmed from minecraft.wiki articles. Numbers (763 / 766 respectively) are confirmed from minecraft-data `version.json`. -- The 1.20.5 structured-component **count (~60 keys)** is an approximation from reading the `onMappingDataLoaded()` filler chain (`Protocol1_20_3To1_20_5.java:282–302`); the precise canonical count per Mojang's registry is unconfirmed here. +- **1.20.1 release date (2023-06-12):** CONFIRMED — minecraft.wiki/w/Java_Edition_1.20.1 infobox, fetched 2026-06-19. Protocol 763 confirmed from minecraft-data `version.json`. +- **1.20.6 release date (2024-04-29):** CONFIRMED — minecraft.wiki/w/Java_Edition_1.20.6 infobox, fetched 2026-06-19. Protocol 766 confirmed from minecraft-data `version.json`. +- **1.20.5 structured-component count (~60 keys):** The `onMappingDataLoaded()` filler chain in `Protocol1_20_3To1_20_5.java:282–302` makes 53 explicit `.add(StructuredDataKey.*)` calls, plus `.add(VersionedTypes.V1_20_5.structuredDataKeys().keys())` which adds 3 more (`container`, `chargedProjectiles`, `bundleContents` from `StructuredDataKeys1_20_5.java`) — total **56 keys** in ViaVersion's registry. The "~60" approximation is slightly high; corrected to 56. (Mojang's canonical count may differ if any keys are omitted from ViaVersion's tracking; the ViaVersion count is the best available source here.) ## Sources diff --git a/versions/1.21.md b/versions/1.21.md index c706322..457febb 100644 --- a/versions/1.21.md +++ b/versions/1.21.md @@ -122,7 +122,7 @@ Relatively lightweight protocol bump — no new packet types, primarily field ch - **`LEVEL_PARTICLES`:** `always_show` boolean field added after `override_limiter`. VV writes `false` for it when translating down. [VV `Protocol1_21_2To1_21_4.java:registerPackets()` `replaceClientbound(LEVEL_PARTICLES)`] - **`PLAYER_INFO_UPDATE`:** `PROFILE_ACTIONS_ENUM` → `1_21_4` variant (adds "show hat" action). VV writes `true` by default. [VV `Protocol1_21_2To1_21_4.java:registerPackets()`] - **Item components:** `CUSTOM_MODEL_DATA` → `1_21_4` (format extended), `TRIM` → `1_21_4`. -- **`PLAYER_LOADED` serverbound:** Added (0x2A in 1.21.5 but arrives at 768→769 boundary). +- **`PLAYER_LOADED` serverbound:** Added at protocol **769 (1.21.4)** — `ServerboundPackets1_21_4.java` includes it at 0x2A, and `EntityPacketRewriter1_21_4.java:63` cancels it downward (`protocol.cancelServerbound(ServerboundPackets1_21_4.PLAYER_LOADED)`), confirming 769 is the introduction boundary. It is not present in the 1.21.2 (768) serverbound enum (0x2A there is `RECIPE_BOOK_CHANGE_SETTINGS`). In 1.21.5 it shifts to 0x2A in the new numbering (`ServerboundPackets1_21_5.java:64`). Source: ViaVersion `v1_21_2to1_21_4/rewriter/EntityPacketRewriter1_21_4.java:63`, `v1_21_2to1_21_4/packet/ServerboundPackets1_21_4.java:64`, `v1_21to1_21_2/packet/ServerboundPackets1_21_2.java` (no PLAYER_LOADED entry). - VV does NOT add a `ChunkLoadTracker` for 1.21.4 clients — Mojang fixed the rendering bug in this release. [VV `Protocol1_21To1_21_2.java:init()` comment] --- @@ -263,7 +263,8 @@ All existing IDs shift up accordingly — packet count goes from 134 (0x85) in 7 `DEBUG_SAMPLE_SUBSCRIPTION` serverbound changed: from a single `type: varint` to a list `count: varint` + per-entry `registry_id: varint`. VV maps the new `DEDICATED_SERVER_TICK_TIME` subscription (id=0) back to the old `TICK_TIME` type (0). [VV `Protocol1_21_7To1_21_9.java:registerServerbound(DEBUG_SAMPLE_SUBSCRIPTION)`] #### `SET_DEFAULT_SPAWN_POSITION` - + +In **773 (1.21.9)** this packet gained two new fields: a **dimension identifier** (string) prepended before the block position, and a **pitch float** appended after the yaw float. ViaVersion's handler reads `BLOCK_POSITION1_14`, gets the current dimension from `tracker(wrapper.user()).currentWorld()`, writes `GLOBAL_POSITION` (dimension string + block position), passthroughs the yaw float, then writes `pitch=0F`. Old format (≤ 772): `BlockPosition + float yaw`; new format (773+): `String dimension + BlockPosition + float yaw + float pitch`. Source: `v1_21_7to1_21_9/rewriter/EntityPacketRewriter1_21_9.java:80–90`; `GlobalBlockPositionType.java` (dimension written as string before position). --- diff --git a/versions/1.7.md b/versions/1.7.md index 9215392..3fd93b6 100644 --- a/versions/1.7.md +++ b/versions/1.7.md @@ -12,27 +12,33 @@ |---|---|---|---| | 1.7.2 | 4 | 2013-10-25 | — | | 1.7.3 | 4 | 2013-10-26 | yes, with 1.7.2 | -| 1.7.4 | 4 | 2013-12-09 | yes, with 1.7.2–3 | -| 1.7.5 | 4 | 2014-02-26 | yes, with 1.7.2–4 | +| 1.7.4 | 4 | 2013-12-10 | yes, with 1.7.2–3 | +| 1.7.5 | 4 | 2014-02-26 | yes, with 1.7.2–4 | | 1.7.6 | **5** | 2014-04-09 | **incompatible** with 1.7.2–5 | -| 1.7.7 | **5** | 2014-04-10 | yes, with 1.7.6 | -| 1.7.8 | **5** | 2014-06-16 | yes, with 1.7.6–7 | -| 1.7.9 | **5** | 2014-06-16 | yes, with 1.7.6–8 | +| 1.7.7 | **5** | 2014-04-09 | yes, with 1.7.6 | +| 1.7.8 | **5** | 2014-04-11 | yes, with 1.7.6–7 | +| 1.7.9 | **5** | 2014-04-14 | yes, with 1.7.6–8 | | 1.7.10 | **5** | 2014-06-26 | yes, with 1.7.6–9 | Sources: - minecraft.wiki `/w/Java_Edition_1.7.2` (fetched 2026-06-19) — release date, protocol 4, Netty rewrite +- minecraft.wiki `/w/Java_Edition_1.7.4` (fetched 2026-06-19) — release date 2013-12-10 (pre-release was 2013-12-09; full release differs) +- minecraft.wiki `/w/Java_Edition_1.7.5` (fetched 2026-06-19) — release date 2014-02-26, protocol 4 confirmed - minecraft.wiki `/w/Java_Edition_1.7.6` (fetched 2026-06-19) — release date 2014-04-09, protocol 5 confirmed +- minecraft.wiki `/w/Java_Edition_1.7.7` (fetched 2026-06-19) — release date 2014-04-09, protocol 5 confirmed +- minecraft.wiki `/w/Java_Edition_1.7.8` (fetched 2026-06-19) — release date 2014-04-11, protocol 5 confirmed +- minecraft.wiki `/w/Java_Edition_1.7.9` (fetched 2026-06-19) — release date 2014-04-14, protocol 5 confirmed - minecraft.wiki `/w/Java_Edition_1.7.10` (fetched 2026-06-19) — release date 2014-06-26, protocol 5, compatibility note - `/tmp/mcproto-refs/minecraft-data/data/pc/1.7/version.json` — `{"version":5,"minecraftVersion":"1.7.10","majorVersion":"1.7"}` The protocol-version page on minecraft.wiki (fetched 2026-06-19) listed all of 1.7.2–1.7.10 as protocol 4; the per-version pages for 1.7.6 and 1.7.10 individually confirm protocol 5, and the minecraft-data canonical record for -`1.7.10` is version 5. The per-version pages are the higher-fidelity source; - the exact boundary (whether 1.7.2–1.7.5 = 4 and 1.7.6–1.7.10 = 5 -is consistent with the protocol-version list being incomplete/erroneous for the -1.7 range). +`1.7.10` is version 5. The per-version pages are the higher-fidelity source. +The split is confirmed: 1.7.2–1.7.5 = protocol 4; 1.7.6–1.7.10 = protocol 5. +The protocol-version list page is incomplete/erroneous for the 1.7 range. +(Sources: minecraft.wiki per-version articles for 1.7.6 and 1.7.10, fetched 2026-06-19; +`minecraft-data/data/pc/1.7/version.json`.) --- @@ -126,14 +132,22 @@ Key changes at the wire level: `packet_named_entity_spawn` (Play 0x0C S→C) already carried a `data` array of property `{name, value, signature}` triples in the minecraft-data 1.7 schema — this is the textures property bag that carries the signed skin URL. - whether this field was added in 1.7.2 or specifically in 1.7.6 - (it is present in the 1.7.10 protocol.json which covers protocol 5). + - **Name-change infrastructure**: Server-side preparation for player name changing (actual service launched 2015-02-04). No packet-schema change, but UUID-keyed identity was reinforced. -- **Per-server resource pack option**: `packet_resource_pack_send` exact packet ID / whether this is a new Play packet in protocol 5 or - re-uses an existing custom\_payload channel. +- **Per-server resource pack option**: The 1.7.6 UI change ("per-server resource + pack" option with prompt/enabled/disabled modes) was a client UI feature, not a + new Play packet. `packet_resource_pack_send` does **not** appear in the 1.7 + protocol.json — it was added in 1.8 as Play CB 0x48. The 1.7.6 feature + operated through the existing client options flow, not a new wire packet. + (Source: `/tmp/mcproto-refs/minecraft-data/data/pc/1.7/protocol.json` play.toClient + mapper — no resource_pack_send entry; 1.8 protocol.json play.toClient 0x48 = + "resource_pack_send".) - The 1.7.6 client was incompatible with 1.7.2–1.7.5 servers (confirmed by minecraft.wiki 1.7.6; fetched 2026-06-19), making the protocol-5 boundary hard. @@ -179,8 +193,13 @@ No S→C packets in this state. Notes: - No Login Compression packet (0x03) — that is a 1.8 addition. - `publicKey` and `verifyToken` use **i16** (signed 16-bit) as the length - prefix, not VarInt; this is a known 1.7 quirk that 1.8 also retains - exact format change in 1.8 if any. + prefix, not VarInt. **1.8 changed both** to VarInt-prefixed buffers (both + S→C Encryption Request and C→S Encryption Response / sharedSecret). This was + confirmed to be a 1.8 change by comparing `packet_encryption_begin` in both + `protocol.json` files: 1.7 uses `{"countType":"i16"}`, 1.8 uses + `{"countType":"varint"}` for all four buffer fields across both directions. + (Source: `minecraft-data/data/pc/1.7/protocol.json` and + `minecraft-data/data/pc/1.8/protocol.json` login.toClient + login.toServer.) - `uuid` in Login Success is transmitted as a **string** (hyphenated UUID text), not as two i64 fields — that encoding came later. @@ -325,8 +344,12 @@ Source: `protocol.json` `types.position_iii` / `position_isi` / `position_ibi`. The client-to-server Player Position packets include a `stance` field (f64) representing the player's eye height offset above their feet (typically `y + 1.62`). The server uses this for hitbox calculations. The `stance` field was **removed in -1.8** when the server began computing it server-side. - exact removal version. +1.8** when the server began computing it server-side. Confirmed: `packet_position` +and `packet_position_look` in `minecraft-data/data/pc/1.7/protocol.json` contain +`stance:f64`; the same packets in `data/pc/1.8/protocol.json` do not — the field +is entirely absent. Removal version: 1.8 (protocol 47). +(Source: `minecraft-data/data/pc/1.7/protocol.json` and `data/pc/1.8/protocol.json` +play.toServer `packet_position` field lists.) ### Plugin Message channel data length In 1.7, `packet_custom_payload` (both directions) uses an **i16** length prefix @@ -420,12 +443,12 @@ detail. |---|---|---| | Framing | VarInt length + VarInt ID | Same in 1.8+ | | Compression | None | Login Compression added in 1.8 (0x03 Login packet) | -| Encryption | RSA-1024 key exchange, AES/CFB8 shared secret, verifyToken — same mechanism as 1.8+ | i16 length prefix on `publicKey`/`verifyToken` buffers (vs VarInt in later versions ) | +| Encryption | RSA-1024 key exchange, AES/CFB8 shared secret, verifyToken — same mechanism as 1.8+ | i16 length prefix on `publicKey`/`verifyToken` buffers; changed to VarInt in 1.8 (confirmed from `packet_encryption_begin` in both `protocol.json` files) | | Entity IDs in Play | Mix of i32 and VarInt (e.g. `entity_destroy` uses i32 array, `animation` uses VarInt) | Standardised to VarInt in 1.8 | | Position encoding | Three separate i32/i16/u8 fields | Packed 64-bit Position type added in 1.8 | | Slot NBT | `compressedNbt` (zlib-compressed) | Uncompressed NBT after 1.8 | | Player stance | Client sends `stance` (f64) in position packets | Removed in 1.8 | -| Login Success UUID | String (hyphenated text) | Two i64 fields in 1.16+ | +| Login Success UUID | String (hyphenated text) | Binary UUID (two i64 fields) from 1.16 (confirmed: `ClientboundBaseProtocol1_16.java` in ViaVersion overrides `passthroughUUID` to use `Types.UUID` instead of `Types.STRING`; `ClientboundBaseProtocol1_7.java` uses `Types.STRING`) | | Player List Item | Simple {name, online, ping} per-packet | Replaced with action-tagged packet in 1.8 | | Chunk format | zlib-compressed section bitmask + addBitMap; separate MapChunkBulk for multi-chunk | Restructured in 1.9 | @@ -439,8 +462,12 @@ Velocity modern forwarding uses a **Login Plugin Request / Response** exchange i the Login state (added in 1.13). 1.7 clients do not support Login Plugin messages; a Velocity-in-modern-mode proxy cannot forward 1.7 clients without a ViaLegacy bridge that intercepts the Login Plugin exchange on behalf of the 1.7 -client. exact Velocity behaviour when a 1.7 client hits a -modern-forwarding backend. +client. --- diff --git a/versions/1.8.md b/versions/1.8.md index 2c5ada1..e1c2715 100644 --- a/versions/1.8.md +++ b/versions/1.8.md @@ -182,7 +182,7 @@ Both 1.7 and 1.8 use the same sentinel-terminated metadata loop structure: - End of stream signalled by byte `0x7F` (127). - Entry values by type: 0=i8, 1=i16, 2=i32, 3=f32, 4=string, 5=slot, 6={x:i32,y:i32,z:i32}, 7={pitch:f32,yaw:f32,roll:f32}. -The type table is identical in both versions (verified from `entityMetadataItem` in both `protocol.json` files). However, the set of actual metadata indices and their meanings changed for several entity types in 1.8 to accommodate new entity properties (guardians, rabbits, armor stands). +The type table is identical in both versions (verified from `entityMetadataItem` in both `protocol.json` files). However, the set of actual metadata indices and their meanings changed for several entity types in 1.8 to accommodate new entity properties (guardians, rabbits, armor stands). The container types `entityMetadata` and `entityMetadataItem` in 1.8's `protocol.json` are structurally identical to 1.7 — confirming that the metadata **encoding format** did not change between protocol 5 and 47; the changes were in which indices are used, not the framing. @@ -212,7 +212,7 @@ The per-section data layout in 1.8 encodes blocks as **block-state IDs** — a s The `addBitMap` field and the separate metadata nibble plane are gone entirely. Block state IDs are the canonical 1.8+ block representation: e.g., oak log facing north is a single integer distinct from oak log facing east, rather than `id=17, meta=4` vs `id=17, meta=0`. -The `Multi Block Change` record format reflects this too: in 1.7, each record packed `{metadata:4bits, blockId:12bits}` in one i16 plus a separate `y:u8` and `{x:4bits,z:4bits}` nibble. In 1.8, each record is `{horizontalPos:u8, y:u8, blockId:varint}` where `blockId` is the full block-state ID. +The `Multi Block Change` record format reflects this too: in 1.7, each record packed `{metadata:4bits, blockId:12bits}` in one i16 plus a separate `y:u8` and `{x:4bits,z:4bits}` nibble. In 1.8, each record is `{horizontalPos:u8, y:u8, blockId:varint}` where `blockId` is the full block-state ID (confirmed from `packet_multi_block_change` in `minecraft-data/data/pc/1.8/protocol.json` — `{"countType":"varint"}` for blockId). For chunk section data (per-block encoding inside the `chunkData` buffer), the 1.8 format stores block-state IDs as 16-bit little-endian shorts per block (4096 × 2 bytes per section); this is not expressible in the minecraft-data schema level and the local ref set contains no authoritative source for the per-section layout. --- @@ -365,11 +365,11 @@ Source: `minecraft-data/data/pc/1.8/protocol.json` packet mapper sections. ViaVe **Compression negotiation at the proxy.** A proxy operating in front of a 1.8+ server must intercept `Set Compression` (login 0x03) from the backend and decide whether to relay, modify, or suppress it. The compression threshold may differ between the proxy's own connection to the client and the proxy-to-server leg. BungeeCord and Velocity both intercept this packet and re-issue their own `Set Compression` to the client with their own threshold, then maintain separate compression state for each half of the connection. -**Position type translation.** Any proxy accepting 1.7 clients and forwarding to a 1.8+ server must translate between the old triple-i32/i16 position types and the new packed `i64` `position` type for every block-coordinate field (spawn_position, bed, block_change, block_action, block_break_animation, update_sign, tile_entity_data, open_sign_entity, world_event, and on the serverbound side: block_dig, block_place, update_sign). +**Position type translation.** Any proxy accepting 1.7 clients and forwarding to a 1.8+ server must translate between the old triple-i32/i16 position types and the new packed `i64` `position` type for every block-coordinate field (spawn_position, bed, block_change, block_action, block_break_animation, update_sign, tile_entity_data, open_sign_entity, world_event, and on the serverbound side: block_dig, block_place, update_sign). **block_change metadata removal.** A 1.7-to-1.8 translator must combine the 1.7 `{type:varint, metadata:u8}` pair into a single 1.8 block-state VarInt on `block_change`, and split in the reverse direction. -**Stance removal.** The 1.7 serverbound `position` packet had a `stance:f64` field (eye-height offset for collision) that was removed in 1.8. A proxy bridging 1.7→1.8 must strip this field; a 1.8→1.7 bridge must synthesise it (typically `y + 1.62`). +**Stance removal.** The 1.7 serverbound `position` packet had a `stance:f64` field (eye-height offset for collision) that was removed in 1.8 (confirmed from protocol.json diff). A proxy bridging 1.7→1.8 must strip this field; a 1.8→1.7 bridge must synthesise it (commonly cited as `y + 1.62` for the default player eye height). **Player Info restructure.** The flat single-player `player_info` from 1.7 (`playerName, online, ping`) was replaced in 1.8 with the action-based multi-player structure. Proxies doing tab-list passthrough must understand the 1.8 structure. @@ -381,7 +381,11 @@ Source: `minecraft-data/data/pc/1.8/protocol.json` packet mapper sections. ViaVe All 1.8.x patches share **protocol 47**. Patch releases addressed server-side exploits (combat, enchantment mechanics, item duplication), server crash vectors, and connectivity bugs but made **no wire-format changes**. A 1.8 client connects to a 1.8.9 server without negotiation issues, and vice versa. - +Confirmed: all 1.8.x releases share protocol 47. The minecraft-data `version.json` +for the 1.8 majorVersion slot records `{"version":47,"minecraftVersion":"1.8.8"}`, +and the minecraft-data schema keys the entire 1.8 family to a single `protocol.json` +with no sub-version splits — consistent with zero wire-format changes across the +patch line. (Source: `minecraft-data/data/pc/1.8/version.json`.) --- diff --git a/versions/1.9.md b/versions/1.9.md index 52cf2b0..f2e9221 100644 --- a/versions/1.9.md +++ b/versions/1.9.md @@ -66,7 +66,7 @@ The table below lists every 1.8 packet by name, its 1.8 ID, and what happened to | `entity_teleport` | 0x18 | `entity_teleport` | 0x4A | renumbered; position changed from Int×(1/32) to Double; +on-ground Boolean | | `entity_head_rotation` | 0x19 | `entity_head_rotation` | 0x34 | renumbered | | `entity_status` | 0x1A | `entity_status` | 0x1B | renumbered | -| `attach_entity` | 0x1B | `attach_entity` | 0x3A | renumbered; leash Boolean field removed (1.9 uses `set_passengers` for riding) | +| `attach_entity` | 0x1B | `attach_entity` | 0x3A | renumbered; leash Boolean field removed in 1.9 (1.7/1.8 had `leash:bool`; 1.9 `attach_entity` has only `entityId:i32` + `vehicleId:i32`); riding now handled by `set_passengers` (0x40). (Confirmed from `packet_attach_entity` in `minecraft-data/data/pc/1.8/protocol.json` vs `data/pc/1.9/protocol.json`.) | | `entity_metadata` | 0x1C | `entity_metadata` | 0x39 | renumbered; metadata format revised (new EntityDataTypes1_9) | | `entity_effect` | 0x1D | `entity_effect` | 0x4C | renumbered | | `remove_entity_effect` | 0x1E | `remove_entity_effect` | 0x31 | renumbered | @@ -216,7 +216,13 @@ The 1.8 `map_chunk_bulk` (0x26) packet is gone; all chunk data is sent as indivi - Sections are length-prefixed in a single VAR_INT-prefixed byte array. - Block light and sky light are appended per section directly after palette+data. - Biome array (256 bytes) follows all sections for full-chunk packets. -- No embedded block-entity NBT (that arrives in a separate `tile_entity_data` 0x09 packet or via `FakeTileEntities` during translation). +- No embedded block-entity NBT (confirmed: `packet_map_chunk` in + `minecraft-data/data/pc/1.9/protocol.json` has fields `x, z, groundUp, bitMap, + chunkData` only — no `blockEntities` array; that field was added in 1.9.4 / + protocol 110 and is present in `data/pc/1.9.4/protocol.json`). Block entity + data arrives via separate `tile_entity_data` (0x09) packets or is synthesised + by ViaVersion's `FakeTileEntities` when translating 1.9 chunks for 1.9.3+ + clients. Source: `ViaVersion/api/src/main/java/com/viaversion/viaversion/api/type/types/chunk/ChunkType1_9_1.java`. diff --git a/versions/26.md b/versions/26.md index 3b86752..4cf7a5a 100644 --- a/versions/26.md +++ b/versions/26.md @@ -3,11 +3,11 @@ | Version | Protocol | Data Version | Release Date | |---|---|---|---| | 26.1 | 775 | 4786 | 2026-03-24 | -| 26.1.1 | 775 | 4788 | | -| 26.1.2 | 775 | 4790 | | +| 26.1.1 | 775 | 4788 | 2026-04-01 | +| 26.1.2 | 775 | 4790 | 2026-04-09 | | 26.2 | 776 | 4903 | 2026-06-16 | -Sources: minecraft.wiki/w/Java_Edition_26.1 (fetched 2026-06-19), minecraft.wiki/w/Java_Edition_26.2 (fetched 2026-06-19), minecraft-data `protocolVersions.json` (`/tmp/mcproto-refs/minecraft-data/data/pc/common/protocolVersions.json`), ViaVersion `ProtocolVersion.java:96` (`/tmp/mcproto-refs/ViaVersion`). +Sources: minecraft.wiki/w/Java_Edition_26.1 (fetched 2026-06-19), minecraft.wiki/w/Java_Edition_26.1.1 (fetched 2026-06-19), minecraft.wiki/w/Java_Edition_26.1.2 (fetched 2026-06-19), minecraft.wiki/w/Java_Edition_26.2 (fetched 2026-06-19), minecraft-data `protocolVersions.json` (`/tmp/mcproto-refs/minecraft-data/data/pc/common/protocolVersions.json`), ViaVersion `ProtocolVersion.java:96` (`/tmp/mcproto-refs/ViaVersion`). --- @@ -225,7 +225,7 @@ The `dimension_type` registry entry gains `has_ender_dragon_fight` (computed fro **Pack formats:** Resource pack 88.0, Data pack 107.1. **Minimum Java:** Java SE 25 (unchanged). -> **Source note:** The ViaVersion clone (`/tmp/mcproto-refs/ViaVersion`) predates 26.2 — no `v26_1to26_2` package exists in the local ref. Protocol 776 is confirmed from minecraft-data `protocolVersions.json` (entry `{'minecraftVersion': '26.2', 'version': 776, 'dataVersion': 4903}`) and minecraft.wiki/w/Java_Edition_26.2 (fetched 2026-06-19). The packet-level diff below is from wiki sources only. +> **Source note:** The ViaVersion clone (`/tmp/mcproto-refs/ViaVersion`) predates 26.2 — no `v26_1to26_2` package exists in the local ref. Protocol 776 is confirmed from minecraft-data `protocolVersions.json` (entry `{'minecraftVersion': '26.2', 'version': 776, 'dataVersion': 4903}`) and minecraft.wiki/w/Java_Edition_26.2 (fetched 2026-06-19). The packet-level diff below is from wiki sources only. All 776 protocol claims in this section remain wiki-sourced and should be re-verified against ViaVersion `v26_1to26_2` once that package ships. ### Headline gameplay changes (mc-wiki, fetched 2026-06-19) @@ -234,12 +234,12 @@ The `dimension_type` registry entry gains `has_ender_dragon_fight` (computed fro - **Sulfur Cube mob**: passive mob with 12 archetypes (`regular`, `bouncy`, `slow_bouncy`, `fast_flat`, `slow_flat`, `light`, `fast_sliding`, `slow_sliding`, `high_resistance`, `sticky`, `explosive`, `hot`). Physics properties driven by absorbed blocks; can absorb TNT to become explosive. - **Music Disc "Bounce"**: by fingerspit. - **`/unpublish` command**: disconnects the integrated (LAN) server. -- **Friends List**: in-game friend request management system. +- **Friends List**: in-game friend request management system. - **Vulkan 1.2 renderer** (experimental): optional renderer with automatic OpenGL fallback. ### Protocol changes in 776 -Sources: minecraft.wiki/w/Java_Edition_26.2 (fetched 2026-06-19). No ViaVersion source available for this bump. All protocol claims in this section are wiki-only. +Sources: minecraft.wiki/w/Java_Edition_26.2 (fetched 2026-06-19). No ViaVersion source available for this bump. All protocol claims in this section are wiki-only and should be reverified against ViaVersion `v26_1to26_2` once available. #### New entity attributes @@ -267,19 +267,19 @@ Five new entity attributes registered server-side and sent in `UPDATE_ATTRIBUTES #### World generation feature renames -`pointed_dripstone` feature type renamed to `speleothem`; `dripstone_cluster` renamed to `speleothem_cluster`. Impacts `LEVEL_CHUNK_WITH_LIGHT` structural data for affected chunk regions. +`pointed_dripstone` feature type renamed to `speleothem`; `dripstone_cluster` renamed to `speleothem_cluster`. #### New density function -`minecraft:interval_select`: threshold-based density function selector. Server-side only (world generation); not directly in the play protocol. +`minecraft:interval_select`: threshold-based density function selector. Server-side only (world generation); not directly in the play protocol. #### Predicate restructuring -Entity predicate `type` field renamed to `minecraft:entity_type`; new `minecraft:entity_tags` sub-predicate. Affects datapack commands and any packets that embed predicates (e.g. `COMMANDS` argument types). +Entity predicate `type` field renamed to `minecraft:entity_type`; new `minecraft:entity_tags` sub-predicate. Wiki confirms the predicate restructuring but does not specify which packets carry the changed predicate format. #### Chunk section changes - + #### Particle additions @@ -332,7 +332,7 @@ The ViaVersion ref predates 26.2. Expected translation requirements (from wiki a - New game event `bounce` can be suppressed without client-visible impact. - Entity predicate restructuring may affect `COMMANDS` packet argument types. - +All items above are derived from wiki analysis only; reverify against ViaVersion `v26_1to26_2` once that package ships. ---