minecraft_protocol: foundation + per-version protocol docs 1.7.10->26.2

8 topical docs (overview, data types, lifecycle, handshake, status/ping,
login+encryption, configuration, version-differences) + proxy-forwarding set
+ 16 per-version release-line docs, sourced from minecraft.wiki, ViaVersion
(source + commits), minecraft-data, node-minecraft-protocol, Velocity, BungeeCord.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
claude-timemachine
2026-06-19 14:15:32 +02:00
commit d73c1c9537
35 changed files with 8894 additions and 0 deletions
+460
View File
@@ -0,0 +1,460 @@
# 1.14.x — Village & Pillage
**Protocols:** 477 (1.14), 480 (1.14.1), 485 (1.14.2), 490 (1.14.3), 498 (1.14.4)
**Release dates:** 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
**Minecraft wiki release articles:**
- <https://minecraft.wiki/w/Java_Edition_1.14> (fetched 2026-06-19) — release date 2019-04-23, protocol 477, data version 1952, resource/data pack format 4
- <https://minecraft.wiki/w/Java_Edition_1.14.1> (fetched 2026-06-19) — release date 2019-05-13, protocol 480, 62 bug fixes
- <https://minecraft.wiki/w/Java_Edition_1.14.2> (fetched 2026-06-19) — release date 2019-05-27, protocol 485, lighting and chunk loading fixes
- <https://minecraft.wiki/w/Java_Edition_1.14.3> (fetched 2026-06-19) — release date 2019-06-24, protocol 490, villager/trade fixes
- <https://minecraft.wiki/w/Java_Edition_1.14.4> (fetched 2026-06-19) — release date 2019-07-19, protocol 498, performance improvements + BLOCK_BREAK_ACK
**Protocol version numbers confirmed:** `ProtocolVersion.java``register(477, "1.14")`, `register(480, "1.14.1")`, `register(485, "1.14.2")`, `register(490, "1.14.3")`, `register(498, "1.14.4")``/tmp/mcproto-refs/ViaVersion/api/src/main/java/com/viaversion/viaversion/api/protocol/version/ProtocolVersion.java`; cross-checked against `/tmp/mcproto-refs/minecraft-data/data/pc/1.14/`, `1.14.1/`, `1.14.3/`, `1.14.4/`.
**ViaVersion packages:**
- `v1_13_2to1_14``/tmp/mcproto-refs/ViaVersion/common/src/main/java/com/viaversion/viaversion/protocols/v1_13_2to1_14/`
- `v1_14to1_14_1``…/protocols/v1_14to1_14_1/`
- `v1_14_1to1_14_2``…/protocols/v1_14_1to1_14_2/`
- `v1_14_2to1_14_3``…/protocols/v1_14_2to1_14_3/`
- `v1_14_3to1_14_4``…/protocols/v1_14_3to1_14_4/`
**minecraft-data sources:** `data/pc/1.13.2/`, `data/pc/1.14/`, `data/pc/1.14.1/`, `data/pc/1.14.3/`, `data/pc/1.14.4/``/tmp/mcproto-refs/minecraft-data/`
---
## Headline changes — Village & Pillage
1.14 (2019-04-23) carries the largest single-version protocol change-set since 1.13's Flattening. Gameplay is dominated by the villager/trading rework and new Village & Pillage mobs (pillager, ravager, wandering trader, fox, panda), but the protocol impact is equally substantial:
1. **Chunk lighting separated.** In 1.13 chunk light data traveled inside the `Chunk Data` packet. In 1.14 light is pulled into its own `Update Light` packet (0x24), sent *before* or *alongside* `Level Chunk` (0x21). The chunk packet itself now carries an NBT **heightmap** compound (keys `MOTION_BLOCKING` and `WORLD_SURFACE`, each a 9-bit-per-cell long-array) that was absent in 1.13. Source: `WorldPacketRewriter1_14.java` (full chunk handler and synthetic `LIGHT_UPDATE` injection) and `minecraft-data` `data/pc/1.14/protocol.json` field `heightmaps`.
2. **Block position bit-field reordered.** The 64-bit packed `Position` type reshuffled its bit layout. In 1.13.2 the 64 bits were `[x:26][y:12][z:26]` (Y in the middle). In 1.14 the layout is `[x:26][z:26][y:12]` (Y moved to the low bits). Source: `minecraft-data` top-level `types.position` in `1.13.2/protocol.json` vs `1.14/protocol.json`. ViaVersion remaps every position-carrying packet accordingly — `WorldPacketRewriter1_14.java` maps `Types.BLOCK_POSITION1_8``Types.BLOCK_POSITION1_14` on BLOCK_DESTRUCTION, BLOCK_ENTITY_DATA, BLOCK_EVENT, BLOCK_UPDATE, SET_DEFAULT_SPAWN_POSITION, and OPEN_SIGN_EDITOR.
3. **Villager trade list reworked.** The old 1.13 `bed` packet (which handled the player-sleeping animation) is gone; sleeping is now handled via entity data. Replacing it (and the old numeric-only trade list from 1.13's `MC|TrList` plugin channel) is the new `Merchant Offers` / `trade_list` packet (0x27). It carries per-trade fields: two input slots, one output slot, disabled flag, trade-use counters (`nbTradeUses`/`maximumNbTradeUses`), XP grant, special price, price multiplier, villager level, total experience, and `isRegularVillager` flag. Source: `minecraft-data` `data/pc/1.14/protocol.json` `packet_trade_list`; `ClientboundPackets1_14.java:63` (MERCHANT_OFFERS 0x27).
4. **New/removed packets.** Seven new clientbound Play packets, three new serverbound Play packets, one removed clientbound:
| Dir | 0x ID | Name | Status |
|-----|-------|------|--------|
| CB | 0x24 | `update_light` (LIGHT_UPDATE) | **NEW** |
| CB | 0x27 | `trade_list` (MERCHANT_OFFERS) | **NEW** |
| CB | 0x2D | `open_book` (OPEN_BOOK) | **NEW** |
| CB | 0x1F | `open_horse_window` (HORSE_SCREEN_OPEN) | **NEW** (split from OPEN_SCREEN) |
| CB | 0x40 | `update_view_position` (SET_CHUNK_CACHE_CENTER) | **NEW** |
| CB | 0x41 | `update_view_distance` (SET_CHUNK_CACHE_RADIUS) | **NEW** |
| CB | 0x50 | `entity_sound_effect` (SOUND_ENTITY) | **NEW** |
| CB | — | `bed` | **REMOVED** (→ entity data) |
| SB | 0x02 | `set_difficulty` (CHANGE_DIFFICULTY) | **NEW** |
| SB | 0x10 | `lock_difficulty` (LOCK_DIFFICULTY) | **NEW** |
| SB | 0x27 | `update_jigsaw_block` (SET_JIGSAW_BLOCK) | **NEW** |
Source: diff of `ClientboundPackets1_14.java` vs `ClientboundPackets1_13.java`; `ServerboundPackets1_14.java`; `minecraft-data` play packet maps for 1.13.2 and 1.14.
5. **Difficulty decoupled from Join Game / Respawn.** In 1.13.2 difficulty was a field inside `Login` (Join Game) and `Respawn` packets. In 1.14 it is stripped from both and sent as a separate `Change Difficulty` packet (0x0D, existing slot) which gains a new boolean `difficultyLocked` field. ViaVersion synthesizes this packet when downgrading: `WorldPacketRewriter1_14.java` in the LOGIN and RESPAWN handlers each read the old difficulty byte and create a synthetic `CHANGE_DIFFICULTY` packet with `difficultyLocked=false`. Source: `WorldPacketRewriter1_14.java`; `minecraft-data` `packet_difficulty` type (1.14 adds `difficultyLocked: bool`); `PlayerPacketRewriter1_14.java` comments ("Added in 19w11a").
6. **Login (Join Game) gains viewDistance.** The 1.14 `login` packet has a new `viewDistance: varint` field after `levelType`. Source: `minecraft-data` `data/pc/1.14/protocol.json` `packet_login`; `WorldPacketRewriter1_14.java` line `wrapper.write(Types.VAR_INT, WorldPacketRewriter1_14.SERVERSIDE_VIEW_DISTANCE)`.
7. **Map locked flag.** The `Map Item Data` packet gains a `locked: boolean` field (added in 19w02a, defaults false for old maps). Source: `WorldPacketRewriter1_14.java` MAP_ITEM_DATA handler.
8. **Massive packet ID renumbering.** With 7 new clientbound packets inserted throughout the ID space, virtually every Play clientbound packet above 0x13 has a different ID in 1.14 vs 1.13.2. Proxies and ViaVersion must remap all IDs. Notable shifts include `open_window` moving from 0x14 to 0x2E, `nbt_query_response` from 0x1D to 0x54 (jumping 55 slots), `sound_effect` from 0x4D to 0x51. Source: `minecraft-data` ID maps for 1.13.2 and 1.14 (full shift list available above in research data).
9. **Entity data: new Pose type, villager data restructure, new entities.** A new entity data type `Pose` (varint enum: Standing=0, FallFlying=1, Sleeping=2, Swimming=3, SpinAttack=4, Sneaking=5) replaces the old per-entity boolean flags for crouching/swimming/sleeping. Villager entity data (index 15) changes from a single profession integer to a compound `VillagerData` struct (villager type, profession, level). New entities added to the registry: Cat (split from Ocelot), Pillager, Ravager, Wandering Trader, Trader Llama, Fox. `PLAYER_SLEEP` clientbound packet is eliminated; sleeping is now communicated via entity metadata index 12 (`optionalBlockPosition`). Source: `EntityPacketRewriter1_14.java` (registerRewrites — filter for ENTITY, LIVING_ENTITY pose index, VILLAGER index 15 → VillagerData, OCELOT removals, ABSTRACT_RAIDER celebrating index); `EntityTypes1_14`.
10. **`nbt:compound_tag` argument type rename.** In command trees (`Declare Commands` / COMMANDS packet), the argument type `minecraft:nbt` was renamed to `minecraft:nbt_compound_tag`. Source: `Protocol1_13_2To1_14.java` CommandRewriter override of `handleArgumentType`.
11. **Fluid tags sent in Update Tags.** The `Update Tags` packet gains a fourth section for fluid tags (in addition to block/item/entity tags). Source: `Protocol1_13_2To1_14.java` tagRewriter handler; VV adds fluid tag registry type and appends entity tags.
---
## Play state — clientbound packet table (1.14, protocol 477)
Full list from `minecraft-data` `data/pc/1.14/protocol.json` `play.toClient` and `ClientboundPackets1_14.java`:
| ID | Name (minecraft-data) | ViaVersion name |
|----|----------------------|-----------------|
| 0x00 | spawn_entity | ADD_ENTITY |
| 0x01 | spawn_entity_experience_orb | ADD_EXPERIENCE_ORB |
| 0x02 | spawn_entity_weather | ADD_GLOBAL_ENTITY |
| 0x03 | spawn_entity_living | ADD_MOB |
| 0x04 | spawn_entity_painting | ADD_PAINTING |
| 0x05 | named_entity_spawn | ADD_PLAYER |
| 0x06 | animation | ANIMATE |
| 0x07 | statistics | AWARD_STATS |
| 0x08 | block_break_animation | BLOCK_DESTRUCTION |
| 0x09 | tile_entity_data | BLOCK_ENTITY_DATA |
| 0x0A | block_action | BLOCK_EVENT |
| 0x0B | block_change | BLOCK_UPDATE |
| 0x0C | boss_bar | BOSS_EVENT |
| 0x0D | difficulty | CHANGE_DIFFICULTY |
| 0x0E | chat | CHAT |
| 0x0F | multi_block_change | CHUNK_BLOCKS_UPDATE |
| 0x10 | tab_complete | COMMAND_SUGGESTIONS |
| 0x11 | declare_commands | COMMANDS |
| 0x12 | transaction | CONTAINER_ACK |
| 0x13 | close_window | CONTAINER_CLOSE |
| 0x14 | window_items | CONTAINER_SET_CONTENT |
| 0x15 | craft_progress_bar | CONTAINER_SET_DATA |
| 0x16 | set_slot | CONTAINER_SET_SLOT |
| 0x17 | set_cooldown | COOLDOWN |
| 0x18 | custom_payload | CUSTOM_PAYLOAD |
| 0x19 | named_sound_effect | CUSTOM_SOUND |
| 0x1A | kick_disconnect | DISCONNECT |
| 0x1B | entity_status | ENTITY_EVENT |
| 0x1C | explosion | EXPLODE |
| 0x1D | unload_chunk | FORGET_LEVEL_CHUNK |
| 0x1E | game_state_change | GAME_EVENT |
| 0x1F | open_horse_window (**NEW**) | HORSE_SCREEN_OPEN |
| 0x20 | keep_alive | KEEP_ALIVE |
| 0x21 | map_chunk | LEVEL_CHUNK |
| 0x22 | world_event | LEVEL_EVENT |
| 0x23 | world_particles | LEVEL_PARTICLES |
| 0x24 | update_light (**NEW**) | LIGHT_UPDATE |
| 0x25 | login | LOGIN |
| 0x26 | map | MAP_ITEM_DATA |
| 0x27 | trade_list (**NEW**) | MERCHANT_OFFERS |
| 0x28 | rel_entity_move | MOVE_ENTITY_POS |
| 0x29 | entity_move_look | MOVE_ENTITY_POS_ROT |
| 0x2A | entity_look | MOVE_ENTITY_ROT |
| 0x2B | entity | MOVE_ENTITY |
| 0x2C | vehicle_move | MOVE_VEHICLE |
| 0x2D | open_book (**NEW**) | OPEN_BOOK |
| 0x2E | open_window | OPEN_SCREEN |
| 0x2F | open_sign_entity | OPEN_SIGN_EDITOR |
| 0x30 | craft_recipe_response | PLACE_GHOST_RECIPE |
| 0x31 | abilities | PLAYER_ABILITIES |
| 0x32 | combat_event | PLAYER_COMBAT |
| 0x33 | player_info | PLAYER_INFO |
| 0x34 | face_player | PLAYER_LOOK_AT |
| 0x35 | position | PLAYER_POSITION |
| 0x36 | unlock_recipes | RECIPE |
| 0x37 | entity_destroy | REMOVE_ENTITIES |
| 0x38 | remove_entity_effect | REMOVE_MOB_EFFECT |
| 0x39 | resource_pack_send | RESOURCE_PACK |
| 0x3A | respawn | RESPAWN |
| 0x3B | entity_head_rotation | ROTATE_HEAD |
| 0x3C | select_advancement_tab | SELECT_ADVANCEMENTS_TAB |
| 0x3D | world_border | SET_BORDER |
| 0x3E | camera | SET_CAMERA |
| 0x3F | held_item_slot | SET_CARRIED_ITEM |
| 0x40 | update_view_position (**NEW**) | SET_CHUNK_CACHE_CENTER |
| 0x41 | update_view_distance (**NEW**) | SET_CHUNK_CACHE_RADIUS |
| 0x42 | scoreboard_display_objective | SET_DISPLAY_OBJECTIVE |
| 0x43 | entity_metadata | SET_ENTITY_DATA |
| 0x44 | attach_entity | SET_ENTITY_LINK |
| 0x45 | entity_velocity | SET_ENTITY_MOTION |
| 0x46 | entity_equipment | SET_EQUIPPED_ITEM |
| 0x47 | experience | SET_EXPERIENCE |
| 0x48 | update_health | SET_HEALTH |
| 0x49 | scoreboard_objective | SET_OBJECTIVE |
| 0x4A | set_passengers | SET_PASSENGERS |
| 0x4B | teams | SET_PLAYER_TEAM |
| 0x4C | scoreboard_score | SET_SCORE |
| 0x4D | spawn_position | SET_DEFAULT_SPAWN_POSITION |
| 0x4E | update_time | SET_TIME |
| 0x4F | title | SET_TITLES |
| 0x50 | entity_sound_effect (**NEW**) | SOUND_ENTITY |
| 0x51 | sound_effect | SOUND |
| 0x52 | stop_sound | STOP_SOUND |
| 0x53 | playerlist_header | TAB_LIST |
| 0x54 | nbt_query_response | TAG_QUERY |
| 0x55 | collect | TAKE_ITEM_ENTITY |
| 0x56 | entity_teleport | TELEPORT_ENTITY |
| 0x57 | advancements | UPDATE_ADVANCEMENTS |
| 0x58 | entity_update_attributes | UPDATE_ATTRIBUTES |
| 0x59 | entity_effect | UPDATE_MOB_EFFECT |
| 0x5A | declare_recipes | UPDATE_RECIPES |
| 0x5B | tags | UPDATE_TAGS |
Removed vs 1.13.2: `bed` (0x33 in 1.13.2) — replaced by entity data.
---
## Play state — serverbound packet table (1.14, protocol 477)
From `ServerboundPackets1_14.java` and `minecraft-data` `data/pc/1.14/protocol.json` `play.toServer`:
| ID | Name | Notes |
|----|------|-------|
| 0x00 | teleport_confirm | unchanged |
| 0x01 | query_block_nbt | unchanged (BLOCK_ENTITY_TAG_QUERY) |
| 0x02 | set_difficulty | **NEW** — CHANGE_DIFFICULTY |
| 0x03 | chat | unchanged |
| 0x04 | client_command | unchanged (CLIENT_COMMAND) |
| 0x05 | settings | unchanged (CLIENT_INFORMATION) |
| 0x06 | tab_complete | unchanged (COMMAND_SUGGESTION) |
| 0x07 | transaction | unchanged (CONTAINER_ACK) |
| 0x08 | enchant_item | unchanged (CONTAINER_BUTTON_CLICK) |
| 0x09 | window_click | unchanged (CONTAINER_CLICK) |
| 0x0A | close_window | unchanged (CONTAINER_CLOSE) |
| 0x0B | custom_payload | unchanged |
| 0x0C | edit_book | unchanged |
| 0x0D | query_entity_nbt | unchanged (ENTITY_TAG_QUERY) |
| 0x0E | use_entity | unchanged (INTERACT) |
| 0x0F | keep_alive | unchanged |
| 0x10 | lock_difficulty | **NEW** — LOCK_DIFFICULTY |
| 0x110x1C | movement packets | unchanged |
| 0x1D | crafting_book_data | unchanged (RECIPE_BOOK_UPDATE) |
| 0x1E | name_item | unchanged (RENAME_ITEM) |
| 0x1F | resource_pack_receive | unchanged (RESOURCE_PACK) |
| 0x20 | advancement_tab | unchanged (SEEN_ADVANCEMENTS) |
| 0x21 | select_trade | unchanged (SELECT_TRADE) |
| 0x22 | set_beacon_effect | unchanged (SET_BEACON) |
| 0x23 | held_item_slot | unchanged (SET_CARRIED_ITEM) |
| 0x24 | update_command_block | unchanged (SET_COMMAND_BLOCK) |
| 0x25 | update_command_block_minecart | unchanged (SET_COMMAND_MINECART) |
| 0x26 | set_creative_slot | unchanged (SET_CREATIVE_MODE_SLOT) |
| 0x27 | update_jigsaw_block | **NEW** — SET_JIGSAW_BLOCK |
| 0x28 | update_structure_block | unchanged (SET_STRUCTURE_BLOCK) |
| 0x29 | update_sign | unchanged (SIGN_UPDATE) |
| 0x2A | arm_animation | unchanged (SWING) |
| 0x2B | spectate | unchanged (TELEPORT_TO_ENTITY) |
| 0x2C | block_place | unchanged (USE_ITEM_ON) |
| 0x2D | use_item | unchanged |
ViaVersion cancels `CHANGE_DIFFICULTY` (0x02) and `LOCK_DIFFICULTY` (0x10) when downgrading to 1.13.2 (server doesn't understand them); also cancels `SET_JIGSAW_BLOCK` (0x27). Source: `Protocol1_13_2To1_14.java` lines 92-96.
---
## Packet format details — new packets
### Update Light (CB 0x24)
Introduced to decouple lighting from chunk data. Sent before or alongside Level Chunk for full chunk loads.
```
VarInt chunkX
VarInt chunkZ
VarInt skyLightMask // bitmask of sections with sky light (bits 0..17, sections -1..16)
VarInt blockLightMask // bitmask of sections with block light
VarInt emptySkyLightMask // sections where sky light should be set to all-zeros
VarInt emptyBlockLightMask
// Followed by skyLight arrays for each set bit in skyLightMask (2048 bytes each)
// Then blockLight arrays for each set bit in blockLightMask (2048 bytes each)
```
Source: `minecraft-data` `data/pc/1.14/protocol.json` `packet_update_light`; `WorldPacketRewriter1_14.java` LEVEL_CHUNK handler (synthetic `LIGHT_UPDATE` construction — 18-bit mask for 18 sections including sub-zero and above-255 virtual sections).
### Level Chunk (CB 0x21) — format change
In 1.13.2 the chunk packet carried light nibble arrays inside each ChunkSection. In 1.14 the light is removed from chunk sections and the packet gains an NBT `heightmaps` compound:
```
// 1.13.2 map_chunk:
Int32 x, z
Boolean groundUp
VarInt bitMap
Buffer chunkData // sections include sky/block light nibbles
NBT[] blockEntities
// 1.14 map_chunk:
Int32 x, z
Boolean groundUp
VarInt bitMap
NBT heightmaps // NEW: compound with MOTION_BLOCKING and WORLD_SURFACE long-arrays
Buffer chunkData // sections no longer carry light
NBT[] blockEntities
```
Source: `minecraft-data` `data/pc/1.13.2/protocol.json` vs `data/pc/1.14/protocol.json` `packet_map_chunk`; `WorldPacketRewriter1_14.java` (builds `heightmaps` CompoundTag with 9-bit compact long-arrays via `CompactArrayUtil.createCompactArray(9, 256, …)` and strips `section.setLight(null)`).
### Merchant Offers (CB 0x27) — new trade list
```
VarInt windowId
u8 count
[count] Trade:
Slot inputItem1
Slot outputItem
Boolean hasInputItem2
Slot? inputItem2 // present if hasInputItem2
Boolean tradeDisabled
Int32 nbTradeUses
Int32 maximumNbTradeUses
Int32 xp // XP granted to villager per trade
Int32 specialPrice // price adjustment (negative = discount)
Float32 priceMultiplier // multiplier for demand/reputation adjustment
VarInt villagerLevel
VarInt experience
Boolean isRegularVillager
```
Source: `minecraft-data` `data/pc/1.14/protocol.json` `packet_trade_list`.
### Update View Position (CB 0x40) and Update View Distance (CB 0x41) — new view management
```
// Update View Position (SET_CHUNK_CACHE_CENTER):
VarInt chunkX
VarInt chunkZ
// Update View Distance (SET_CHUNK_CACHE_RADIUS):
VarInt viewDistance
```
Both are new in 1.14 (added in 19w13a snapshots). ViaVersion synthesizes Update View Position from chunk coordinates when downgrading, and sends a fixed `SERVERSIDE_VIEW_DISTANCE = 64` for Update View Distance. Source: `WorldPacketRewriter1_14.java` `sendViewDistancePacket()` and chunk handler.
### Open Book (CB 0x2D) — new
```
VarInt hand // 0 = main hand, 1 = off hand
```
Source: `minecraft-data` `data/pc/1.14/protocol.json` `packet_open_book`.
### Open Horse Window (CB 0x1F) — split from Open Screen
Previously horse inventory was opened via the generic `Open Screen` packet with type `"EntityHorse"`. In 1.14 it has its own packet:
```
u8 windowId
VarInt nbSlots
Int32 entityId
```
ViaVersion converts the old `OPEN_SCREEN` with type `EntityHorse` into the new `HORSE_SCREEN_OPEN` packet. Source: `ItemPacketRewriter1_14.java` OPEN_SCREEN handler.
---
## Per-patch sub-sections
### Protocol 477 — 1.14 (2019-04-23)
Base release. All changes described above vs 1.13.2. Key ViaVersion package: `v1_13_2to1_14`.
Git log (top commits affecting `protocols/v1_13_2to1_14/`):
```
2e91b841b Automatically call mapTypes in entity rewriter
0121534e7 Deduplicate particle type fillers
8f8f5e72c Default rewriter registrations across protocols
a0b0ed4b6 Make <1.21.2 container id types consistent with Vanilla
c13b40a37 Add ParticleRewriter base
e436bbe37 Refactor dimension switch handling across all protocols
463381b84 Rename missing metadata references to entity data
```
Source: `git -C /tmp/mcproto-refs/ViaVersion log --oneline -- common/src/main/java/com/viaversion/viaversion/protocols/v1_13_2to1_14/` — most recent commits are refactors; the original 1.14 implementation predates the VV shallow-clone window.
Notable implementation notes from ViaVersion source:
- **Particle rewriter**: The 1.14 particle type encoding changes slightly; ViaVersion uses `ParticleType.Fillers.fill1_13_2(this, Types1_14.PARTICLE, true)` to remap particle IDs. Source: `Protocol1_13_2To1_14.java:106-107`.
- **Explosion negative-coordinate fix**: When downgrading 1.14→1.13.2, negative explosion coordinates are truncated to integer (a Mojang bug workaround). Source: `WorldPacketRewriter1_14.java` EXPLODE handler.
- **Health NaN fix**: The 1.14 health entity data can send `NaN` for living entities; ViaVersion optionally clamps to 1.0F. Source: `EntityPacketRewriter1_14.java` LIVING_ENTITY index 8 handler.
- **Arrow velocity separate packet**: In 1.14, velocity in `ADD_ENTITY` (Spawn Object) is ignored for items and arrows; ViaVersion emits a synthetic `SET_ENTITY_MOTION` packet. Source: `EntityPacketRewriter1_14.java` ADD_ENTITY handler.
---
### Protocol 480 — 1.14.1 (2019-05-13)
**What changed:** Villager entity data gained a new index. No packet added or removed — the packet set is identical to 477 (`Protocol1_14To1_14_1` maps `ClientboundPackets1_14 → ClientboundPackets1_14` with no new packet enum). Primary protocol-level change: entity data index 15 added to **both Villager and Wandering Trader** entity types.
From ViaVersion `v1_14to1_14_1`:
- `EntityPacketRewriter1_14_1.registerRewrites()`: `filter().type(EntityTypes1_14.VILLAGER).addIndex(15)` and `filter().type(EntityTypes1_14.WANDERING_TRADER).addIndex(15)` — an extra entity data slot inserted at index 15 for both entity types. Source: `/tmp/mcproto-refs/ViaVersion/common/src/main/java/com/viaversion/viaversion/protocols/v1_14to1_14_1/rewriter/EntityPacketRewriter1_14_1.java:79-80`.
- The `ADD_MOB` and `ADD_PLAYER` packets are registered to handle entity tracking but no field changes exist.
The `trade_list` (`MERCHANT_OFFERS`) packet is identical between 1.14 and 1.14.1 (confirmed: `minecraft-data` structures match exactly). Source: `data/pc/1.14/protocol.json` vs `data/pc/1.14.1/protocol.json` `packet_trade_list` — identical.
**Gameplay context:** 62 bug fixes, villager pathfinding/AI improvements, performance work. No new blocks or entities.
Git log for `v1_14to1_14_1/`: commits are all ViaVersion internal refactors (`bd4df2813`, `e965e9713`, `501f65e21`, `5286efde1`, `75d86851c`) — renaming, reformatting, no protocol logic changes.
---
### Protocol 485 — 1.14.2 (2019-05-27)
**What changed:** Version bump only at the protocol level; no packet structure changes vs 1.14.1. The `Protocol1_14_1To1_14_2` class is an empty `AbstractProtocol` subclass with no registered packet handlers. Source: `/tmp/mcproto-refs/ViaVersion/common/src/main/java/com/viaversion/viaversion/protocols/v1_14_1to1_14_2/Protocol1_14_1To1_14_2.java` — the entire class body has no `registerPackets()` override.
**Confirmed:** `minecraft-data` has no `data/pc/1.14.2/` directory (skipped — implies identical packet structure to 1.14.1).
**Gameplay context:** Lighting re-calculation when opening old worlds for the first time; debug screen shows server-side chunk counts; raiders restricted to fully-loaded chunks; 50+ bug fixes. No packet-level protocol change beyond the version number.
Git log for `v1_14_1to1_14_2/`: only cosmetic/rename commits (`cff9a8715`, `9f6e7fa4e`, `e965e9713`).
---
### Protocol 490 — 1.14.3 (2019-06-24)
**What changed:** One `MERCHANT_OFFERS` (`trade_list`) packet field added: `canRestock: boolean` appended to the packet's trailing fields (after `isRegularVillager`). ViaVersion inserts a synthetic `canRestock=isRegularVillager` when translating down from 1.14.3 to 1.14.2.
From `Protocol1_14_2To1_14_3.registerPackets()`:
```java
registerClientbound(ClientboundPackets1_14.MERCHANT_OFFERS, wrapper -> {
// … passthrough all trade fields …
boolean regularVillager = wrapper.passthrough(Types.BOOLEAN);
wrapper.write(Types.BOOLEAN, regularVillager); // new boolean added in pre-1
});
```
Source: `/tmp/mcproto-refs/ViaVersion/common/src/main/java/com/viaversion/viaversion/protocols/v1_14_2to1_14_3/Protocol1_14_2To1_14_3.java:33-53`.
Confirmed by `minecraft-data`: `data/pc/1.14.3/protocol.json` `packet_trade_list` has `canRestock: bool` as the last field; `data/pc/1.14/protocol.json` and `data/pc/1.14.1/protocol.json` do not.
**Gameplay context:** New gamerule `disableRaids`; protection enchantments mutually exclusive again; lantern placement on iron bars; item repair-by-crafting restored; villager panic behavior adjusted; 82 bug fixes.
Git log for `v1_14_2to1_14_3/`: internal refactors only — no protocol logic commits unique to this package.
---
### Protocol 498 — 1.14.4 (2019-07-19)
**What changed:** One new clientbound Play packet added: `acknowledge_player_digging` (`BLOCK_BREAK_ACK`) at ID **0x5C**.
```
// Acknowledge Player Digging (CB 0x5C):
Position location // block position (new 1.14 format: [x:26][z:26][y:12])
VarInt block // block state ID at that location
VarInt status // dig status: 0=started, 1=cancelled, 2=finished
Boolean successful // whether the dig was acknowledged as successful
```
Source: `minecraft-data` `data/pc/1.14.4/protocol.json` `packet_acknowledge_player_digging`; `ClientboundPackets1_14_4.java:116``BLOCK_BREAK_ACK; // 0x5C` is the only addition vs `ClientboundPackets1_14.java`.
ViaVersion `Protocol1_14_3To1_14_4` translates the `MERCHANT_OFFERS` packet to inject a `demand: i32` field (set to 0) into each trade entry:
```java
registerClientbound(ClientboundPackets1_14.MERCHANT_OFFERS, wrapper -> {
// … passthrough all existing fields …
wrapper.write(Types.INT, 0); // demand value added in pre5
});
```
Source: `/tmp/mcproto-refs/ViaVersion/common/src/main/java/com/viaversion/viaversion/protocols/v1_14_3to1_14_4/Protocol1_14_3To1_14_4.java:34-51`.
Confirmed by `minecraft-data`: `data/pc/1.14.4/protocol.json` `packet_trade_list` each trade entry has `demand: i32` after `priceMultiplier`; `data/pc/1.14.3/protocol.json` does not.
**Total 1.14.4 MERCHANT_OFFERS trade entry fields** (per-trade): `inputItem1`, `outputItem`, `inputItem2?`, `tradeDisabled`, `nbTradeUses`, `maximumNbTradeUses`, `xp`, `specialPrice`, `priceMultiplier`, **`demand`** → then packet-level: `villagerLevel`, `experience`, `isRegularVillager`, `canRestock`.
**Gameplay context:** Performance improvements (chunk loading at high speeds, leaf rendering); camera first-person pivot fix; `/reload` and `/forceload` accessible at permission level 2; villager behavior improvements; 54 bug fixes.
Git log for `v1_14_3to1_14_4/`: internal refactors only (`cff9a8715`, `9f6e7fa4e`, `75d86851c`, `5286efde1`, `501f65e21`, `e965e9713`); the functional `MERCHANT_OFFERS` and `BLOCK_BREAK_ACK` logic predates the shallow-clone window.
---
## Proxy and translation impact
**Version-negotiation:** Five distinct protocol numbers in a single minor release line (477/480/485/490/498) is unusual. A proxy supporting 1.14.x must negotiate all five and route each to the appropriate ViaVersion translation chain.
**Light packet ordering:** When a 1.14+ client connects to a 1.13.2 server via ViaVersion, the proxy must synthesize the `Update Light` packet from light data embedded in the chunk packet, and send it to the client before or alongside the `Level Chunk` packet. The ViaVersion `WorldPacketRewriter1_14` does this by intercepting the 1.13 `LEVEL_CHUNK` packet, stripping light from each section (`section.setLight(null)` after building the synthetic light packet), and sending the light packet immediately before the chunk. Source: `WorldPacketRewriter1_14.java` LEVEL_CHUNK handler.
**Block position format:** Any proxy bridging 1.13.2 ↔ 1.14+ must reorder every `Position` field in every packet that carries one. The bit layout changed from `[x:26][y:12][z:26]` (1.13.2) to `[x:26][z:26][y:12]` (1.14+). Failure to remap results in silently wrong Y coordinates (shifted 14 bits left, producing wildly out-of-range block Y values). ViaVersion applies `BLOCK_POSITION1_8 → BLOCK_POSITION1_14` on every positional packet. Source: `WorldPacketRewriter1_14.java`, `PlayerPacketRewriter1_14.java`.
**Chunk center tracking:** 1.14 clients require `Update View Position` (SET_CHUNK_CACHE_CENTER) to know which chunk column they are centered on; without it the client shows a rendering artifact with nearby chunks not loading. ViaVersion emits a synthetic SET_CHUNK_CACHE_CENTER whenever a chunk arrives that is more than `SERVERSIDE_VIEW_DISTANCE` (64) columns from the last known center. Source: `WorldPacketRewriter1_14.java` chunk handler `entityTracker.isForceSendCenterChunk()` check.
**MERCHANT_OFFERS evolution across patches:** The trade list packet changed three times across the 1.14.x line. A proxy bridging between 1.14.x sub-versions must account for each field addition in sequence:
| Protocol | MERCHANT_OFFERS field added |
|----------|-----------------------------|
| 477 | Base: inputItem1/outputItem/inputItem2/tradeDisabled/nbTradeUses/maximumNbTradeUses/xp/specialPrice/priceMultiplier/villagerLevel/experience/isRegularVillager |
| 480 | No change to packet (entity data index 15 change for villager/wandering-trader) |
| 485 | No change |
| 490 | `canRestock: bool` appended after isRegularVillager |
| 498 | `demand: i32` appended inside each trade entry after priceMultiplier |
**Entity data: villager profession mapping.** When downgrading villager entity data from 1.14 to 1.13.2, ViaVersion must map the new `VillagerData` struct (type, profession, level) back to the old single-integer profession. The mapping is: farmer→5, librarian→9, cleric→4 (priest), armorer→1 (blacksmith), butcher→2, nitwit→11, none→0. This is lossy (the new villager type and level fields have no 1.13.2 equivalent). Source: `EntityPacketRewriter1_14.java` `getNewProfessionId()`.
**Ocelot/Cat split.** 1.14 splits the Ocelot into Ocelot and Cat as separate entity types with different IDs. When downgrading from 1.14 a proxy must either map Cat back to Ocelot (ViaVersion default, with config option `translateOcelotToCat`) or spawn a pig as fallback. Source: `EntityPacketRewriter1_14.java` `onMappingDataLoaded()` and the 1.13→1.14 entity type registry.
**BLOCK_BREAK_ACK (1.14.4 only):** The new 0x5C packet in protocol 498 has no counterpart in 497 and below. A proxy must suppress or synthesize it appropriately. ViaVersion's `Protocol1_14_3To1_14_4` registers a new `ClientboundPackets1_14_4` enum that adds `BLOCK_BREAK_ACK` as the only addition beyond the 1.14.3 packet set. Source: `ClientboundPackets1_14_4.java:116`.
---
## Summary of VERIFY flags
<!-- VERIFY --> Release dates for 1.14.11.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.
<!-- VERIFY --> 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`.
<!-- VERIFY --> 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 (<!-- VERIFY --> likely the `Villager XP` or second VillagerData sub-field) is not fully confirmed from available sources.