Corrected real errors: several 1.7.x release dates, resource_pack_send version, config packet ordering, structured-component count (56), PLAYER_LOADED (1.21.4), entity_sound_effect field order. Confirmed+cited the rest; remaining ~19 items re-marked UNCONFIRMED (third-party/ViaLegacy/26.2 internals unreachable from refs). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
26 KiB
1.8.x — The Bountiful Update
Protocol: 47
Versions: 1.8 (2014-09-02) through 1.8.9 (2015-12-09) — all share the same protocol number
Minecraft wiki release article: https://minecraft.wiki/w/Java_Edition_1.8 (fetched 2026-06-19)
minecraft-data sources: /tmp/mcproto-refs/minecraft-data/data/pc/1.8/protocol.json, version.json; diff against /tmp/mcproto-refs/minecraft-data/data/pc/1.7/protocol.json
ViaVersion source: /tmp/mcproto-refs/ViaVersion/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/packet/ — ClientboundPackets1_8.java, ServerboundPackets1_8.java
Protocol version confirmed: version.json (/tmp/mcproto-refs/minecraft-data/data/pc/1.8/version.json) = {"version":47,"minecraftVersion":"1.8.8","majorVersion":"1.8"}; 1.7.10 = {"version":5}.
Headline changes
1.8 ("The Bountiful Update") shipped 2014-09-02. On the wire it made three structural additions that defined the protocol for years:
Packet compression. A new Set Compression packet was inserted into the login flow (login-state, clientbound 0x03). From that point forward, each packet carries a second VarInt (Data Length) between the existing Packet Length VarInt and the payload, enabling optional zlib deflate per-packet. This is the biggest framing change since the Netty rewrite in 1.7. See § Compression detail below.
Palette-based block and chunk encoding. The Map Chunk (0x21) and Multi Block Change (0x22) packets switched from the 1.7 format (separate 8-bit block-ID + 4-bit metadata nibble-plane) to a single unified block-state integer. The Multi Block Change record went from a packed {12-bit blockId, 4-bit metadata} bitfield (separate words) to a single VarInt block-state ID per record. The block_change packet's payload similarly changed from {type:varint, metadata:u8} (two fields) to a single {type:varint} block-state ID.
New packed-integer Position type. Block coordinates moved from three separate i32/i16/i32 fields in a position_iii/position_isi/position_ibi struct to a single i64 packed as {x:26-bit signed, y:12-bit signed, z:26-bit signed}. This is the position bitfield type that appears throughout the 1.8 protocol.
Why protocol 47 stayed so long. 1.8 was the last major version for ~17 months (1.9 shipped 2016-02-29). Server operators preferred it for PvP because 1.9 introduced a weapon cooldown mechanic that most competitive networks rejected. Combined with Mojang's slow adoption of forced upgrades, protocol 47 remained the dominant live-traffic version until at least 2017 — the era that spawned the entire ViaVersion ecosystem.
Compression in detail
Cross-reference: ../05-login-encryption.md covers the full login flow; this section focuses on the 1.8 addition.
The Set Compression packet
Sent by the server during the login state, after Login Success is in the pipeline but before it is actually sent:
| State | Direction | ID | Name | Field | Type |
|---|---|---|---|---|---|
| login | clientbound | 0x03 |
Set Compression | threshold | VarInt |
Source: minecraft-data/data/pc/1.8/protocol.json login.toClient mappings "0x03": "compress" and packet_compress definition [{"name":"threshold","type":"varint"}].
The 1.7 login state had only three clientbound packets (0x00 disconnect, 0x01 encryption_begin, 0x02 success). 1.8 added 0x03 compress.
A negative threshold value disables compression. A value ≥ 0 means: packets whose uncompressed payload is ≥ threshold bytes must be zlib-compressed; smaller packets may be sent uncompressed (Data Length = 0).
Framing change: the Data Length VarInt
Before compression is enabled the packet format is identical to 1.7:
[Packet Length : VarInt] [Packet ID : VarInt] [Payload...]
After Set Compression is received, all subsequent packets (in both directions) add a second VarInt:
[Packet Length : VarInt] [Data Length : VarInt] [Packet ID + Payload : zlib or raw]
Packet Length= byte-count of everything that follows, i.e.len(Data Length varint) + len(compressed-or-raw-data).Data Length = 0→ the following bytes are not compressed (uncompressed payload was below threshold).Data Length > 0→ the following bytes are zlib-deflated;Data Lengthis the uncompressed byte count (used to size the decompression buffer).
This second VarInt is invisible in the 1.7 framing; adding it is the entire framing change. The rest of the packet (ID + payload) is structurally unchanged — compression is a wrapper layer only.
Login flow with compression (1.8)
sequenceDiagram
participant C as Client
participant S as Server
C->>S: Login Start (0x00) [username]
S->>C: Encryption Request (0x01) [serverId, pubKey, verifyToken]
C->>S: Encryption Response (0x02) [encSharedSecret, encVerifyToken]
Note over C,S: AES/CFB8 encryption begins (both directions)
S->>C: Set Compression (0x03) [threshold] — NEW in 1.8
Note over C,S: Framing switches to compressed format (both directions)
S->>C: Login Success (0x02) [uuid, username]
Note over C,S: Transition to PLAY state
Note: Set Compression is sent encrypted (after the AES stream is established) but before the state transitions to PLAY. The compression threshold is server-controlled; vanilla default is 256 bytes.
Protocol changes vs 1.7 (from minecraft-data diff)
The 1.7 and 1.8 protocol.json files share the same top-level packet names and IDs for nearly all play-state packets (0x00–0x40 clientbound, 0x00–0x17 serverbound). The protocol-breaking changes are in field types and the new packets. Key diffs:
Handshake state
Identical. Both: 0x00 set_protocol (protocolVersion:varint, serverHost:string, serverPort:u16, nextState:varint).
Login state (clientbound)
| ID | 1.7 packet | 1.8 change |
|---|---|---|
| 0x00 | disconnect | unchanged |
| 0x01 | encryption_begin | field type change: publicKey and verifyToken lengths changed from i16-prefixed buffers (1.7) to varint-prefixed buffers (1.8) |
| 0x02 | success | unchanged (uuid:string, username:string) |
| 0x03 | — | NEW: compress (threshold:varint) |
Source: compare login.toClient in both protocol.json files. In 1.7, packet_encryption_begin uses {"countType":"i16"} for both fields; in 1.8 they use {"countType":"varint"}.
Login state (serverbound)
Same change: 1.8 encryption_begin uses varint-prefixed sharedSecret and verifyToken buffers instead of i16-prefixed.
Play state — new/changed clientbound packets
| ID | Name | 1.7 → 1.8 change |
|---|---|---|
| 0x01 (login) | Login | Added reducedDebugInfo:bool field in 1.8 |
| 0x02 (chat) | Chat | Added position:i8 field in 1.8 (chat box=0, system=1, game info/action bar=2) |
| 0x04 (entity_equipment) | Entity Equipment | Entity ID: i32 → varint |
| 0x05 (spawn_position) | Spawn Position | location: position_iii (3×i32) → packed position (single i64 bitfield) |
| 0x06 (update_health) | Update Health | food: i16 → varint |
| 0x0a (bed) | Use Bed | Entity ID i32 → varint; location: position_ibi → packed position |
| 0x0c (named_entity_spawn) | Named Entity Spawn | Major: removed inline playerName:string and data[] properties array (1.7 sent these inline); added playerUUID:UUID binary type; removed currentItem field; 1.7 had string UUID + full profile inline |
| 0x0d (collect) | Collect | Both entity IDs i32 → varint |
| 0x0e (spawn_entity) | Spawn Entity | objectData refactored: was inline {intField:i32, velocityX/Y/Z:i16-conditional}; same semantics, slightly different schema |
| 0x12 (entity_velocity) | Entity Velocity | Entity ID i32 → varint |
| 0x13 (entity_destroy) | Entity Destroy | Count prefix i8+entity i32 array → varint count + varint array |
| 0x14–0x19 (entity move/look/teleport) | Entity movement | Entity ID i32 → varint; onGround:bool added to rel_entity_move, entity_look, entity_move_look, entity_teleport |
| 0x1a (entity_status) | Entity Status | Entity ID unchanged (i32) |
| 0x1c (entity_metadata) | Entity Metadata | Entity ID i32 → varint |
| 0x1d (entity_effect) | Entity Effect | duration: i16 → varint; added hideParticles:bool |
| 0x1e (remove_entity_effect) | Remove Entity Effect | Entity ID i32 → varint |
| 0x1f (experience) | Set Experience | level and totalExperience: i16 → varint |
| 0x20 (update_attributes) | Update Attributes | Modifier count prefix: i16 → varint |
| 0x21 (map_chunk) | Map Chunk | Major: removed addBitMap:u16 and compressedChunkData (zlib-in-packet); replaced with raw chunkData:ByteArray(varint-prefixed); blocks now use palette block-state IDs |
| 0x22 (multi_block_change) | Multi Block Change | Major: record format changed from separate {metadata+blockId bitfield, y:u8, x+z bitfield} to {horizontalPos:u8, y:u8, blockId:varint}; count now varint, removed dataLength:i32 |
| 0x23 (block_change) | Block Change | location: position_ibi → packed position; removed metadata:u8 field — block-state ID in type:varint encodes both |
| 0x24 (block_action) | Block Action | location: position_isi → packed position |
| 0x25 (block_break_animation) | Block Break Animation | location: position_iii → packed position |
| 0x26 (map_chunk_bulk) | Map Chunk Bulk | Major: removed per-chunk addBitMap:u16; removed compressedChunkData bulk buffer; switched to skyLightSent:bool + varint-prefixed meta array + raw data buffer |
| 0x28 (world_event) | World Event | location: position_ibi → packed position |
| 0x2a (world_particles) | World Particles | Switched from particleName:string to particleId:i32; added longDistance:bool; added extra data[] varint array for item/block particles |
| 0x2c (spawn_entity_weather) | Spawn Weather Entity | Entity ID unchanged (varint) |
| 0x2d (open_window) | Open Window | inventoryType: u8 numeric → string identifier; removed useProvidedTitle:bool |
| 0x33 (update_sign) | Update Sign | location: position_isi → packed position |
| 0x34 (map) | Map Item Data | Major reformat: 1.7 had just {itemDamage:varint, data:buffer(i16)}; 1.8 expanded to {itemDamage:varint, scale:i8, icons:[...], columns:i8, rows:i8, x:i8, y:i8, data:ByteArray} |
| 0x35 (tile_entity_data) | Tile Entity Data | location: position_isi → packed position; nbtData: compressedNbt → uncompressed optionalNbt |
| 0x36 (open_sign_entity) | Open Sign Editor | location: position_iii → packed position |
| 0x38 (player_info) | Player Info | Major: 1.7 was a flat {playerName:string, online:bool, ping:i16}; 1.8 became an action-based structure with {action:varint, data:[{uuid:UUID, ...}]} supporting add/remove/update-gamemode/update-latency/update-displayname actions |
| 0x41 (difficulty) | Change Difficulty | NEW in 1.8 (absent from 1.7) |
| 0x42 (combat_event) | Player Combat | NEW in 1.8 |
| 0x43 (camera) | Set Camera | NEW in 1.8 |
| 0x44 (world_border) | World Border | NEW in 1.8 |
| 0x45 (title) | Title | NEW in 1.8 |
| 0x46 (set_compression) | Set Compression | NEW in 1.8 (play-state duplicate; also exists in login state as 0x03) |
| 0x47 (playerlist_header) | Tab List Header/Footer | NEW in 1.8 |
| 0x48 (resource_pack_send) | Resource Pack | NEW in 1.8 |
| 0x49 (update_entity_nbt) | Update Entity NBT | NEW in 1.8 |
Source: packet maps in minecraft-data/data/pc/1.8/protocol.json play.toClient vs data/pc/1.7/protocol.json play.toClient. 1.7 clientbound play topped at 0x40 (kick_disconnect); 1.8 extends to 0x49.
Play state — changed serverbound packets
| ID | Name | 1.7 → 1.8 change |
|---|---|---|
| 0x02 (use_entity) | Interact | target:i32 → varint; mouse:i8 → varint; added optional {x,y,z}:f32 fields when mouse=2 (interact-at) |
| 0x04 (position) | Player Position | Removed stance:f64 field (1.7 had x,stance,y,z; 1.8 has x,y,z) |
| 0x06 (position_look) | Player Pos+Look | Same: removed stance:f64 |
| 0x07 (block_dig) | Player Action | status:i8 → varint; location: position_ibi → packed position |
| 0x08 (block_place) | Use Item On | location: position_ibi → packed position |
| 0x0a (arm_animation) | Swing Arm | 1.7 had {entityId:i32, animation:i8}; 1.8 is empty (no fields) |
| 0x0b (entity_action) | Player Command | entityId:i32 → varint; actionId:i8 → varint; jumpBoost:i32 → varint |
| 0x0c (steer_vehicle) | Player Input | jump:bool+unmount:bool → single jump:u8 flags byte |
| 0x12 (update_sign) | Sign Update | location: position_isi → packed position |
| 0x14 (tab_complete) | Command Suggestion | Added optional block:option<position> field |
| 0x15 (settings) | Client Information | Removed difficulty:u8 and showCape:bool; added skinParts:u8 bitmask |
| 0x18 (spectate) | Teleport To Entity | NEW in 1.8 |
| 0x19 (resource_pack_receive) | Resource Pack Status | NEW in 1.8 |
Source: minecraft-data/data/pc/1.8/protocol.json play.toServer vs data/pc/1.7/protocol.json play.toServer. 1.7 serverbound play topped at 0x17 (custom_payload); 1.8 extends to 0x19.
Entity metadata format
Both 1.7 and 1.8 use the same sentinel-terminated metadata loop structure:
- Each entry is a header byte with
{type:3 bits, key:5 bits}. - 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 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.
Chunk and block encoding
1.7 chunk format (for comparison)
In 1.7, Map Chunk (0x21) contained:
bitMap:u16— which of the 16 vertical sections are presentaddBitMap:u16— additional-data sections for blocks requiring >8 bits of block ID (extended blocks)compressedChunkData:buffer(i32-count)— zlib-deflated payload containing raw nibble arrays: 8-bit block IDs + 4-bit metadata nibbles + 4-bit block light + optional 4-bit sky light + optional 4-bit add-data
The 1.7 format encoded block type as (blockID << 4) | metadata using two separate nibble planes.
1.8 chunk format
In 1.8, Map Chunk (0x21) contains:
bitMap:u16— which sections are presentchunkData:ByteArray(varint-prefixed) — raw uncompressed per-section data
The per-section data layout in 1.8 encodes blocks as block-state IDs — a single integer combining what was previously blockId and metadata. Each section now stores:
- 4096 block-state values as 16-bit entries (2 bytes per block, stored little-endian in a flat array of
4096 × 2bytes) - 2048 bytes block light nibble array
- 2048 bytes sky light nibble array (overworld only)
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.
Packet inventory by state — 1.8 (protocol 47)
Source: minecraft-data/data/pc/1.8/protocol.json packet mapper sections. ViaVersion ClientboundPackets1_8.java and ServerboundPackets1_8.java confirm the same IDs.
Handshake (C→S)
| ID | Name |
|---|---|
| 0x00 | Set Protocol (Handshake) |
| 0xFE | Legacy Server List Ping |
Status
| ID | Direction | Name |
|---|---|---|
| 0x00 | S→C | Server Info (JSON response) |
| 0x01 | S→C | Ping (i64 payload echo) |
| 0x00 | C→S | Request (empty) |
| 0x01 | C→S | Ping (i64 timestamp) |
Login
| ID | Direction | Name |
|---|---|---|
| 0x00 | S→C | Disconnect |
| 0x01 | S→C | Encryption Request |
| 0x02 | S→C | Login Success |
| 0x03 | S→C | Set Compression ← new in 1.8 |
| 0x00 | C→S | Login Start |
| 0x01 | C→S | Encryption Response |
Play — Clientbound (S→C)
| ID | Name |
|---|---|
| 0x00 | Keep Alive |
| 0x01 | Login (Join Game) |
| 0x02 | Chat Message |
| 0x03 | Time Update |
| 0x04 | Entity Equipment |
| 0x05 | Spawn Position |
| 0x06 | Update Health |
| 0x07 | Respawn |
| 0x08 | Player Position and Look |
| 0x09 | Held Item Change |
| 0x0A | Use Bed |
| 0x0B | Animation |
| 0x0C | Spawn Named Entity |
| 0x0D | Collect Item |
| 0x0E | Spawn Object |
| 0x0F | Spawn Mob |
| 0x10 | Spawn Painting |
| 0x11 | Spawn Experience Orb |
| 0x12 | Entity Velocity |
| 0x13 | Destroy Entities |
| 0x14 | Entity (no-op move) |
| 0x15 | Entity Relative Move |
| 0x16 | Entity Look |
| 0x17 | Entity Look and Relative Move |
| 0x18 | Entity Teleport |
| 0x19 | Entity Head Look |
| 0x1A | Entity Status |
| 0x1B | Attach Entity |
| 0x1C | Entity Metadata |
| 0x1D | Entity Effect |
| 0x1E | Remove Entity Effect |
| 0x1F | Set Experience |
| 0x20 | Entity Properties |
| 0x21 | Chunk Data |
| 0x22 | Multi Block Change |
| 0x23 | Block Change |
| 0x24 | Block Action |
| 0x25 | Block Break Animation |
| 0x26 | Map Chunk Bulk |
| 0x27 | Explosion |
| 0x28 | Effect |
| 0x29 | Sound Effect |
| 0x2A | Particle |
| 0x2B | Change Game State |
| 0x2C | Spawn Global Entity |
| 0x2D | Open Window |
| 0x2E | Close Window |
| 0x2F | Set Slot |
| 0x30 | Window Items |
| 0x31 | Window Property |
| 0x32 | Confirm Transaction |
| 0x33 | Update Sign |
| 0x34 | Maps |
| 0x35 | Update Block Entity |
| 0x36 | Open Sign Editor |
| 0x37 | Statistics |
| 0x38 | Player List Item |
| 0x39 | Player Abilities |
| 0x3A | Tab-Complete |
| 0x3B | Scoreboard Objective |
| 0x3C | Update Score |
| 0x3D | Display Scoreboard |
| 0x3E | Teams |
| 0x3F | Plugin Message |
| 0x40 | Disconnect |
| 0x41 | Server Difficulty ← new in 1.8 |
| 0x42 | Combat Event ← new in 1.8 |
| 0x43 | Camera ← new in 1.8 |
| 0x44 | World Border ← new in 1.8 |
| 0x45 | Title ← new in 1.8 |
| 0x46 | Set Compression (play-state) ← new in 1.8 |
| 0x47 | Player List Header and Footer ← new in 1.8 |
| 0x48 | Resource Pack Send ← new in 1.8 |
| 0x49 | Update Entity NBT ← new in 1.8 |
Play — Serverbound (C→S)
| ID | Name |
|---|---|
| 0x00 | Keep Alive |
| 0x01 | Chat Message |
| 0x02 | Use Entity |
| 0x03 | Player (ground status only) |
| 0x04 | Player Position |
| 0x05 | Player Look |
| 0x06 | Player Position and Look |
| 0x07 | Player Digging |
| 0x08 | Player Block Placement |
| 0x09 | Held Item Change |
| 0x0A | Animation (arm swing — empty payload in 1.8) |
| 0x0B | Entity Action |
| 0x0C | Steer Vehicle |
| 0x0D | Close Window |
| 0x0E | Click Window |
| 0x0F | Confirm Transaction |
| 0x10 | Creative Inventory Action |
| 0x11 | Enchant Item |
| 0x12 | Update Sign |
| 0x13 | Player Abilities |
| 0x14 | Tab-Complete |
| 0x15 | Client Settings |
| 0x16 | Client Status |
| 0x17 | Plugin Message |
| 0x18 | Spectate ← new in 1.8 |
| 0x19 | Resource Pack Status ← new in 1.8 |
Proxy and translation impact
ViaVersion floor. Protocol 47 is ViaVersion's oldest natively supported client. There is no v1_7to1_8 package in ViaVersion — 1.7 support requires ViaLegacy/ViaRewind. The v1_8to1_9 package (/tmp/mcproto-refs/ViaVersion/common/src/main/java/com/viaversion/viaversion/protocols/v1_8to1_9/) is the FROM-1.8 direction and serves as the canonical definition of the 1.8 packet set.
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).
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).
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.
New packets requiring proxy awareness. World Border (0x44), Title (0x45), Combat Event (0x42), and Set Compression (0x46 in play-state) are all 1.8-new and unknown to 1.7 clients. A proxy connecting a 1.7 client to a 1.8 server must either translate or drop these; ViaLegacy/ViaRewind handle this for the compatibility layer.
Sub-version notes (1.8.1 – 1.8.9)
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.)
Sources summary
| Claim | Source |
|---|---|
| Protocol 47; version 1.8.8 as representative | /tmp/mcproto-refs/minecraft-data/data/pc/1.8/version.json |
| Release date 2014-09-02 | https://minecraft.wiki/w/Java_Edition_1.8 (fetched 2026-06-19) |
Login 0x03 compress packet field def |
/tmp/mcproto-refs/minecraft-data/data/pc/1.8/protocol.json login.toClient |
| 1.7 login had no 0x03 | /tmp/mcproto-refs/minecraft-data/data/pc/1.7/protocol.json login.toClient (0x00–0x02 only) |
| Encryption buffer countType i16→varint | Both protocol.json files, packet_encryption_begin |
| Play packet IDs 0x00–0x49 (1.8) | /tmp/mcproto-refs/minecraft-data/data/pc/1.8/protocol.json play.toClient mapper |
| Play packet IDs 0x00–0x40 (1.7) | /tmp/mcproto-refs/minecraft-data/data/pc/1.7/protocol.json play.toClient mapper |
| 1.8 clientbound packet enum with IDs | /tmp/mcproto-refs/ViaVersion/…/v1_8to1_9/packet/ClientboundPackets1_8.java |
| 1.8 serverbound packet enum with IDs | /tmp/mcproto-refs/ViaVersion/…/v1_8to1_9/packet/ServerboundPackets1_8.java |
| Compression framing (Data Length VarInt) | https://minecraft.wiki/w/Minecraft_Wiki:Projects/wiki.vg_merge/Protocol (fetched 2026-06-19) |
| chunk_data addBitMap present in 1.7, absent in 1.8 | diff of packet_map_chunk in both protocol.json |
| multi_block_change record format change | diff of packet_multi_block_change in both protocol.json |
stance field in 1.7 position, absent in 1.8 |
packet_position in both protocol.json |
| metadata loop structure identical 1.7 and 1.8 | entityMetadata/entityMetadataItem in both protocol.json |