diff --git a/changelogs/5.0-alpha.md b/changelogs/5.0-alpha.md new file mode 100644 index 000000000..9eeb54e9a --- /dev/null +++ b/changelogs/5.0-alpha.md @@ -0,0 +1,302 @@ +**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. + +## 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.** Any world or player data loaded in 5.0.0 will not work in 4.x due to backwards-incompatible storage format changes, and may also not work in future snapshots of 5.0.0. + +In addition, there are several 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. + +## 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`