|
| 1 | +# 5.26.0 |
| 2 | +Released 22nd March 2025. |
| 3 | + |
| 4 | +This is a minor feature release focused on performance improvements. |
| 5 | + |
| 6 | +**Plugin compatibility:** Plugins for previous 5.x versions will run unchanged on this release, unless they use internal APIs, reflection, or packages like the `pocketmine\network\mcpe` or `pocketmine\data` namespace. |
| 7 | +Do not update plugin minimum API versions unless you need new features added in this release. |
| 8 | + |
| 9 | +**WARNING: If your plugin uses the `pocketmine\network\mcpe` namespace, you're not shielded by API change constraints.** |
| 10 | +Consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if you're using packets directly. |
| 11 | + |
| 12 | +## Performance |
| 13 | +- Significantly improved performance of entity movement. Load testing with item entities showed a 3x increase in the number of entities supported without lag. |
| 14 | +- Significantly improved performance of on-ground checks for player movement. This still needs further work, but optimisations implemented in this version should improve performance substantially. |
| 15 | +- Updated `pocketmine/nbt` dependency with performance improvements to `TAG_Compound` and `TAG_List` comparison. This should improve performance of inventory-related actions. |
| 16 | +- `InventoryTransaction` now avoids useless item clones when processing transactions, which should improve performance of inventory-related actions. |
| 17 | + |
| 18 | +## Dependencies |
| 19 | +- `pocketmine/bedrock-protocol` has been updated to `36.2.0`, which adds new functions to access some packet fields. |
| 20 | +- `pocketmine/nbt` has been updated to `1.1.0`, which improves performance when comparing NBT object trees. |
| 21 | + |
| 22 | +## Gameplay |
| 23 | +- Block break progress now takes into account the following: jumping, being in water, haste, mining fatigue |
| 24 | + |
| 25 | +## Tools |
| 26 | +- `blockstate-upgrade-schema-utils.php` now has a new `dump-table` command, which turns a `.bin` palette table file into human-readable text for debugging. |
| 27 | + |
| 28 | +## API |
| 29 | +### `pocketmine\block` |
| 30 | +- The following methods have been added: |
| 31 | + - `public RuntimeBlockStateRegistry->hasStateId(int $stateId) : bool` - checks whether the given state ID is registered |
| 32 | + |
| 33 | +### `pocketmine\crafting` |
| 34 | +- The following methods have been deprecated: |
| 35 | + - `CraftingManager::sort()` - this was implicitly internal anyway |
| 36 | + |
| 37 | +### `pocketmine\utils` |
| 38 | +- The following constants have been added: |
| 39 | + - `TextFormat::MATERIAL_RESIN` |
| 40 | +- The following static properties have been added: |
| 41 | + - `Terminal::$COLOR_MATERIAL_RESIN` |
| 42 | + |
| 43 | +### `pocketmine\data\bedrock\block` |
| 44 | +- `BlockStateToObjectDeserializer` now permits overriding **deserializers** for Bedrock IDs. This may be useful to implement custom state handling, or to implement missing block variants (such as snow cauldron). |
| 45 | + - This was originally prohibited since 5.0.0. However, there is no technical reason to disallow overriding **deserializers**. |
| 46 | + - Overriding **serializers** is still **not permitted**. Reusing type IDs doesn't make any sense and would break internal design contracts. |
| 47 | + - If you want to make a custom version of a vanilla block, create a custom type ID for it, exactly as you would for a regular custom block. |
| 48 | +- The following methods have been added: |
| 49 | + - `public BlockStateToObjectDeserializer->getDeserializerForId(string $id) : ?(\Closure(BlockStateReader) : Block)` |
| 50 | + |
| 51 | +### `pocketmine\data\bedrock\item` |
| 52 | +- `ItemDeserializer` now permits overriding **deserializers** for Bedrock IDs. As above, this may be useful to implement custom data handling, or to implement missing variants of existing items. |
| 53 | + - This was originally prohibited since 5.0.0. However, there is no technical reason to disallow overriding **deserializers**. |
| 54 | + - Overriding **serializers** is still **not permitted**. Reusing type IDs doesn't make any sense and would break internal design contracts. |
| 55 | + - As above, if you want to make a custom version of a vanilla item, create a custom type ID for it, exactly as you would for a regular custom item. |
| 56 | +- The following methods have been added: |
| 57 | + - `public ItemDeserializer->getDeserializerForId(string $id) : ?(\Closure(SavedItemData) : Item)` |
| 58 | + |
| 59 | +## Internals |
| 60 | +- `new $class` is now banned on new internals code by a PHPStan rule. Closures or factory objects should be used instead for greater flexibility and better static analysis. |
| 61 | +- `CraftingManager` now uses a more stable hash function for recipe output filtering. |
| 62 | +- `ChunkCache` now accepts `int $dimensionId` in the constructor. This may be useful for plugins which implement the nether. |
| 63 | +- `RuntimeBlockStateRegistry` now precomputes basic collision info about known states for fast paths. |
| 64 | + - This permits specialization for common shapes like cubes and collisionless blocks, which allows skipping complex logic in entity movement calculation. This vastly improves performance. |
| 65 | + - Any block whose class overrides `readStateFromWorld()` or `getModelPositionOffset()` will *not* be optimised. |
| 66 | + - `Block->recalculateCollisionBoxes()` now has a hard requirement not to depend on anything other than available properties. It must not use `World` or its position. |
| 67 | + - This change was problematic for `ChorusPlant`, which used nearby blocks to calculate its collision boxes. |
| 68 | + - Blocks which need nearby blocks should override `readStateFromWorld()` and set dynamic state properties, similar to fences. |
| 69 | + - This design flaw will be corrected with a major change to `Block` internals currently in planning for a future major version. |
| 70 | +- `Block->getCollisionBoxes()` may not be called at all during gameplay for blocks with shapes determined to be simple, like cubes and collisionless blocks. |
| 71 | +- `BlockStateToObjectDeserializer` now checks if the returned blockstate is registered in `RuntimeBlockStateRegistry` to promote earlier error detection (instead of crashing in random code paths). |
0 commit comments