22 KiB
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
andblockdust
particle types in/particle
now follows the same pattern as other particle types, with the data for each being passed in thedata
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 valuesgenerate-blockstate-upgrade-schema.php
- generates JSON blockstate upgrade schemas like those found in BedrockBlockUpgradeSchemagenerate-item-upgrade-schema.php
- generates JSON item ID/meta upgrade schemas like those found in 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 inBlockTypeIds
.- 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()
andBlock->encodeType()
- State data - this is discarded when the block is broken (facing direction, lit/unlit, powered/unpowered, etc.) - handled by
Block->decodeState()
andBlock->encodeState()
- Dynamic type data - this is retained by items when the block is broken (colour, wet/dry, coral type, etc.) - handled by
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 uniformlyutils\InvalidBlockStateException
- this has been superseded bypocketmine\data\runtime\InvalidSerializedRuntimeDataException
utils\NormalHorizontalFacingInMetadataTrait
-utils\HorizontalFacingTrait
now implements facing type data serialization uniformlyutils\PillarRotationInMetadataTrait
-utils\PillarRotationTrait
now implements rotation type data serialization uniformlyutils\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 typesutils\WoodType
- enum of all possible wood types, used for wood material blocks like planks and logsutils\WoodTypeTrait
- The following API methods have been removed:
Block->getId()
- for type comparisons, useBlock->getTypeId()
insteadBlock->getMeta()
- for state comparisons, useBlock->getStateId()
insteadBlock->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:
- Use
GlobalBlockStateHandlers::getUpgrader()->upgradeIntIdMeta()
to convert it to modern data - Pass the data to
GlobalBlockStateHandlers::getDeserializer()
to get a blockstate ID - Pass the blockstate ID to
BlockFactory::fromStateId()
to get aBlock
instance
- Use
- To get a block at runtime, e.g. stone, use
BlockIdentifier->getBlockId()
BlockIdentifier->getAllBlockIds()
BlockIdentifier->getVariant()
BlockIdentifier->getItemId()
Door->isPowered()
Door->setPowered()
Skull->isNoDrops()
Skull->setNoDrops()
VanillaBlocks::*_GLAZED_TERRACOTTA()
- useVanillaBlocks::GLAZED_TERRACOTTA()->setColor(DyeColor::WHATEVER())
insteadutils\FallableTrait->getId()
is no longer requiredutils\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 acceptsint $blockTypeId
, and no longer acceptsint $blockId, int $variant, ?int $itemId
ItemFrame->getFacing()
may now returnFacing::UP
andFacing::DOWN
ItemFrame->setFacing()
now acceptsFacing::UP
andFacing::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 datapublic Block->getRequiredTypeDataBits()
- returns the number of bits required to encode the block's type datapublic BlockIdentifier->getBlockTypeId()
- returns the block's type ID according toBlockTypeIds
public GlazedTerracotta->getColor()
(fromColoredTrait
) - this was previously unsupported due to legacy limitationspublic GlazedTerracotta->setColor()
(fromColoredTrait
) - this was previously unsupported due to legacy limitationspublic Wall->getConnections()
- returns the wall's connections and their types (seeutils\WallConnectionType
)public Wall->setConnections()
- sets the wall's connections and their types (seeutils\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
usesutils\WoodTypeTrait
GlazedTerracotta
usesutils\ColoredTrait
Planks
usesutils\WoodTypeTrait
Wood
usesutils\WoodTypeTrait
WoodenButton
usesutils\WoodTypeTrait
WoodenDoor
usesutils\WoodTypeTrait
WoodenFence
usesutils\WoodTypeTrait
WoodenPressurePlate
usesutils\WoodTypeTrait
WoodenSlab
usesutils\WoodTypeTrait
WoodenStairs
usesutils\WoodTypeTrait
WoodenTrapdoor
usesutils\WoodTypeTrait
pocketmine\crafting
- The following classes have been added:
RecipeIngredient
interfaceExactRecipeIngredient
- matches an exact itemMetaWildcardRecipeIngredient
- matches an item with the given legacy Minecraft ID, but any metadata value
- The following API methods have signature changes:
FurnaceRecipe->__construct()
now acceptsRecipeIngredient
instead ofItem
FurnaceRecipe->getInput()
now returnsRecipeIngredient
instead ofItem
PotionContainerChangeRecipe->__construct()
now acceptsstring, RecipeIngredient, string
(using Minecraft string IDs instead of legacy integers).PotionContainerChangeRecipe->getIngredient()
now returnsRecipeIngredient
instead ofItem
.PotionContainerChangeRecipe->getInputItemId()
now returnsstring
(using Minecraft string IDs instead of legacy integers).PotionContainerChangeRecipe->getOutputItemId()
now returnsstring
(using Minecraft string IDs instead of legacy integers).PotionTypeRecipe->__construct()
now acceptsRecipeIngredient
instead ofItem
PotionTypeRecipe->getIngredient()
now returnsRecipeIngredient
instead ofItem
PotionTypeRecipe->getInput()
now returnsRecipeIngredient
instead ofItem
ShapedRecipe->__construct()
now acceptsRecipeIngredient
instead ofItem
ShapedRecipe->getIngredient()
now returns?RecipeIngredient
instead of?Item
ShapedRecipe->getIngredientList()
now returnsRecipeIngredient[]
instead ofItem[]
ShapedRecipe->getIngredientMap()
now returnsRecipeIngredient[][]
instead ofItem[][]
ShapelessRecipe->__construct()
now acceptsRecipeIngredient
instead ofItem
ShapelessRecipe->getIngredientList()
now returnsRecipeIngredient[]
instead ofItem[]
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 inItemTypeIds
.- 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 longerjson_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, bypassingItem
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 theItem
implementation and its serialization method.- It's relatively easy to write a replacement method to encode items to JSON as you desire.
- The original purpose of this was to allow items to be serialized to JSON for crafting data generated from
- 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, useItem->getTypeId()
insteadItem->getMeta()
- use the item's specific API methods to compare information such as colour, potion type etc.Item->hasAnyDamageValue()
- for meta wildcard recipe ingredients, usepocketmine\crafting\MetaWildcardRecipeIngredient
insteadItemFactory->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:
- Use
GlobalItemDataHandlers::getUpgrader()->upgradeItemTypeDataInt()
to convert the legacy ID and meta toItemStackData
- Pass the itemstack data to
GlobalItemDataHandlers::getDeserializer()
to get anItem
instance
- Use
- To get an item at runtime, e.g. iron ingot, use
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 parameterItemIdentifier->__construct()
no longer accepts a$variant
parameter, and now expects an item type ID for the ID parameterLegacyStringToItemParser->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
andVanillaBlocks
has been inverted.- Now, blocks are defined in
VanillaBlocks
, and automatically registered inBlockFactory
. - Manual registration in
BlockFactory
is still required for custom blocks. BlockFactory
now has only one purpose, which is to map internal blockstate IDs toBlock
objects when reading blocks from chunks.
- Now, blocks are defined in
- 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 membersCARTOGRAPHY
andSMITHING
pocketmine\data
LegacyToStringBidirectionalIdMap
has been reduced toLegacyToStringIdMap
.- 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 datapublic 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 datapublic BlockStateData->getState(string $name) : ?Tag
- The following internal API methods have signature changes:
BlockStateData->__construct()
now acceptsarray<string, Tag
> for$states
instead ofCompoundTag
BlockStateData->getStates()
now returnsarray<string, Tag>
instead ofCompoundTag
(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.
- Vanilla item registration is now done via
- 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 parametersint $toughness
andbool $fireProof
- The following classes have been added:
HoneyBottle
- The following enums have new members:
ToolTier
has new memberNETHERITE
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