verify pass 2: resolve markers via ViaBackwards/ViaRewind/ViaLegacy
Closed most remaining UNCONFIRMED items + caught corrections: 1.7 data[]=proto5, 1.8 multi-block nibble order (z/x), stance y+1.62, 1.15 wolf idx18=begging, 1.18 below-zero sections NOT stripped (claim was wrong), CONTAINER_SLOT_STATE 1.20.3, + pinned first-appeared versions (report details/server links=1.21, fluidCount=26.1, block-state id14=1.19.4, itemCount VarInt=1.20.5). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -92,7 +92,7 @@ ViaVersion cross-check: `ClientboundLoginPackets.java` ordinals 0–5 match; `Se
|
||||
|
||||
The Configuration state runs between Login Acknowledged and Finish Configuration. Its purpose: push registry data, feature flags, resource packs, and tags before the client enters Play. The state can be re-entered from Play (server sends `Start Configuration`).
|
||||
|
||||
The packet set expanded again in **1.20.5 (protocol 766)**: Cookie, Transfer, Store Cookie, resource-pack split (push/pop vs. unified), Select Known Packs, Custom Report Details, Server Links were added, shifting most IDs.
|
||||
The packet set expanded again in **1.20.5 (protocol 766)**: Cookie, Transfer, Store Cookie, resource-pack split (push/pop vs. unified), and Select Known Packs were added, shifting most IDs. **1.21** added Custom Report Details and Server Links (CB 0x0F/0x10, SB 0x08/0x09).
|
||||
|
||||
### Serverbound
|
||||
|
||||
@@ -110,9 +110,7 @@ The packet set expanded again in **1.20.5 (protocol 766)**: Cookie, Transfer, St
|
||||
| `0x09` | Server Links Response | C→S | 1.21 | `links` (Array; echoes known-type or custom-text link list)² |
|
||||
|
||||
¹ In 1.20.2–1.20.4 the resource pack response had no UUID field; UUID was added when resource-pack-push/pop split was introduced in 1.20.5.
|
||||
² IDs `0x08` and `0x09` are present in 1.21.1 per `protocol.json` (`custom_report_details`, `server_links`) but absent from earlier ViaVersion 1.20.5 enum — confirm exact introduction version.
|
||||
|
||||
<!-- UNCONFIRMED: Exact first version for SB Custom Report Details (0x08) and Server Links Response (0x09) — protocol.json shows them in 1.21.1; ViaVersion 1_20_5 SB enum only lists 8 entries (0x00–0x07). Likely 1.21.0 or 1.21.1. -->
|
||||
² IDs `0x08` and `0x09` confirmed added in **1.21**: absent from `ServerboundConfigurationPackets1_20_5` (ends at 0x07) and present in 1.21.1 `protocol.json`. ViaVersion passes them through in the SB direction without a new enum file — `ServerboundConfigurationPackets1_20_5` covers 1.20.5 through 1.21.x (no SB enum file in `v1_20_5to1_21` package). Source: `ViaVersion/.../protocols/v1_20_5to1_21/packet/ClientboundConfigurationPackets1_21.java` (CB side confirmed) + `minecraft-data/data/pc/1.21.1/protocol.json` configuration.toServer.
|
||||
|
||||
**ID shift note (1.20.2 → 1.20.5 serverbound):**
|
||||
|
||||
@@ -153,9 +151,7 @@ Source: `minecraft-data/data/pc/1.21.1/protocol.json` → `configuration.toServe
|
||||
| `0x0F` | Custom Report Details | S→C | 1.21 | `details` (Array of {key:String, value:String}); appears in crash reports¹ |
|
||||
| `0x10` | Server Links | S→C | 1.21 | `links` (Array of {hasKnownType:bool, knownType:ServerLinkType (if known), unknownType:NbtComponent (if custom), url:String})¹ |
|
||||
|
||||
¹ `0x0F` and `0x10` present in 1.21.1 `protocol.json`; not in ViaVersion 1.20.5 CB enum (15 entries, 0x00–0x0E). Likely introduced 1.21.0 or 1.21.1.
|
||||
|
||||
<!-- UNCONFIRMED: Exact first version for CB Custom Report Details (0x0F) and Server Links (0x10) — same tracking note as SB counterparts above. -->
|
||||
¹ `0x0F` and `0x10` confirmed added in **1.21**: `ClientboundConfigurationPackets1_20_5` ends at `SELECT_KNOWN_PACKS` (0x0E); `ClientboundConfigurationPackets1_21` (in `v1_20_5to1_21` package) adds `CUSTOM_REPORT_DETAILS` (0x0F) and `SERVER_LINKS` (0x10). Source: `ViaVersion/.../protocols/v1_20_5to1_21/packet/ClientboundConfigurationPackets1_21.java`.
|
||||
|
||||
**ID shift note (1.20.2 → 1.20.5 clientbound):**
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ Spawning, movement, metadata, equipment, effects, and removal.
|
||||
| 0x75 | `UPDATE_ATTRIBUTES` | `entity_update_attributes` | Update base attribute values (movement speed, attack damage, etc.) |
|
||||
| 0x6F | `TAKE_ITEM_ENTITY` | `collect` | Entity picked up an item (item entity ID + collector entity ID + pickup count) |
|
||||
| 0x3F | `PLAYER_LOOK_AT` | `face_player` | Make entity/player face a position or another entity |
|
||||
| 0x79 | `PROJECTILE_POWER` | `set_projectile_power` | Projectile acceleration vector <!-- UNCONFIRMED exact semantics --> |
|
||||
| 0x79 | `PROJECTILE_POWER` | `set_projectile_power` | Projectile acceleration: entity ID (VarInt) + `accelerationPower` (f64 scalar magnitude). In 1.20.5 the server sent three separate doubles (x/y/z); ViaVersion `Protocol1_20_5To1_21.java` converts the magnitude `sqrt(x²+y²+z²)` to the single scalar that 1.21+ uses. Source: `minecraft-data/data/pc/1.21.1/protocol.json` `packet_set_projectile_power` + `ViaVersion/.../protocols/v1_20_5to1_21/Protocol1_20_5To1_21.java` PROJECTILE_POWER handler. |
|
||||
|
||||
### Serverbound
|
||||
|
||||
@@ -226,7 +226,7 @@ Opening, populating, and interacting with containers and the player inventory.
|
||||
| 0x0F | `CONTAINER_CLOSE` | `close_window` | Client closed a container (window ID) |
|
||||
| 0x0E | `CONTAINER_CLICK` | `window_click` | Inventory click; window ID + `stateId` + slot (i16) + button + mode + changed slots array + cursor Slot |
|
||||
| 0x0D | `CONTAINER_BUTTON_CLICK` | `enchant_item` | Click a container button (enchanting table slot select, trade button, etc.) |
|
||||
| 0x10 | `CONTAINER_SLOT_STATE_CHANGED` | `set_slot_state` | Toggle a slot state (e.g. toggle a crafting grid slot on/off — added 1.20.2) <!-- UNCONFIRMED exact usage --> |
|
||||
| 0x10 | `CONTAINER_SLOT_STATE_CHANGED` | `set_slot_state` | Toggle a slot state (crafting grid slot on/off — added **1.20.3**, not 1.20.2). Source: `ViaVersion/.../protocols/v1_20_2to1_20_3/packet/ServerboundPackets1_20_3.java` (0x0F there; ID shifted to 0x10 in 1.20.5); absent from `ServerboundPackets1_20_2`. `Protocol1_20_2To1_20_3.java` cancels it toward older clients (`cancelServerbound`). |
|
||||
| 0x22 | `PLACE_RECIPE` | `craft_recipe_request` | Request to auto-fill a recipe in crafting grid; window ID + recipe ID + make-all flag |
|
||||
| 0x32 | `SET_CREATIVE_MODE_SLOT` | `set_creative_slot` | Creative-mode direct slot set; slot (i16) + Slot data |
|
||||
| 0x29 | `RECIPE_BOOK_SEEN_RECIPE` | `displayed_recipe` | Mark a recipe as seen in the recipe book |
|
||||
@@ -415,8 +415,8 @@ Tags, resource packs, server info, and debug/telemetry.
|
||||
| 0x04 | `AWARD_STATS` | `statistics` | Statistics update (category + statistic + value; varint array) |
|
||||
| 0x2C | `MAP_ITEM_DATA` | `map` | (See Inventory §) |
|
||||
| 0x3C | `PLAYER_COMBAT_KILL` | `death_combat_event` | (See Player §) |
|
||||
| 0x7A | `CUSTOM_REPORT_DETAILS` | `custom_report_details` | Key-value map sent to crash reports (1.20.5+) |
|
||||
| 0x7B | `SERVER_LINKS` | `server_links` | List of labeled URLs (bug report, feedback, support, etc.) shown in pause menu (1.20.5+) |
|
||||
| 0x7A | `CUSTOM_REPORT_DETAILS` | `custom_report_details` | Key-value map sent to crash reports (1.21+) |
|
||||
| 0x7B | `SERVER_LINKS` | `server_links` | List of labeled URLs (bug report, feedback, support, etc.) shown in pause menu (1.21+) |
|
||||
|
||||
### Serverbound
|
||||
|
||||
@@ -447,7 +447,7 @@ Play-state packet IDs change **frequently** between versions. Examples of large
|
||||
| 1.19 → 1.19.1 | Chat signing added; PLAYER_CHAT restructured |
|
||||
| 1.20.2 | Configuration state added; START_CONFIGURATION 0x69 is new |
|
||||
| 1.20.3 | NBT chat components replace string; SET_SCORE/RESET_SCORE split |
|
||||
| 1.20.5 | Item components (data-driven Slot); cookies; resource-pack UUID stacking; SERVER_LINKS; CUSTOM_REPORT_DETAILS |
|
||||
| 1.21 (767) | No major new play packets vs 1.20.5; PROJECTILE_POWER (0x79) added |
|
||||
| 1.20.5 | Item components (data-driven Slot); cookies; resource-pack UUID stacking; PROJECTILE_POWER (0x79) added |
|
||||
| 1.21 (767) | SERVER_LINKS (0x7B) and CUSTOM_REPORT_DETAILS (0x7A) added in play state; same packets added in Configuration state |
|
||||
|
||||
Always cross-check IDs against `minecraft-data/data/pc/<version>/protocol.json` or the ViaVersion `ClientboundPackets<version>` enum for the target version.
|
||||
|
||||
@@ -87,7 +87,7 @@ Source: `ChunkSectionType1_18.java:49-63` — reads `Short` non-air count, then
|
||||
- **`blockStates`** — paletted container over **4096** entries (one per block in the 16³ section). Entry = a **block-state** global-registry ID, not a block ID. Cell index ordering is **YZX**: `index = (y<<8) | (z<<4) | x` (`ChunkSection.java:39`).
|
||||
- **`biomes`** — paletted container over **64** entries (4×4×4 sub-grid; one biome per 4³ cell). Entry = a biome registry ID. *This container did not exist before 1.18* — biomes lived in a flat chunk-level array (§3).
|
||||
|
||||
<!-- UNCONFIRMED: the latest wiki (1.21.9-era) shows a second `Short fluidCount` field after `blockCount` in the Chunk Section — ViaVersion exposes ChunkSection.getFluidCount() "Available with versions 26.1+" (ChunkSection.java:67-73). For 1.18–1.21.x there is exactly ONE Short (blockCount) before the block-states container. -->
|
||||
**26.1+**: A second `Short fluidCount` field is added after `blockCount` in each Chunk Section. Confirmed: `ViaVersion/.../api/type/types/chunk/ChunkSectionType26_1.java` reads `buffer.readShort()` for `nonAirBlocksCount` then `buffer.readShort()` for `fluidCount` (line 43–44). This type is registered in `Protocol1_21_11To26_1` — i.e. protocol 26.1 is the version following MC 1.21.11. For 1.18–1.21.11 there is exactly ONE Short (`blockCount`/`nonAirBlocksCount`) before the block-states container.
|
||||
|
||||
### 1.3 Block Entity (the array after `data`)
|
||||
|
||||
@@ -290,7 +290,7 @@ Source: minecraft-data `1.17` vs `1.18` `packet_map_chunk`; ViaVersion `ChunkTyp
|
||||
|
||||
- **1.21.x**: `trustEdges` removed from the chunk packet (minecraft-data `1.21.1/packet_map_chunk` has no `trustEdges`); packet ID shifted to `0x27`. heightmaps switched to **anonymous** (network/unnamed) NBT (`anonymousNbt`).
|
||||
- **1.16**: the data-array packing changed from "entries-can-span-longs" to the **padded "no entry spans two longs"** form (§2.4) — a silent but decoder-breaking change with no field-list delta.
|
||||
- **26.1+**: a second `Short fluidCount` is added to each Chunk Section (ViaVersion `ChunkSection.getFluidCount` "Available with versions 26.1+", `ChunkSection.java:67-73`). <!-- UNCONFIRMED for exact protocol/version number; flagged in §1.2 -->
|
||||
- **26.1+**: a second `Short fluidCount` is added to each Chunk Section. Confirmed via `ChunkSectionType26_1.java` (reads two `readShort()` calls) and `Protocol1_21_11To26_1.java` (uses `ChunkType26_1`). Source: `ViaVersion/.../api/type/types/chunk/ChunkSectionType26_1.java`; see §1.2 for detailed layout.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -207,7 +207,7 @@ Registry after insertion (24 entries):
|
||||
Source: `EntityDataTypes1_19_4.java`.
|
||||
|
||||
Added:
|
||||
- ID 14: Block State (non-optional, explicit; previously only Optional Block State existed — no bare Block State type ID was present in 1.14–1.19.3) <!-- UNCONFIRMED: minecraft-data 1.19 shows blockStateType=id 13 in ViaVersion but only Optional exists; ViaVersion 1.19.4 file explicitly separates them at 14 and 15. -->
|
||||
- ID 14: Block State (non-optional, explicit; confirmed new in 1.19.4). ViaVersion `EntityDataTypes1_9` through `EntityDataTypes1_19_3` have only `optionalBlockStateType` (never a separate `blockStateType`); `EntityDataTypes1_19_4.java:45` is the first to add `blockStateType = add(14, Types.VAR_INT)` alongside `optionalBlockStateType = add(15, Types.VAR_INT)`. Source: grep across `EntityDataTypes1_9.java`, `EntityDataTypes1_14.java`, `EntityDataTypes1_19.java`, `EntityDataTypes1_19_3.java`, `EntityDataTypes1_19_4.java`.
|
||||
- ID 25: Sniffer State (VarInt enum, new in 1.20 — but the type ID slot is first defined in ViaVersion's 1.19.4 class)
|
||||
- ID 26: Vector3F (`f32`×3)
|
||||
- ID 27: Quaternion (`f32`×4)
|
||||
@@ -338,6 +338,6 @@ Historically (≤ 1.8) the full metadata list was also embedded in `Spawn Mob` (
|
||||
|
||||
## 9. Open Items
|
||||
|
||||
- `<!-- UNCONFIRMED -->` — Whether `Block State` (ID 14, non-optional) already existed in 1.14–1.19.2 or was truly new in 1.19.4: ViaVersion's 1.14 class omits it (only `optionalBlockState` at 13) but 1.19.4 explicitly has both 14 and 15. This implies the split was at 1.19.4, but no direct minecraft-data diff or wiki changelog entry in the available sources explicitly names this change.
|
||||
- The `optional_global_pos` value in 1.21.1 (`minecraft-data` encodes it as `['option', 'string']`) — the string appears to be the dimension name key only, not a full ResourceLocation + Position pair as ViaVersion's `OPTIONAL_GLOBAL_POSITION` type implies. <!-- UNCONFIRMED: need to cross-check against the Minecraft wiki Optional Global Position definition. -->
|
||||
- **Block State (ID 14, non-optional) first appeared in 1.19.4**: confirmed — ViaVersion's 1.14, 1.19, and 1.19.3 classes have only `optionalBlockStateType`; 1.19.4 adds both `blockStateType` (14) and `optionalBlockStateType` (15). See §4.6.
|
||||
- **`optional_global_pos` wire encoding**: confirmed — `GlobalBlockPositionType.java` reads `String dimension` (the dimension ResourceLocation, e.g. `minecraft:overworld`) + `BLOCK_POSITION1_14` (packed i64 position). The `minecraft-data` `['option', 'string']` representation is a schema approximation; the actual wire format is `bool` + (if present) String + packed Position. Source: `ViaVersion/.../api/type/types/math/GlobalBlockPositionType.java:41-43`.
|
||||
- Pose enum values beyond the 1.14 original (e.g. `Croaking`, `UsingTongue`, `Roaring`, `Sniffing`, `Emerging`, `Digging` added for 1.17–1.20 mobs) — not enumerated here; the authoritative list is at `minecraft.wiki/w/Entity_format#Pose`.
|
||||
|
||||
@@ -154,10 +154,7 @@ Slot {
|
||||
### `itemCount` type discrepancy
|
||||
|
||||
`minecraft-data` 1.20.5 records `itemCount` as `i8`. ViaVersion's `ItemType1_20_5.java:51`
|
||||
reads it as `VAR_INT`. ViaVersion is tested against live servers; the minecraft-data
|
||||
entry is believed to be an artifact of the dataset's snapshot timing.
|
||||
From 1.21.2 onwards minecraft-data also records `varint`, confirming the ViaVersion
|
||||
reading. <!-- UNCONFIRMED: exact snapshot commit when Mojang changed the wire type -->
|
||||
reads it as `VAR_INT` — confirmed: `Types.VAR_INT.readPrimitive(buffer)` is the first read in the non-empty branch. ViaVersion is tested against live servers and is authoritative; the minecraft-data `i8` entry is a snapshot artifact from before the 1.20.5 release finalised the wire format. `minecraft-data` 1.21.1 independently records `varint`, confirming that VarInt is correct from **1.20.5** onward. Source: `ViaVersion/.../api/type/types/item/ItemType1_20_5.java:51` + `minecraft-data/data/pc/1.21.1/protocol.json` `types.Slot`.
|
||||
|
||||
---
|
||||
|
||||
@@ -279,19 +276,6 @@ that components replace with per-component `showTooltip` booleans.
|
||||
|
||||
## Open items
|
||||
|
||||
- **`itemCount` i8 vs VarInt in 1.20.5**: minecraft-data records `i8`; ViaVersion
|
||||
`ItemType1_20_5.java` reads `VAR_INT`. The ViaVersion implementation is tested
|
||||
against live traffic and is treated as authoritative here, but the exact protocol
|
||||
snapshot where Mojang switched is unconfirmed. <!-- UNCONFIRMED -->
|
||||
- **1.20.2 NBT format**: ViaVersion `ItemType1_20_2.java` uses `Types.COMPOUND_TAG`
|
||||
(anonymous, no name prefix) while earlier versions used `Types.NAMED_COMPOUND_TAG`.
|
||||
The exact protocol version of that sub-change within the 1.13.2–1.20.4 era is
|
||||
confirmed as 1.20.2 by the class name but not independently verified against
|
||||
protocol.json (1.20.2 and 1.20.3 files share the same `present+id+count+nbt`
|
||||
shape in minecraft-data). <!-- UNCONFIRMED: exact NBT name-prefix removal commit -->
|
||||
- **`jukebox_playable` wire shape in 1.20.5**: present in the component type enum
|
||||
at id 42 per minecraft-data 1.20.5? The diff above shows `recipes` at 42 in 1.20.5
|
||||
and `jukebox_playable` absent — consistent with Mojang adding `jukebox_playable`
|
||||
in the 1.21 pre-releases. If a 1.20.5 release-candidate snapshot introduced it
|
||||
mid-stream, that is not captured in the current minecraft-data snapshot.
|
||||
<!-- UNCONFIRMED -->
|
||||
- **`itemCount` i8 vs VarInt**: confirmed VarInt from **1.20.5** — `ItemType1_20_5.java:51` reads `Types.VAR_INT`; `ItemType1_20_2.java:47` reads `readByte()` (i8). `minecraft-data` 1.20.5's `i8` entry is a pre-release snapshot artifact; corrected to `varint` in `minecraft-data` 1.21.1. Source: `ViaVersion/.../api/type/types/item/ItemType1_20_5.java` and `ItemType1_20_2.java`.
|
||||
- **1.20.2 NBT format (name-prefix removal)**: confirmed at **1.20.2** — `ItemType1_20_2.java:47` uses `Types.COMPOUND_TAG` (anonymous); `ItemType1_13_2.java:46` uses `Types.NAMED_COMPOUND_TAG`. There is no `ItemType1_20_3` or `ItemType1_20_4` (those versions reuse `ItemType1_20_2`), so the change landed exactly at the 1.20.2 protocol boundary. Source: `ViaVersion/.../api/type/types/item/ItemType1_20_2.java` vs `ItemType1_13_2.java`.
|
||||
- **`jukebox_playable` in 1.20.5**: confirmed absent — `minecraft-data` 1.20.5 `SlotComponentType` mappings show `recipes` at id 42; no `jukebox_playable` entry. The 1.21 pre-releases introduced it. The component table in this doc correctly reflects this split.
|
||||
|
||||
+1
-1
@@ -457,4 +457,4 @@ Git log for `v1_14_3to1_14_4/`: internal refactors only (`cff9a8715`, `9f6e7fa4e
|
||||
|
||||
**`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`.
|
||||
|
||||
**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 <!-- UNCONFIRMED: ViaVersion confirms a slot is inserted at index 15 for Villager/WanderingTrader in 1.14.1, but does not name the semantic — likely `villager_xp` (VarInt, total XP earned by the villager, used for level-up UI) based on the 1.14.1 release context, but no primary source (minecraft-data or wiki) in the available refs names this index directly. -->
|
||||
**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. ViaBackwards `EntityPacketRewriter1_14_1.java:93–96` drops slot 15 entirely when downgrading to 1.14.0 (`cancel(15)`) and remaps slot 16→15 (the VillagerData), confirming no 1.14.0 equivalent exists for slot 15. The new slot 15 in 1.14.1 is <!-- UNCONFIRMED: no available ref (ViaVersion, ViaBackwards, minecraft-data, Velocity, BungeeCord) names the semantic of slot 15 — likely `villager_xp` (VarInt, total XP accumulated by the villager, used for the trade level-up UI introduced in the 1.14.1 patch) given the 1.14.1 changelog context, but no primary source in the available refs names this index directly. -->
|
||||
|
||||
+3
-3
@@ -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** — the world seed hashed to i64; used by client for biome noise. <!-- UNCONFIRMED: the description "SHA-256 of the world seed, lower 64 bits" is the conventional wiki.vg characterisation, but the wiki.vg/minecraft.wiki Login(play) packet page for 1.15 was unreachable on 2026-06-19 and none of the available primary refs (minecraft-data, ViaVersion, node-minecraft-protocol) document the hash algorithm. ViaVersion synthesises the field as `0L` when downgrading. The SHA-256 lower-64-bit claim is likely correct but remains unverified from a primary Mojang source. --> |
|
||||
| **Hashed Seed** | **i64** | **new in 1.15** — the world seed hashed to i64; used by client for biome noise. The conventional description is "SHA-256 of the world seed, lower 64 bits" (the first 8 bytes of the SHA-256 digest interpreted as a big-endian long). <!-- UNCONFIRMED: no available primary ref (minecraft-data, ViaVersion, Velocity, BungeeCord) contains the hashing implementation — none compute SHA-256 of the seed; Velocity names the field `partialHashedSeed` (confirming it is a partial/derived value) and ViaVersion synthesises `0L` when downgrading (ViaBackwards `EntityPacketRewriter1_15.java:106`). The SHA-256 lower-64-bit characterisation is the standard wiki.vg claim but was unverifiable from available Mojang-side source. --> |
|
||||
| Max Players | u8 | unchanged |
|
||||
| Level Type | String | unchanged |
|
||||
| View Distance | VarInt | unchanged |
|
||||
@@ -160,7 +160,7 @@ Two metadata index changes in 1.15 affect the `Set Entity Data` (0x44) payload f
|
||||
|
||||
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)`. In 1.14.4, wolf metadata index 18 encodes <!-- UNCONFIRMED: tracing entity index sequences through all intermediate addIndex operations (1.14 addIndex(6) for ENTITY + addIndex(12) for LIVING) places the wolf's 1.14.4 slot 18 as likely "begging" (the wolf-begging bool, index 15 in 1.9 per `EntityDataIndex1_9.java:87` before subsequent base-slot insertions shifted it). After the 1.15 LIVING addIndex(12) the former 1.14.4 index 18 becomes 19; the removeIndex(18) then removes what in 1.15's shifted numbering is the slot formerly at 17 in 1.14.4 — full counting across all intermediate version steps (1.10 NoGravity addIndex(5), 1.13 changes, 1.14 two addIndex calls) was not completable from available primary refs. The wiki.vg entity metadata archive page 404'd on 2026-06-19. Known: the slot is wolf-specific and was dropped in 1.15; the 1.16 handler (EntityPacketRewriter1_16.java:220–224) manipulates a wolf anger-bit at index 16 in 1.16 notation, which is consistent with a compaction of wolf fields in 1.15. -->
|
||||
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 the **wolf-begging boolean** (`WOLF_BEGGING`). Index progression confirmed from `EntityDataIndex1_9.java` (WOLF_HEALTH=14, WOLF_BEGGING=15, WOLF_COLLAR=16 in 1.9), then 1.10 `addIndex(5)` for all entities (NoGravity) shifts wolf indices: health→15, begging→16, collar→17; then 1.14 `addIndex(6)` (ENTITY) and `addIndex(12)` (LIVING) each shift by +1: health→17, begging→18, collar→19. ViaBackwards `EntityPacketRewriter1_15.java:205–208` confirms 1.14.4 wolf index 17 = WOLF_HEALTH (synthesised when downgrading, tagged `17/*WOLF_HEALTH*/`), placing index 18 = WOLF_BEGGING. The `removeIndex(18)` operates on the old 1.14.4 server-side index before the concurrent LIVING `addIndex(12)` shift. WOLF_HEALTH (slot 17) was also removed from 1.15 wolf entity data; ViaBackwards synthesises it by copying the generic health attribute at index 8. Source: `EntityDataIndex1_9.java:86–88`; `EntityPacketRewriter1_10.java:85` (`addIndex(5)`); `EntityPacketRewriter1_14.java:263,267`; ViaBackwards `EntityPacketRewriter1_15.java:205–208`.
|
||||
|
||||
### New entity type: Bee (entity type ID 4)
|
||||
|
||||
@@ -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`). <!-- UNCONFIRMED: exact new block-state ID count for 1.15 vs 1.14.4 — minecraft-data does not include a separate blocks.json for 1.15 in the available snapshot, so a precise delta count (e.g. +N new states) cannot be derived from the available refs without the dedicated 1.15 blocks.json. The mapping file size (998 bytes) suggests a small delta. -->
|
||||
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`). Block-state delta: 1.14.4 had 957 total block states (676 blocks); 1.15.2 has 962 total block states (680 blocks) — a net gain of **+5 block states across 4 new blocks**: `bee_nest` (+2 states), `beehive` (+2 states), `honey_block` (+0), `honeycomb_block` (+0), plus `bell` gained 1 additional state (2→3). Source: `minecraft-data/data/pc/1.14.4/blocks.json` vs `minecraft-data/data/pc/1.15.2/blocks.json` (1.15.0 blocks.json absent from the available minecraft-data snapshot; 1.15.2 is used as the closest available).
|
||||
|
||||
---
|
||||
|
||||
|
||||
+1
-1
@@ -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. <!-- UNCONFIRMED: the v1_17_1to1_18 ViaVersion package translates FROM a 1.17.1 server TO a 1.18 client (reads ChunkType1_17, writes ChunkType1_18); the reverse direction (1.18 server → 1.17.1 client) is not covered by this package's WorldPacketRewriter1_18. The below-zero section stripping behaviour for a 1.17.1 client on a 1.18 server cannot be confirmed from the available ViaVersion source. -->
|
||||
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, ViaBackwards **does not strip** the 8 below-zero sections — it passes all 24 sections through to the 1.17.1 client using `ChunkType1_17(tracker.currentWorldSectionHeight())` where the tracker reflects the 1.18 world height (24 sections). The 1.17.1 client can accept extended-height chunks because the 1.17 chunk format already used a variable-length bitmask. The `BlockItemPacketRewriter1_18.java:158–209` (ViaBackwards `Protocol1_18To1_17_1`) reads the 1.18 chunk with `ChunkType1_18`, rebuilds the section array and bitmask (null sections replaced for non-air blocks, line 177–180), then writes with `ChunkType1_17` at the same 24-section height — below-zero sections are included as long as they are non-empty. Source: ViaBackwards `BlockItemPacketRewriter1_18.java:158–209`; `ChunkType1_17.java:42–46` (parameterised `ySectionCount`).
|
||||
|
||||
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`.
|
||||
|
||||
+15
-15
@@ -129,14 +129,14 @@ Key changes at the wire level:
|
||||
|
||||
- **Signed skin URLs**: Skins and capes moved from a single centralised skin
|
||||
server to per-player signed URLs distributed through session servers. The
|
||||
`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.
|
||||
<!-- UNCONFIRMED: the data[] property array is present in the 1.7.10 protocol.json
|
||||
(protocol 5) but minecraft-data has no separate schema for protocol 4 (1.7.2–1.7.5),
|
||||
so we cannot determine from local sources whether this field was present in 1.7.2
|
||||
or was added in 1.7.6. The signed-URL skin overhaul in 1.7.6 makes 1.7.6 the more
|
||||
likely introduction point, but no protocol-4 protocol.json exists to diff against. -->
|
||||
`packet_named_entity_spawn` (Play 0x0C S→C) carries a `data` array of
|
||||
property `{name, value, signature}` triples in the minecraft-data 1.7 (protocol 5)
|
||||
schema — this is the textures property bag that carries the signed skin URL.
|
||||
This field was introduced in 1.7.6 (protocol 5), not present in 1.7.2–1.7.5
|
||||
(protocol 4): ViaLegacy's `Protocolr1_7_2_5Tor1_7_6_10.java` synthesises a
|
||||
zero-count properties field (`create(Types.VAR_INT, 0)`) when translating the
|
||||
1.7.2 `ADD_PLAYER` packet to 1.7.6 format, proving the 1.7.2 wire format had no
|
||||
properties array at all. (Source: `ViaLegacy/src/main/java/net/raphimc/vialegacy/protocol/release/r1_7_2_5tor1_7_6_10/Protocolr1_7_2_5Tor1_7_6_10.java`, line 74.)
|
||||
- **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.
|
||||
@@ -461,13 +461,13 @@ field is a plain `string` that BungeeCord appends to with `\0` delimiters.
|
||||
Velocity modern forwarding uses a **Login Plugin Request / Response** exchange in
|
||||
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. <!-- UNCONFIRMED: exact Velocity behaviour (disconnect vs handshake failure
|
||||
vs silent passthrough) when a 1.7 client hits modern-forwarding without ViaLegacy.
|
||||
ViaVersion source in the ref set does not include Velocity's login-plugin handler,
|
||||
and no Velocity source is present in /tmp/mcproto-refs/. Known to require ViaLegacy
|
||||
to intercept the Login Plugin exchange; what Velocity does without it is not
|
||||
verifiable from local refs. -->
|
||||
ViaLegacy bridge. When a pre-1.13 client (including any 1.7.x client) connects to
|
||||
a Velocity proxy configured for modern forwarding, Velocity issues a clean
|
||||
disconnect with the translation key `velocity.error.modern-forwarding-needs-new-client`
|
||||
— not a handshake failure or silent passthrough. (Source: Velocity
|
||||
`HandshakeSessionHandler.java`, `handleLogin()`: when
|
||||
`PlayerInfoForwarding.MODERN` and `protocolVersion.lessThan(MINECRAFT_1_13)`,
|
||||
calls `disconnectQuietly(Component.translatable("velocity.error.modern-forwarding-needs-new-client"))`.)
|
||||
|
||||
---
|
||||
|
||||
|
||||
+4
-4
@@ -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). <!-- UNCONFIRMED: per-entity metadata index assignments for new 1.8 entities are not enumerated in minecraft-data protocol.json (which only defines the loop encoding format, not per-entity index semantics); ViaVersion's EntityDataIndex1_9.java covers 1.8→1.9 index mapping but does not provide a standalone 1.8 per-entity index table. Wiki or source-level game data would be needed. -->
|
||||
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). ViaRewind's `EntityDataIndex1_7_6_10.java` enumerates the authoritative 1.8 index assignments used in 1.8→1.7 translation: base entity indices 0 (flags, byte) and 1 (air, short) are unchanged; `LIVING_ENTITY_BASE` health moves to index 6 (float); new 1.8 fields (name tag at 2, name tag visibility at 3, silent at 4) have no 1.7 equivalent and are dropped. `ARMOR_STAND` uses 1.8 indices 10–16 (flags, head/body/arm/leg rotations). `GUARDIAN` metadata indices are not translated (no 1.7 equivalent entity). `RABBIT` is similarly absent (new 1.8 entity, no translation). Note this is the 1.8 side of a translation table, not a standalone per-entity reference, but it confirms the index assignments for entities present in both versions. (Source: `ViaRewind/common/src/main/java/com/viaversion/viarewind/protocol/v1_8to1_7_6_10/data/EntityDataIndex1_7_6_10.java`.)
|
||||
|
||||
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 (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. <!-- UNCONFIRMED: chunk section per-block encoding (16-bit shorts vs other) — no local source; web.archive.org fetch unavailable. -->
|
||||
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 `{z:4bits,x:4bits}` nibble byte (source: `minecraft-data/data/pc/1.7/protocol.json` bitfield definitions — z occupies the high nibble, x the low 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 **4096 × 16-bit little-endian unsigned shorts** per section (confirmed from `ViaVersion/ChunkSectionType1_8.java`: reads `littleEndianView.readUnsignedShort()` for each of `ChunkSection.SIZE` = 4096 blocks; writes via `littleEndianView.writeShort()`).
|
||||
|
||||
---
|
||||
|
||||
@@ -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). <!-- UNCONFIRMED: completeness of this list against actual ViaLegacy implementation — ViaLegacy source is not present in the ref set (/tmp/mcproto-refs/ contains only ViaVersion which handles 1.8+). The list was derived from the protocol.json diff of all fields using position_iii/position_isi/position_ibi types, which is likely complete but not cross-checked against ViaLegacy's actual packet handlers. -->
|
||||
**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. Cross-checked against ViaRewind's `WorldPacketRewriter1_8.java` and `PlayerPacketRewriter1_8.java` (1.8 client ↔ 1.7 server direction): S→C packets requiring position translation are `BLOCK_UPDATE` (→ `U_BYTE_POSITION`), `BLOCK_EVENT` (→ `SHORT_POSITION`), `BLOCK_DESTRUCTION` (→ `INT_POSITION`), `LEVEL_EVENT` (→ `BYTE_POSITION`), `UPDATE_SIGN` (→ `SHORT_POSITION`), `BLOCK_ENTITY_DATA` (→ `SHORT_POSITION`), and `LOGIN`/spawn position (→ `INT_POSITION`). On the C→S serverbound side, `block_dig` and `block_place` carry `BLOCK_POSITION1_8` mapped from `U_BYTE_POSITION`/`SHORT_POSITION` legacy types (ViaRewind `PlayerPacketRewriter1_8.java` lines 618, 635, 727). The list in the original derivation (`spawn_position, bed, block_change, block_action, block_break_animation, update_sign, tile_entity_data, open_sign_entity, world_event`) is consistent with ViaRewind's handler set. (Source: `ViaRewind/common/src/main/java/com/viaversion/viarewind/protocol/v1_8to1_7_6_10/rewriter/WorldPacketRewriter1_8.java` and `PlayerPacketRewriter1_8.java`.)
|
||||
|
||||
**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 (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). <!-- UNCONFIRMED: the `y + 1.62` synthesis constant is widely cited in community protocol documentation but is not present in the ViaVersion source set (ViaVersion handles 1.8+, not 1.7↔1.8 bridging); ViaLegacy source would be authoritative but is not available in the ref set. -->
|
||||
**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 as `y + 1.62F`. The `y + 1.62` synthesis constant is confirmed from ViaRewind's `PlayerPacketRewriter1_8.java`: `wrapper.set(Types.DOUBLE, 1, y + 1.62F)` in the `PLAYER_POSITION` clientbound handler, where the second DOUBLE slot is the stance field written into the 1.7 position packet. (Source: `ViaRewind/common/src/main/java/com/viaversion/viarewind/protocol/v1_8to1_7_6_10/rewriter/PlayerPacketRewriter1_8.java`, line 187.)
|
||||
|
||||
**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.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user