Files
claude-timemachine 02a249a379 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>
2026-06-19 19:13:19 +02:00

26 KiB
Raw Permalink Blame History

Minecraft Java Edition 1.7 — Protocol Deep-Dive

Range floor. This line defines the oldest protocol the modern toolchain targets. Every proxy, translator, and compatibility layer that claims "1.7+" speaks the protocol described here.


Header

Sub-release range Protocol version Release dates Cross-compatible
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-10 yes, with 1.7.23
1.7.5 4 2014-02-26 yes, with 1.7.24
1.7.6 5 2014-04-09 incompatible with 1.7.25
1.7.7 5 2014-04-09 yes, with 1.7.6
1.7.8 5 2014-04-11 yes, with 1.7.67
1.7.9 5 2014-04-14 yes, with 1.7.68
1.7.10 5 2014-06-26 yes, with 1.7.69

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.21.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 split is confirmed: 1.7.21.7.5 = protocol 4; 1.7.61.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.)


1. Headline changes — the Netty rewrite

1.7.2 ("The Update that Changed the World", released 2013-10-25) is not just a gameplay release — it is the architectural reset for the entire modern Minecraft protocol. Everything that followed is a delta on top of what 1.7.2 established.

1.1 Netty and length-prefixed VarInt framing

The network layer was completely rewritten to use Netty, replacing the old hand-rolled byte-stream code. The visible wire change:

[length: VarInt] [packet-id: VarInt] [fields...]

Before 1.7, each packet began with a fixed-width packet-ID byte; the receiver had to know the exact byte length of every packet to know where the next one started. After 1.7, every packet is prefixed by its own byte length as a VarInt, making the stream self-delimiting regardless of packet content. The minecraft.wiki 1.7.2 release article confirms "there is now a packet length header" (fetched 2026-06-19). The string type likewise moved to VarInt-length prefix (see protocol.json types.string entry, /tmp/mcproto-refs/minecraft-data/data/pc/1.7/protocol.json).

1.2 State machine: Handshake / Status / Login / Play

Before 1.7, the connection had two informal phases (pre-login and in-game). 1.7.2 formalised this as four explicit states, each with its own packet namespace and numeric IDs:

State Initiated by
Handshaking Always the first state; client sends one packet (0x00 Set Protocol) then transitions
Status (next_state = 1) Server List Ping path
Login (next_state = 2) Authentication + encryption setup path
Play After Login Success; all gameplay traffic

Packet IDs are per-state. 0x00 in Status means something completely different from 0x00 in Login. The pre-1.7 protocol had a flat namespace where a single byte identified every packet across all phases — this is the deepest structural break from the legacy protocol.

1.3 JSON chat

Chat messages on the wire became JSON-encoded Text component strings (source: minecraft.wiki 1.7.2 article — "/tellraw enables JSON formatted messages"; fetched 2026-06-19). The packet_chat payload (both S→C and C→S) is a VarInt-length-prefixed string carrying JSON. This is a breaking change from the old raw-string chat packet.

1.4 New Server List Ping (SLP)

The Server List Ping was redesigned. The new flow uses the Status state:

  1. Client sends Handshake (0x00) with next_state = 1.
  2. Client sends Status Request (0x00, no fields).
  3. Server responds with Status Response (0x00) carrying a JSON string: {"version":{"name":"...","protocol":N},"players":{...},"description":{...},"favicon":"data:image/png;base64,..."}
  4. Client sends Ping (0x01, i64 timestamp); server echoes it back.

The old "legacy SLP" (0xFE magic byte) is preserved as packet_legacy_server_list_ping in the Handshake state for pre-1.7 client compatibility (see protocol.json handshaking.toServer mappings). Server icons in the server list (favicon field as a base64 PNG) are new in 1.7.2 (minecraft.wiki 1.7.2; fetched 2026-06-19).

1.5 Packet renumbering

All packet IDs were renumbered. The pre-1.7 flat namespace had IDs like 0x01 (Login Request), 0x02 (Handshake), 0xFF (Kick Disconnect) scattered across 256 possible values. In 1.7, the Play state alone starts at 0x00 and counts up sequentially within the state; 65 unique packet types were defined (41 S→C + 24 C→S in the 1.7.10 data — see §3).


2. Protocol 4 → Protocol 5 delta (1.7.6)

The bump from protocol 4 (1.7.21.7.5) to protocol 5 (1.7.61.7.10) coincided with a skin system overhaul in 1.7.6 (released 2014-04-09; minecraft.wiki /w/Java_Edition_1.7.6, fetched 2026-06-19).

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) 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.21.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.
  • 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.21.7.5 servers (confirmed by minecraft.wiki 1.7.6; fetched 2026-06-19), making the protocol-5 boundary hard.

The subsequent 1.7.71.7.10 releases did not change the protocol number; they were bug-fix and stability releases (1.7.6 had a crash that was fixed the next day in 1.7.7).


3. Packet inventory (protocol 5 / 1.7.10)

Source: /tmp/mcproto-refs/minecraft-data/data/pc/1.7/protocol.json

3.1 Handshaking state

ID Direction Name Key fields
0x00 C→S Set Protocol protocolVersion (VarInt), serverHost (string), serverPort (u16), nextState (VarInt: 1=Status, 2=Login)
0xFE C→S Legacy Server List Ping payload (u8, always 0x01) — pre-1.7 compat

No S→C packets in this state.

3.2 Status state

ID Direction Name Key fields
0x00 C→S Ping Start (no fields)
0x01 C→S Ping time (i64)
0x00 S→C Server Info response (string — JSON payload)
0x01 S→C Ping time (i64 echo)

3.3 Login state

ID Direction Name Key fields
0x00 C→S Login Start username (string)
0x01 C→S Encryption Begin sharedSecret (i16-length buffer), verifyToken (i16-length buffer)
0x00 S→C Disconnect reason (string — JSON chat)
0x01 S→C Encryption Request serverId (string), publicKey (i16-length buffer), verifyToken (i16-length buffer)
0x02 S→C Login Success uuid (string), username (string)

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. 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.

3.4 Play state — Server→Client (0x000x40)

ID Name Key fields / notes
0x00 Keep Alive keepAliveId (i32)
0x01 Login (Join Game) entityId (i32), gameMode (u8), dimension (i8), difficulty (u8), maxPlayers (u8), levelType (string)
0x02 Chat Message message (string — JSON)
0x03 Update Time age (i64), time (i64)
0x04 Entity Equipment entityId (i32), slot (i16), item (Slot)
0x05 Spawn Position location (position_iii: 3×i32)
0x06 Update Health health (f32), food (i16), foodSaturation (f32)
0x07 Respawn dimension (i32), difficulty (u8), gamemode (u8), levelType (string)
0x08 Player Position And Look x/y/z (f64), yaw/pitch (f32), onGround (bool)
0x09 Held Item Change slot (i8)
0x0A Use Bed entityId (i32), location (position_ibi: i32/u8/i32)
0x0B Animation entityId (VarInt), animation (u8)
0x0C Spawn Named Entity entityId (VarInt), playerUUID (string), playerName (string), data (array of {name,value,signature} property triples), x/y/z (i32), yaw/pitch (i8), currentItem (i16), metadata
0x0D Collect Item collectedEntityId (i32), collectorEntityId (i32)
0x0E Spawn Object entityId (VarInt), type (i8), x/y/z (i32), pitch/yaw (i8), objectData (i32 + conditional i16×3 velocity)
0x0F Spawn Mob entityId (VarInt), type (u8), x/y/z (i32), yaw/pitch/headPitch (i8), velocity (vec3i16), metadata
0x10 Spawn Painting entityId (VarInt), title (string), location (position_iii), direction (i32)
0x11 Spawn Experience Orb entityId (VarInt), x/y/z (i32), count (i16)
0x12 Entity Velocity entityId (i32), velocity (vec3i16)
0x13 Destroy Entities entityIds (i8-count array of i32)
0x14 Entity entityId (i32) — no-op movement
0x15 Entity Relative Move entityId (i32), dX/dY/dZ (i8)
0x16 Entity Look entityId (i32), yaw/pitch (i8)
0x17 Entity Look And Relative Move entityId (i32), dX/dY/dZ (i8), yaw/pitch (i8)
0x18 Entity Teleport entityId (i32), x/y/z (i32), yaw/pitch (i8)
0x19 Entity Head Look entityId (i32), headYaw (i8)
0x1A Entity Status entityId (i32), entityStatus (i8)
0x1B Attach Entity entityId (i32), vehicleId (i32), leash (bool)
0x1C Entity Metadata entityId (i32), metadata (entityMetadata)
0x1D Entity Effect entityId (i32), effectId/amplifier (i8), duration (i16)
0x1E Remove Entity Effect entityId (i32), effectId (i8)
0x1F Set Experience experienceBar (f32), level/totalExperience (i16)
0x20 Entity Properties entityId (i32), properties (i32-count array of {key:string, value:f64, modifiers:[{uuid,amount:f64,operation:i8}]})
0x21 Chunk Data x/z (i32), groundUp (bool), bitMap/addBitMap (u16), compressedChunkData (i32-length buffer)
0x22 Multi Block Change chunkX/chunkZ (i32), recordCount (i16), dataLength (i32), records (array of {metadata:4bit, blockId:12bit, y:u8, z:4bit, x:4bit})
0x23 Block Change location (position_ibi), type (VarInt), metadata (u8)
0x24 Block Action location (position_isi: i32/i16/i32), byte1/byte2 (u8), blockId (VarInt)
0x25 Block Break Animation entityId (VarInt), location (position_iii), destroyStage (i8)
0x26 Map Chunk Bulk chunkColumnCount (i16), dataLength (i32), skyLightSent (bool), compressedChunkData, meta array of {x/z:i32, bitMap/addBitMap:u16}
0x27 Explosion x/y/z/radius (f32), affectedBlockOffsets (i32-count array of i8×3), playerMotionX/Y/Z (f32)
0x28 Effect (World Event) effectId (i32), location (position_ibi), data (i32), global (bool)
0x29 Named Sound Effect soundName (string), x/y/z (i32), volume (f32), pitch (u8)
0x2A World Particles particleName (string), x/y/z/offsetX/Y/Z/particleData (f32), particles (i32)
0x2B Game State Change reason (u8), gameMode (f32)
0x2C Spawn Global Entity (Weather) entityId (VarInt), type (i8), x/y/z (i32)
0x2D Open Window windowId (u8), inventoryType (u8), windowTitle (string), slotCount (u8), useProvidedTitle (bool), entityId (i32, only for type 11)
0x2E Close Window windowId (u8)
0x2F Set Slot windowId (i8), slot (i16), item (Slot)
0x30 Window Items windowId (u8), items (i16-count Slot array)
0x31 Window Property windowId (u8), property/value (i16)
0x32 Confirm Transaction windowId (u8), action (i16), accepted (bool)
0x33 Update Sign location (position_isi), text14 (string×4)
0x34 Maps itemDamage (VarInt), data (i16-length buffer)
0x35 Update Block Entity location (position_isi), action (u8), nbtData (compressedNbt)
0x36 Open Sign Editor location (position_iii)
0x37 Statistics entries (VarInt-count array of {name:string, value:VarInt})
0x38 Player List Item playerName (string), online (bool), ping (i16)
0x39 Player Abilities flags (i8), flyingSpeed/walkingSpeed (f32)
0x3A Tab-Complete matches (VarInt-count string array)
0x3B Scoreboard Objective name (string), displayText (string), action (i8)
0x3C Update Score itemName (string), action (i8), scoreName (string, absent if action=1), value (i32, absent if action=1)
0x3D Display Scoreboard position (i8), name (string)
0x3E Teams team (string), mode (i8), conditional fields for name/prefix/suffix/friendlyFire/players depending on mode
0x3F Plugin Message channel (string), data (i16-length buffer)
0x40 Disconnect reason (string — JSON chat)

Total S→C Play: 65 packet types (0x000x40).

3.5 Play state — Client→Server (0x000x17)

ID Name Key fields / notes
0x00 Keep Alive keepAliveId (i32)
0x01 Chat Message message (string)
0x02 Use Entity target (i32), mouse (i8: 0=interact, 1=attack, 2=interact_at), x/y/z (f32, only if mouse=2)
0x03 Player (ground status only) onGround (bool)
0x04 Player Position x/stance/y/z (f64), onGround (bool) — note stance field (eye height)
0x05 Player Look yaw/pitch (f32), onGround (bool)
0x06 Player Position And Look x/stance/y/z (f64), yaw/pitch (f32), onGround (bool)
0x07 Player Digging status (i8), location (position_ibi: i32/u8/i32), face (i8)
0x08 Player Block Placement location (position_ibi), direction (i8), heldItem (Slot), cursorX/Y/Z (i8)
0x09 Held Item Change slotId (i16)
0x0A Animation entityId (i32), animation (i8)
0x0B Entity Action entityId (i32), actionId (i8), jumpBoost (i32)
0x0C Steer Vehicle sideways/forward (f32), jump/unmount (bool)
0x0D Close Window windowId (u8)
0x0E Click Window windowId (i8), slot (i16), mouseButton (i8), action (i16), mode (i8), item (Slot)
0x0F Confirm Transaction windowId (i8), action (i16), accepted (bool)
0x10 Creative Inventory Action slot (i16), item (Slot)
0x11 Enchant Item windowId/enchantment (i8)
0x12 Update Sign location (position_isi), text14 (string×4)
0x13 Player Abilities flags (i8), flyingSpeed/walkingSpeed (f32)
0x14 Tab-Complete text (string)
0x15 Client Settings locale (string), viewDistance (i8), chatFlags (i8), chatColors (bool), difficulty (u8), showCape (bool)
0x16 Client Status payload (i8: 0=perform_respawn, 1=request_stats, 2=open_inventory)
0x17 Plugin Message channel (string), data (i16-length buffer)

Total C→S Play: 24 packet types (0x000x17).


4. Notable data-type details

Slot (item stack)

blockId: i16          // -1 = empty (null slot)
if blockId != -1:
  itemCount: i8
  itemDamage: i16
  nbtData: compressedNbt   // zlib-deflate compressed NBT, or 0x0000 if absent

Source: protocol.json types.slot.

Entity Metadata (1.7 wire format)

Each entry is a byte whose high 3 bits are the type and low 5 bits are the key (entityMetadataItem bitfield). Types: 0=i8, 1=i16, 2=i32, 3=f32, 4=string, 5=Slot, 6=int-triple (x/y/z i32s), 7=float-triple (pitch/yaw/roll). The loop terminates on byte value 0x7F (127). Source: protocol.json types.entityMetadataLoop / entityMetadataItem.

String

VarInt-prefixed UTF-8 (pstring with countType: varint). No null terminator. Source: protocol.json types.string.

Position variants (1.7-era)

No packed 64-bit Position type (that is a 1.8 addition). 1.7 uses explicit multi-field combinations:

  • position_iii — x:i32, y:i32, z:i32
  • position_isi — x:i32, y:i16, z:i32
  • position_ibi — x:i32, y:u8, z:i32

Source: protocol.json types.position_iii / position_isi / position_ibi.

Player Position — stance field

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. 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 for the data buffer, not VarInt. Source: protocol.json types for packet_custom_payload.data in both play.toClient and play.toServer.


5. Wire framing summary

Packet (1.7+):
  [length:  VarInt]   ← total byte count of the rest of this packet
  [id:      VarInt]   ← state-scoped packet ID (always 1 byte in 1.7 range: ≤ 0x7F)
  [fields:  ...]

String:
  [byteLength: VarInt]
  [utf8 bytes: ...]

No compression in 1.7. Login Compression (0x03) was added in 1.8.
No encryption wrapper at the framing level — AES/CFB8 is applied per-byte
over the already-framed stream after Login Success.

6. Why 1.7 is the "oldest viable baseline"

Modern proxies (Velocity, BungeeCord, mc-router) target 1.7.10 as their floor because:

  1. State machine is present — Handshake/Status/Login/Play states let a proxy correctly intercept the login sequence to inject forwarding data (BungeeCord IP-forwarding via serverAddress overload, Velocity login-plugin-message). The pre-1.7 protocol has no Login state; there is no clean injection point.

  2. VarInt framing is self-delimiting — a proxy can pipeline and inspect packets without a static byte-length lookup table. The pre-1.7 format required per-packet hardcoded lengths.

  3. JSON chat and SLP — modern server-list-ping tools and anti-bot layers depend on the JSON SLP format. The old 0xFE SLP returns a §-delimited string that is not JSON.

  4. UUIDs in Login Success — the Login Success packet carries a UUID string, enabling player identity to be keyed on UUID rather than name. BungeeCord forwarding injects UUID + skin properties into the Handshake serverAddress or (for Velocity) via a Login Plugin Request; both require the Login state.

  5. Plugin Message channel — the custom_payload packet (C→S 0x17, S→C 0x3F) provides a channel-namespaced side-band that Forge uses for FML handshake (FML|HS) and that proxies use for capability negotiation.

The pre-1.7 legacy protocol (Minecraft ≤1.6.4, protocol ≤78) required a completely different code path. Proxies that support it (e.g. BungeeCord legacy mode) maintain a separate parser. The consensus since ~2015 is that 1.7.10 is the floor: old enough to be "legacy" but new enough to share the modern framing and state machine.


7. Proxy / translation impact

ViaVersion floor

ViaVersion handles protocol translation for 1.8 and above only. Its lowest supported input protocol is 1.8 (protocol 47). There is no protocols/v4to5/ or protocols/v5to47/ package in ViaVersion; the 1.7 → 1.8 gap is explicitly out of scope for the ViaVersion project.

Bridging below 1.8: ViaLegacy and ViaRewind

To support 1.7.x clients on modern servers, the translation stack requires:

  • ViaLegacy — handles protocol ≤ 1.7.10 (protocol ≤ 5) → modern. It re-implements the full 1.7 state machine, framing parser, and all packet transforms including the stance-removal, position packing, and the 1.7 entity-metadata format.
  • ViaRewind — handles 1.7 and 1.8 clients against 1.9+ servers. Sits on top of ViaVersion.

Neither ViaLegacy nor ViaRewind is cloned in this repo's ref set; they are referenced by name only. See their respective GitHub repos for implementation detail.

What a 1.7-aware proxy must handle

Concern 1.7 detail Modern delta
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; 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) 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

BungeeCord / Velocity forwarding with 1.7 clients

BungeeCord legacy forwarding (IP injection into Handshake serverAddress) works unchanged with 1.7 clients because the packet_set_protocol (Handshake 0x00) 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. 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")).)


8. Sources summary

Source Used for
minecraft.wiki /w/Java_Edition_1.7.2 (fetched 2026-06-19) Release date, Netty rewrite, JSON chat, SLP, packet length header
minecraft.wiki /w/Java_Edition_1.7.6 (fetched 2026-06-19) Protocol 5 confirmation, release date 2014-04-09, skin overhaul, incompatibility note
minecraft.wiki /w/Java_Edition_1.7.10 (fetched 2026-06-19) Protocol 5 confirmation, release date 2014-06-26, 1.7.69 compatibility note, Log4j note
/tmp/mcproto-refs/minecraft-data/data/pc/1.7/version.json Canonical: {"version":5,"minecraftVersion":"1.7.10","majorVersion":"1.7"}
/tmp/mcproto-refs/minecraft-data/data/pc/1.7/protocol.json Full packet inventory by state: all IDs, field names, data types