📘

PocketMine-MPのAPI5の変更点まとめ(ALPHA4時点)

2022/12/01に公開

この記事はPocketMine-MPの次期メジャーバージョン、5.0.0(pm5)の大きな変更点をまとめたものです。
https://github.com/pmmp/PocketMine-MP/blob/5.0.0-ALPHA4/changelogs/5.0-alpha.md の情報を編纂・翻訳したものになります。
大枠のみを翻訳しています。細かいところまでは翻訳しないので詳細は上ページを見てください。

TL;DR

  • 全体
    • protectedとpublicのプロパティがPHPネイティブの型を使用するようになる。
    • 以前は不可能だった多くの場所で引数と返り値のタイプヒントがされるようになる。
  • ブロック
    • レガシーID関連のAPIがなくなる
    • 新しいブロックIDが導入される(BlockTypeId)
    • ブロックステートがメタデータではなくPM特有の内部ステートデータで表現されるようになる
    • これらのデータは実行時用だからデータベースとかにコンフィグには入れてはならない
    • 上の過程でAPIが消えたり名前変わったりした
    • BlockStateSerializerが導入された
    • BlockStateDeserializerが導入された
  • アイテム
    • だいたいブロックと同じ
    • 耐久値のあるアイテムはNBTのDamageタグを使うようになった
    • json_encode()使えなくなった
    • ItemFactoryなくなった
    • ItemSerializerが導入された
    • ItemDeserializerが導入された
  • クラフト
    • レシピの材料の統一インターフェースRecipeIngredientが追加
    • レシピの材料がItemではなくRecipeIngredientインターフェースで表現されるようになる

pocketmine\block名前空間

実行時ブロック表現(runtime block representation)

内部コードがレガシーID(旧来のMinecraft内部IDを使っていたもの)への依存がなくなりました。
これに伴い、すべてのレガシーID,metaに係わるAPIが削除されます

VanillaBlocks由来で生成された新しいPocketMine-MP固有の実行時IDがブロックIDとして用いられます。このIDはBlockTypeIds内で定義されています。

このIDは実行時限定で使用されます。これらの値は予告なく変更される可能性があるのでコンフィグやデータベースに保存するべきではありません

ブロック状態(Block state)の属性(向き、色、等々)は、従来のメタデータではなくPM固有のステートデータにより表現されるようになります。

ステートデータは以下のもので構成されます

  • 動的な種類の情報 ブロックが壊されてもアイテムで保持される情報
    • 色、濡れてる/乾いてる、サンゴの種類、等々
    • Block->decodeType()Block->encodeType()で処理されます。
  • 状態情報 ブロックが破壊されたときに破棄される情報
    • 向き、火がついてるか/消えてるか、活性化してるか/いないか
    • Block->decodeState()Block->encodeState()で処理されます。

繰り返しになりますが、ブロックタイプIDおよびステート/タイプデータは実行時以外で使用されることを意図していません。これらの値は警告なしに変更される可能性があります。決してコンフィグやデータベースに保存しないでください

【PocketMine-MPの開発者向け】新しいブロックを実装する(implementing new blocks)

新しいブロックを登録する場合、以下の手順を踏む必要があります。

  • 新しいタイプIDをBlockTypeIdsに追加する
  • BlockFactoryを変更する[1]
  • VanillaBlocksを変更する
  • ディスクからブロックをデシリアライズするためにBlockStateToObjectDeserializerを変更する
  • ディスクにブロックをシリアライズするためにBlockObjectToStateSerializerを変更する
  • 必要に応じて、/giveで使用できるブロックのエイリアスを追加するためにStringToItemParserを変更する。

BlockFactory->get()の削除

BlockFactoryの役割は一つのみになりました。チャンクからブロックを読み出すときに内部ブロックステートIDをBlockオブジェクトに対応させるというものです。
それに従ってブロックをデータベースから読み出すような場合には以下のような方法が良いでしょう。

  1. minecraft:dirtのような文字IDを保存してあると仮定する。
  2. GlobalBlockStateHandlers::getDeserializer()に文字IDを渡して内部ブロックステートIDに変換する
  3. 内部ブロックステートIDをBlockFactory::fromStateId()に渡してBlockインスタンスを得る。

pocketmine\item名前空間

内部コードがレガシーID(旧来のMinecraft内部IDを使っていたもの)への依存がなくなりました。
これに伴い、すべてのレガシーID,metaに係わるAPIが削除されます

以下ブロックと同じところは省略します。

json_encode()可能でなくなる

本来、アイテムがjson_encode()可能であった理由はアイテムをCraftDataPacketで使用されるクラフトデータの形にシリアライズできるようにするためでした。
しかし生成の豊穣の変更により、アイテムをまるごとバイパスすることになったためjson_encodeをする必要なくなりました。

jsonSerialize()はどのようにしてアイテムがシリアライズされるかを知る必要がありますが、これによってアイテムの実装とシリアライズの方法に循環依存が生まれてしまいます。

アイテムを望むようにJSONへとエンコードする別の方法は比較的簡単にかけます。

pocketmine\crafting名前空間

RecipeIngredientインターフェースが追加されました。
WIP

data名前空間

WIP

Extra

このセクションからはチェンジログには書かれてはいないものの従来の方法から変わっていたり、新規にできるようになった方法について書いていきます。

【プラグイン開発者向け】pmmpで実装されていないブロック・アイテムを実装する

詳細はhttps://github.com/pmmp/RegisterBlocksDemoPM5 を見ること。
概要としては

  • Vanilla(Item|Block)sのようなCloningRegistryTraitを利用したクラスを作成しブロックを保持しておく手段を用意する
  • メインスレッドでの登録
  • それ以外の非同期スレッドでの登録
  • (Item|Block)TypeIds::new()を使用して既存のIdと被らないようにTypeIdを取得

これらの手順が重要です。

脚注
  1. ALPHA1までBlockFactoryに登録する必要がありましたが、ALPHA2でVanillaBlocksに登録されたアイテムが自動的にBlockFactoryに登録されるようになったためこの手順はなくなりました。
    カスタムブロックを登録する場合には引き続きこの手順が必要です。 ↩︎

Discussion