# 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:** - (fetched 2026-06-19) — release date 2019-04-23, protocol 477, data version 1952, resource/data pack format 4 - (fetched 2026-06-19) — release date 2019-05-13, protocol 480, 62 bug fixes - (fetched 2026-06-19) — release date 2019-05-27, protocol 485, lighting and chunk loading fixes - (fetched 2026-06-19) — release date 2019-06-24, protocol 490, villager/trade fixes - (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 | | 0x11–0x1C | 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`. --- ## Resolved verification notes **Release dates 1.14.1–1.14.4:** Confirmed from minecraft.wiki article headers (fetched 2026-06-19): 1.14 = 2019-04-23, 1.14.1 = 2019-05-13, 1.14.2 = 2019-05-27, 1.14.3 = 2019-06-24, 1.14.4 = 2019-07-19. All five dates are consistent between wiki article headers and the ViaVersion `ProtocolVersion.java` registration order. **`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