**For Minecraft: Bedrock Edition 1.19.0** # 5.0.0-ALPHA1 Released 6th July 2022. This is a development snapshot of 5.0.0, an upcoming major update to PocketMine-MP. This version includes many new improvements, including support for Bedrock worlds from 1.13 onwards, a large array of new blocks, and various changes to the plugin API. ## WARNING **This is an ALPHA release.** It is an early development snapshot of the upcoming 5.0.0 release. This means it is LIKELY to be unstable, and/or have performance issues not found in the latest stable releases. **BACK UP your data before testing this.** This version will work with worlds and player data from 4.x, **BUT** any world or player data loaded in 5.0.0 **will not work in 4.x** due to backwards-incompatible storage format changes. In addition, there are a number of breaking API changes. Plugins for 4.x may require code changes to run on this version. The API is **not finalized**. You should expect further changes in later alphas. ## Core - Worlds are now saved according to the Bedrock 1.19.0 format. - Worlds generated by Bedrock from 1.13.0 and up are now supported (previously, only worlds up to 1.12 were supported). - `/particle` now accepts strings for particle data instead of integers. - `/particle` no longer accepts integers for block or item IDs. - The usage of `blockcrack`, `iconcrack` and `blockdust` particle types in `/particle` now follows the same pattern as other particle types, with the data for each being passed in the `data` parameter instead of being baked into the particle name. ## Tools - The following tool scripts have been added: - `generate-block-palette-spec.php` - generates a JSON file with a readable overview of blocks, their state properties, and their possible values - `generate-blockstate-upgrade-schema.php` - generates JSON blockstate upgrade schemas like those found in [BedrockBlockUpgradeSchema](https://github.com/pmmp/BedrockBlockUpgradeSchema) - `generate-item-upgrade-schema.php` - generates JSON item ID/meta upgrade schemas like those found in [BedrockItemUpgradeSchema](https://github.com/pmmp/BedrockItemUpgradeSchema) ## Gameplay ### Blocks - Added the following new blocks: - Amethyst Block - Ancient Debris - Basalt - Blackstone blocks, slabs, stairs, and walls - Calcite - Chiseled Deepslate - Chiseled Nether Bricks - Chiseled Polished Blackstone - Cobbled Deepslate blocks, slabs, stairs, and walls - Copper Ore - Cracked Deepslate Bricks - Crached Deepslate Tiles - Cracked Nether Bricks - Cracked Polished Blackstone Bricks - Crimson buttons, doors, fences, fence gates, hyphae, planks, pressure plates, signs, slabs, stairs, stems, and trapdoors - Deepslate - Deepslate Bricks blocks, slabs, stairs, and walls - Deepslate Ores (coal, copper, diamond, emerald, gold, iron, lapis lazuli, redstone) - Deepslate Tiles blocks, slabs, stairs, and walls - Honeycomb Block - Light Block - Mangrove buttons, doors, fences, fence gates, logs, planks, pressure plates, signs, slabs, stairs, trapdoors, and wood - Mud Bricks blocks, slabs, stairs, and walls - Nether Gold Ore - Polished Basalt - Polished Blackstone blocks, buttons, pressure plates, slabs, stairs, and walls - Polished Blackstone Bricks blocks, slabs, stairs, and walls - Polished Deepslate blocks, slabs, stairs, and walls - Quartz Bricks - Shroomlight - Smooth Basalt - Soul Fire - Soul Lantern - Soul Soil - Soul Torch - Tuff - Warped buttons, doors, fences, fence gates, hyphae, planks, pressure plates, signs, slabs, stairs, stems, and trapdoors - Added support for basalt generators - Iron Ore and Gold Ore now drop Raw Iron and Raw Gold respectively, instead of the ore blocks. - Item frames can now be placed on the top and bottom of blocks. - All-sided logs ("wood", for want of a better name) can now be placed in X, Y, and Z orientations. - Walls now connect when placed, following the pre-1.16 logic. (1.16 logic is planned to be implemented, but currently low priority.) - Stripping logs by right-clicking them with an axe is now supported. ### Items - Added the following new items: - Amethyst Shard - Copper Ingot - Disc Fragment (5) - Echo Shard - Glow Ink Sac - Honeycomb - Phantom Membrane - Raw Copper - Raw Gold - Raw Iron - Spyglass ## API ### General - Protected and public properties now use native property types wherever possible. - Parameter and return typehints have been applied in many places where it wasn't previously possible. ### `pocketmine\block` #### Runtime block representation - Blocks no longer use internal Minecraft IDs and metadata to identify themselves. All APIs associated with legacy IDs and meta have been removed. - A new set of runtime IDs generated from `VanillaBlocks` is used to identify block types. These IDs are defined in `BlockTypeIds`. - These new IDs are used for runtime representation of blocks on chunks, and for type comparison purposes. - Block type IDs are used at **runtime only**. They should **NOT** be stored in configs or databases, as they are subject to change without warning. - Block state properties (e.g. facing, colour, etc.) are now represented by PM-specific state data instead of legacy metadata. The state data consists of: - Dynamic type data - this is retained by items when the block is broken (colour, wet/dry, coral type, etc.) - handled by `Block->decodeType()` and `Block->encodeType()` - State data - this is discarded when the block is broken (facing direction, lit/unlit, powered/unpowered, etc.) - handled by `Block->decodeState()` and `Block->encodeState()` **Block type IDs, and state/type data, are intended for use at RUNTIME only. The values of type IDs and state data may change without warning. They should NOT be saved in configs or databases.** #### Implementing new blocks To register a new block, the following changes are now required: - Add a new type ID to `BlockTypeIds` - Register the block in `BlockFactory` - Amend `VanillaBlocks` to include the new block - Amend `BlockStateToBlockObjectDeserializer` to deserialize the block from disk - Amend `BlockObjectToBlockStateSerializer` to serialize the block for disk - Optionally, amend `StringToItemParser` to add string alias(es) for the block, so that it can be given via `/give` This is admittedly rather more of a hassle than in the old days, but that's the price of abstraction. Research is underway for ways to improve this without spaghettifying the code again. #### Change list - The following classes have been removed: - `BlockIdentifierFlattened` - `BlockLegacyIds` - `BlockLegacyMetadata` - `utils\ColorInMetadataTrait` - `utils\ColoredTrait` now implements colour type data serialization uniformly - `utils\InvalidBlockStateException` - this has been superseded by `pocketmine\data\runtime\InvalidSerializedRuntimeDataException` - `utils\NormalHorizontalFacingInMetadataTrait` - `utils\HorizontalFacingTrait` now implements facing type data serialization uniformly - `utils\PillarRotationInMetadataTrait` - `utils\PillarRotationTrait` now implements rotation type data serialization uniformly - `utils\BlockDataSerializer` - The following classes have been added: - `BaseFire` - `SoulFire` - `BlockTypeIds` - This is a generated enum of PocketMine-MP-specific block type IDs - There is one for every entry in `VanillaBlocks` - Do NOT save these IDs in a config or database, as they may change without warning - Block type IDs are intended for comparison purposes only - Block type IDs cannot be negative - `CopperOre` - `GoldOre` - `IronOre` - `Light` - `NetherGoldOre` - `utils\WallConnectionType` - enum of all possible wall connection types - `utils\WoodType` - enum of all possible wood types, used for wood material blocks like planks and logs - `utils\WoodTypeTrait` - The following API methods have been removed: - `Block->getId()` - for type comparisons, use `Block->getTypeId()` instead - `Block->getMeta()` - for state comparisons, use `Block->getStateId()` instead - `Block->readStateFromData()` - `Block->writeStateToMeta()` - `Block->writeStateToItemMeta()` - `Block->getStateBitmask()` - `BlockFactory->get()` - To get a block at runtime, e.g. stone, use `VanillaBlocks::STONE()` - To load a block from old config or database data: 1. Use `GlobalBlockStateHandlers::getUpgrader()->upgradeIntIdMeta()` to convert it to modern data 2. Pass the data to `GlobalBlockStateHandlers::getDeserializer()` to get a blockstate ID 3. Pass the blockstate ID to `BlockFactory::fromStateId()` to get a `Block` instance - `BlockIdentifier->getBlockId()` - `BlockIdentifier->getAllBlockIds()` - `BlockIdentifier->getVariant()` - `BlockIdentifier->getItemId()` - `Door->isPowered()` - `Door->setPowered()` - `Skull->isNoDrops()` - `Skull->setNoDrops()` - `VanillaBlocks::*_GLAZED_TERRACOTTA()` - use `VanillaBlocks::GLAZED_TERRACOTTA()->setColor(DyeColor::WHATEVER())` instead - `utils\FallableTrait->getId()` is no longer required - `utils\FallableTrait->getMeta()` is no longer required - The following constants have been renamed: - `Block::INTERNAL_METADATA_BITS` -> `Block::INTERNAL_STATE_DATA_BITS` - `Block::INTERNAL_METADATA_MASK` -> `Block::INTERNAL_STATE_DATA_MASK` - The following API methods have been renamed: - `Block->getFullId()` -> `Block->getStateId()` - The following API methods have signature changes: - `BlockIdentifier->__construct()` now accepts `int $blockTypeId`, and no longer accepts `int $blockId, int $variant, ?int $itemId` - `ItemFrame->getFacing()` may now return `Facing::UP` and `Facing::DOWN` - `ItemFrame->setFacing()` now accepts `Facing::UP` and `Facing::DOWN` - The following API methods have been added: - `protected Block->decodeState()` - encodes the block's state properties, e.g. facing, powered/unpowered, etc. - `protected Block->decodeType()` - encodes the block's type properties, e.g. colour, wet/dry, coral type, etc. - `public Block->getRequiredStateDataBits()` - returns the number of bits required to encode the block's state data - `public Block->getRequiredTypeDataBits()` - returns the number of bits required to encode the block's type data - `public BlockIdentifier->getBlockTypeId()` - returns the block's type ID according to `BlockTypeIds` - `public GlazedTerracotta->getColor()` (from `ColoredTrait`) - this was previously unsupported due to legacy limitations - `public GlazedTerracotta->setColor()` (from `ColoredTrait`) - this was previously unsupported due to legacy limitations - `public Wall->getConnections()` - returns the wall's connections and their types (see `utils\WallConnectionType`) - `public Wall->setConnections()` - sets the wall's connections and their types (see `utils\WallConnectionType`) - `public Wall->getConnection()` - `public Wall->setConnection()` - `public Wall->isPost()` - `public Wall->setPost()` - `public Wood->isStripped()` - `public Wood->setStripped()` - The following classes now use new traits, adding API methods and/or properties: - `FenceGate` uses `utils\WoodTypeTrait` - `GlazedTerracotta` uses `utils\ColoredTrait` - `Planks` uses `utils\WoodTypeTrait` - `Wood` uses `utils\WoodTypeTrait` - `WoodenButton` uses `utils\WoodTypeTrait` - `WoodenDoor` uses `utils\WoodTypeTrait` - `WoodenFence` uses `utils\WoodTypeTrait` - `WoodenPressurePlate` uses `utils\WoodTypeTrait` - `WoodenSlab` uses `utils\WoodTypeTrait` - `WoodenStairs` uses `utils\WoodTypeTrait` - `WoodenTrapdoor` uses `utils\WoodTypeTrait` ### `pocketmine\crafting` - The following classes have been added: - `RecipeIngredient` interface - `ExactRecipeIngredient` - matches an exact item - `MetaWildcardRecipeIngredient` - matches an item with the given legacy Minecraft ID, but any metadata value - The following API methods have signature changes: - `FurnaceRecipe->__construct()` now accepts `RecipeIngredient` instead of `Item` - `FurnaceRecipe->getInput()` now returns `RecipeIngredient` instead of `Item` - `PotionContainerChangeRecipe->__construct()` now accepts `string, RecipeIngredient, string` (using Minecraft string IDs instead of legacy integers). - `PotionContainerChangeRecipe->getIngredient()` now returns `RecipeIngredient` instead of `Item`. - `PotionContainerChangeRecipe->getInputItemId()` now returns `string` (using Minecraft string IDs instead of legacy integers). - `PotionContainerChangeRecipe->getOutputItemId()` now returns `string` (using Minecraft string IDs instead of legacy integers). - `PotionTypeRecipe->__construct()` now accepts `RecipeIngredient` instead of `Item` - `PotionTypeRecipe->getIngredient()` now returns `RecipeIngredient` instead of `Item` - `PotionTypeRecipe->getInput()` now returns `RecipeIngredient` instead of `Item` - `ShapedRecipe->__construct()` now accepts `RecipeIngredient` instead of `Item` - `ShapedRecipe->getIngredient()` now returns `?RecipeIngredient` instead of `?Item` - `ShapedRecipe->getIngredientList()` now returns `RecipeIngredient[]` instead of `Item[]` - `ShapedRecipe->getIngredientMap()` now returns `RecipeIngredient[][]` instead of `Item[][]` - `ShapelessRecipe->__construct()` now accepts `RecipeIngredient` instead of `Item` - `ShapelessRecipe->getIngredientList()` now returns `RecipeIngredient[]` instead of `Item[]` ### `pocketmine\entity` - `Entity` now declares new abstract methods which must be implemented by subclasses: - `public Entity->getInitialDragMultiplier()` - `public Entity->getInitialGravity()` ### `pocketmine\item` #### Runtime item representation - Items no longer use internal Minecraft string IDs and metadata to identify themselves. All APIs associated with legacy IDs and/or meta have been removed. - A new set of runtime item IDs generated from `VanillaItems` is now used to identify item types. These IDs are defined in `ItemTypeIds`. - These new IDs are primarily intended for type comparison purposes. - Item type IDs are used at **runtime only**. They should **NOT** be stored in configs or databases, as they are not guaranteed to remain the same between versions. - In some cases, items may have additional "type data" which provides extra type information about an item. This replaces item metadata in some cases. - Type data may be used to store dynamic type information such as dye colour, potion type, etc. - Items must have the same type ID **and** type data in order to be stackable. - Blocks, when represented as items: - retain their block type data, but not state data (for example, different colours of concrete don't stack, but things like facing don't affect stackability) - use the negative of their block type ID (e.g. a block with type ID `1` will have an item type ID of `-1`). - Durable items (e.g. tools, armour) now use NBT `Damage` tag to store durability (like Minecraft 1.13+), instead of legacy meta values. **Item type IDs and type data are intended for RUNTIME use only. The values of type IDs and/or type data may change without warning. They should NOT be saved in configs or databases.** #### Implementing new items To register a new item, the following changes are now required: - Add a new ID to `ItemTypeIds` - Register the item in `ItemFactory` - Amend `VanillaItems` to add the item - Amend `ItemDeserializer` to add a deserializer for loading the item from disk - Amend `ItemSerializer` to add a serializer for saving the item to disk - Optionally, amend `StringToItemParser` to add string alias(es) for the item, so it can be given via `/give` Again, it's acknowledged this is rather more cumbersome than it should be, but this is an ongoing process. #### Change list - `Item` is no longer `json_encode()`-able. - The original purpose of this was to allow items to be serialized to JSON for crafting data generated from `CraftingDataPacket`. Due to changes in the generation methodology, bypassing `Item`s entirely, this is no longer necessary. - `jsonSerialize()` requires the item to know about the method by which it will be serialized, creating a cyclic dependency between the `Item` implementation and its serialization method. - It's relatively easy to write a replacement method to encode items to JSON as you desire. - The following classes have been removed: - `ItemIds` - `Skull` - `Bed` - The following classes have been added: - `CoralFan` - `Spyglass` - The following API methods have been added: - `public Dye->setColor()` - `public ItemIdentifer->getTypeId()` - `public static ItemIdentifier::fromBlock()` - `public Potion->setType()` - `public SplashPotion->setType()` - The following API methods have been removed: - `Item->getId()` - for type comparisons, use `Item->getTypeId()` instead - `Item->getMeta()` - use the item's specific API methods to compare information such as colour, potion type etc. - `Item->hasAnyDamageValue()` - for meta wildcard recipe ingredients, use `pocketmine\crafting\MetaWildcardRecipeIngredient` instead - `ItemFactory->get()` - To get an item at runtime, e.g. iron ingot, use `VanillaItems::IRON_INGOT()` - To get a block as an item, e.g. stone, use `VanillaBlocks::STONE()->asItem()` - To load an item from legacy ID and meta: 1. Use `GlobalItemDataHandlers::getUpgrader()->upgradeItemTypeDataInt()` to convert the legacy ID and meta to `ItemStackData` 2. Pass the itemstack data to `GlobalItemDataHandlers::getDeserializer()` to get an `Item` instance - `ItemFactory->remap()` - `ItemIdentifier->getId()` - `ItemIdentifier->getMeta()` - The following API methods have been renamed: - `Item::jsonDeserialize()` -> `Item::legacyJsonDeserialize()` - `ItemFactory->getAllRegistered()` -> `ItemFactory->getAllKnownTypes()` - The following API methods have signature changes: - `ItemFactory->isRegistered()` no longer accepts a `$variant` parameter, and now expects an item type ID for the ID parameter - `ItemIdentifier->__construct()` no longer accepts a `$variant` parameter, and now expects an item type ID for the ID parameter - `LegacyStringToItemParser->addMapping()` now accepts a string for ID, instead of an integer ### `pocketmine\world` - The following classes have been added: - `pocketmine\world\format\io\GlobalBlockStateHandlers` - `pocketmine\world\format\io\GlobalItemDataHandlers` # 5.0.0-ALPHA2 Released 14th July 2022. ## Core - Reduced memory usage of the server on startup. - Fixed error spam when loading item frames without items in them. ## Gameplay ### Blocks - Added the following new blocks: - Cakes with Candle & Dyed Candle - Candle & Dyed Candle - Cartography Table (not currently usable due to maps not being implemented) - Copper block (random oxidation not yet implemented) - Cut Copper block, stairs and slabs (random oxidation not yet implemented) - Crying Obsidian - Gilded Blackstone - Glow Item Frame - Hanging Roots - Lightning Rod - Netherite Block - Smithing Table - Tinted Glass - Warped Wart Block - Wither Rose ### Items - Added the following new items: - Honey Bottle - Netherite Axe - Netherite Boots - Netherite Chestplate - Netherite Helmet - Netherite Ingot - Netherite Leggings - Netherite Pickaxe - Netherite Scrap - Netherite Shovel - Netherite Sword ## API ### `pocketmine\block` - Dependency between `BlockFactory` and `VanillaBlocks` has been inverted. - Now, blocks are defined in `VanillaBlocks`, and automatically registered in `BlockFactory`. - Manual registration in `BlockFactory` is still required for custom blocks. - `BlockFactory` now has only one purpose, which is to map internal blockstate IDs to `Block` objects when reading blocks from chunks. - The following new API methods have been added: - `public Block->isFireProofAsItem()` - `public Block->onProjectileHit()` - `public ItemFrame->isGlowing()` - `public ItemFrame->setGlowing()` - The following new classes have been added: - `BaseCake` - `CakeWithCandle` - `CakeWithDyedCandle` - `Candle` - `CartographyTable` - `CopperSlab` - `CopperStairs` - `Copper` - `DyedCandle` - `GildedBlackstone` - `HangingRoots` - `LightningRod` - `SmithingTable` - `WitherRose` - `utils\CandleTrait` - `utils\CopperOxidation` - `utils\CopperTrait` ### `pocketmine\crafting` - JSON models have been updated to reflect updated crafting data format. - The following enum classes have new members: - `ShapelessRecipeType` has new members `CARTOGRAPHY` and `SMITHING` ### `pocketmine\data` - `LegacyToStringBidirectionalIdMap` has been reduced to `LegacyToStringIdMap`. - Since we never map from string ID to legacy ID, bidirectional mapping is no longer necessary. - This affects the following subclasses: - `LegacyBiomeIdToStringIdMap` - `LegacyBlockIdToStringIdMap` - `LegacyEntityIdToStringIdMap` - `LegacyItemIdToStringIdMap` - The following internal API methods have been added: - `public LegacyToStringIdMap->add(string $string, int $legacy) : void` - adds a mapping from a custom legacy ID to custom string ID, needed for upgrading old saved data - `public LegacyBlockStateMapper->addMapping(string $stringId, int $intId, int $meta, BlockStateData $stateData) : void` - adds a mapping from legacy block data to a modern blockstate, needed for upgrading old saved data - `public BlockStateData->getState(string $name) : ?Tag` - The following internal API methods have signature changes: - `BlockStateData->__construct()` now accepts `array for `$states` instead of `CompoundTag` - `BlockStateData->getStates()` now returns `array` instead of `CompoundTag` (allows reducing memory usage) - The following classes have been added: - `UnsupportedItemTypeException` ### `pocketmine\item` - `ItemFactory` has been removed. - Vanilla item registration is now done via `VanillaItems`. - The procedure for registering a custom item is the same as in ALPHA1, minus the `ItemFactory` step. - The following API methods have been added: - `public ArmorTypeInfo->getToughness() : int` - `public ArmorTypeInfo->isFireProof() : bool` - `public Item->isFireProof() : bool` - The following API methods have signature changes: - `ArmorTypeInfo->__construct()` now accepts optional parameters `int $toughness` and `bool $fireProof` - The following classes have been added: - `HoneyBottle` - The following enums have new members: - `ToolTier` has new member `NETHERITE` ### `pocketmine\world` - The following API methods have signature changes: - `SubChunk->__construct()` parameter `$blocks` has been renamed to `$blockLayers`. - The following classes have been added: - `CopperWaxApplySound` - `CopperWaxRemoveSound`