Skip to content

Updating to the Next Protocol Version

This guide outlines the general process for updating the Allay core to a new Minecraft Bedrock Edition protocol version. In practice, special cases may occur, so do not rely solely on this guide.

1. Update Endstone

Before updating Allay, you need to extract the latest data from BDS using Endstone DevTools. First, update Endstone to the latest version. Then, use it to export the following files:

  • block_palette.nbt
  • block_states.json
  • block_tags.json
  • block_types.json
  • creative_groups.json
  • creative_items.nbt
  • item_components.nbt
  • item_tags.json
  • items.json
  • recipes.json

2. Update Resource Files (data/resources)

Files obtained directly

File Source
biome_definitions.json CloudburstMC/Data
colormap/* Mojang/bedrock-samples
Others (block_types.json, creative_items.nbt, etc.) Exported from Endstone

Manually maintained files

File Notes
block_tags_custom.json Update manually if IDs have changed
item_tags_custom.json Same as above
trim_data.json Rarely changes; can be updated using CloudburstMC/ProxyPass if needed

3. Update Files in data/resources/unpacked

These are used in code generation and are not included in the final .jar:

File Source / Notes
block_tags.json From Endstone
block_states_raw.json Rename block_states.json from Endstone
items_raw.json Rename items.json from Endstone
block_palette.nbt From Endstone
item_tags.json From Endstone
block_property_types.json Generated by running BlockPropertyTypeDataFileGen
biome_id_and_type.json Update manually (biomes rarely change)
entity_id_map.json pmmp/BedrockData
music_definitions.json Mojang/bedrock-samples
sound_definitions.json Mojang/bedrock-samples

4. Generate Derived Files

block_states.json

Generate using BlockStateDataProcessor, based on block_states_raw.json.

items.json

Generate using ItemDataProcessor, based on items_raw.json.

Language Files

  1. Copy original .lang files from endstone/bedrock_server/resource_packs/vanilla/texts to unpacked/lang_raw/vanilla.
  2. Run LangBuilder in data.
  3. Then run TrKeyGen in codegen.

5. Code Generation (codegen)

Generator When to Run
SoundNameGen If music_definitions.json or sound_definitions.json changed
CreativeItemGroupNameGen If creative_groups.json changed
BiomeIdEnumGen If biome_id_and_type.json changed
EntityIdEnumGen -> EntityClassGen If entity_id_map.json changed
TagGen If item_tags.json, block_tags.json, or biome_definitions.json changed
BlockIdEnumGen -> BlockPropertyTypeGen Always after block updates
BlockClassGen Requires manual edits:
– Delete old blocks
– Update properties and logic
– Check BlockTypeInitializer.java for errors
– Add merged blocks in registerMergedBlocks() if needed
ItemIdEnumGen -> ItemClassGen Similar to blocks:
– Remove old items
– Migrate logic if only names changed
– Add merged items in registerMergedItems() if needed

6. Update Protocol Dependencies

Update to the latest versions of:

Keep ProtocolInfo.FEATURE_VERSION and the block/item state updater constants aligned with the data files. Supported client versions are owned by ProtocolRegistry, not ProtocolInfo.

7. Add the Protocol Implementation

For a new international protocol version:

  1. Add ProtocolV<version> extending the previous international protocol class.
  2. Add PacketEncoderV<version> extending the previous international encoder class.
  3. Override only processor factories, encoded data, packet encoders, or features that changed at that version boundary.
  4. Register the protocol in ProtocolRegistry.createDefault().

For a NetEase variant, extend the international protocol and encoder with the same protocol number directly. Do not inherit another NetEase version, and do not place NetEase behavior in the later international inheritance chain.

Protocol classes must not inspect a player's negotiated version. Version-specific behavior belongs in the applicable protocol/data/encoder override. Connection state belongs in processors created by the protocol's processor factory table.

8. Review Protocol Data and Encoders

  • Keep protocol-independent frozen registry sources in NetworkData.
  • Keep expensive client payloads and stable ID mappings in ProtocolData.
  • Build recipe payloads and recipesByNetworkId together in the protocol's RecipeTable.
  • Construct a new packet for every encoder call. Never cache a BedrockPacket.
  • Send normal gameplay output through the negotiated protocol's PacketEncoder and ProtocolSession.
  • Add an encoder override only where the wire-level behavior actually changes.

9. Test and Finalize

  1. Add registry and inheritance tests for the new implementation.
  2. Verify representative encoder output with the target codec.
  3. Add boundary regression tests for every overridden processor, data set, encoder, or feature.
  4. Run ./gradlew build.
  5. Test login and gameplay with each newly supported client variant.

Remember to record all changes in CHANGELOG.md.

Comments