Minecraft Education(Win10Beta) と Java版のワールドを変換するツールを作った

2017年7月3日

こんにちは、ラルフです。

前回の投稿で触れなかった技術面的なものを紹介したいなと思います。

上の投稿のWSでは、Minecraft Educationを使用し、熊本城の建築もWin10Beta版で行いました。

しかし、途中にMinecraft Edu (Java版のMinecraftと中身は同じ)を使うかもしれないという話を受け、急遽ワールドを変換しなければいけないという自体が発生しました。

前提知識としては、Minecraft EducationとMinecraft Windows 10 Betaはmcworld形式(PEバージョンなどと互換性がある方式です)でワールドの書き出しができます。

Java版のワールドは、Anvil形式というワールドの保存形式が使われています。

もちろん互換性はまったくなく、変換するツールが有償で配布されていたりもしたのですが、確実に変換できる保証がないためコンバーターを作成しました。

https://github.com/r-ralph/Transcendens

こちらです。

現状はmcworld→pcの1方向しか変換ができません。

また、ブロックの変換しか出来ないという制限や、変換されたワールドが1.7上で読み込むと不安定というバグもあります。

内部のプロセスや形式周りについて話していきたいと思います。

mcworld形式のファイルは単純なzipファイルで、拡張子を変えてあげれば解凍することが出来ます。

内部にはlevel.datなどがあり、zipファイル内のdbフォルダがワールドデータが格納されているフォルダになります。

このdbフォルダ全体でLevelDBというファイル形式であり、Googleが開発したものらしいです。

しかし、本家のものからzlibでの圧縮ができるように改変されたものらしく、こちらのリポジトリでC++用のコードが見れます。

https://github.com/Mojang/leveldb-mcpe

Javaでの実装もしっかりと作っている方がいたので、そちらを使います。

https://github.com/tinfoiled/leveldb

LevelDBはKeyValue型のデータを格納することが出来、Keyの中に「どのチャンクのどのようなデータか」という情報が入っています。

手順としては、全てのKeyValueのペアに対してループを回し、ブロックの情報を格納しているペアだけを次の処理に回す形です。

Keyは9バイトのデータであり、先頭4バイトがチャンクのx座標、次の4バイトがチャンクのz座標、最後1バイトがどのデータかの数値となっています。

ブロックデータを保存しているペアのとき、Valueは83220バイトのデータであり、先頭32768バイトがブロックデータ(1ブロック1バイトで16*16*128個、データは符号なし整数でブロックIDと同じ数字になる)となります。

次の16384バイトがRegular dataというセクションで、いわゆるブロックのメタデータとなります。1バイトの中で先頭4bit、後方4bitで別々のブロックのメタデータを表します。

同じように次の16384バイトがSkylight dataというセクションで、イマイチ使用用途が読めませんでした(おそらく太陽光と何かしら関係しているはずですが・・・)

次の16384バイトがブロックのライトレベルに関するデータです。

更に256バイトと1024バイトのセクションもあるっぽいですが、今回の変換では使いませんでした。

PC側では、ワールドデータの生成にJ2Blocksを使用したので、細かな仕様は気にせずに行うことが出来ました。

https://github.com/MorbZ/J2Blocks

こういったライブラリが既にあるというのは非常に助かりました。

変換作業の中で一番混乱した点は、mcworld側のBlockIDとJava側のBlockIDが違うものがあるという点です。

例えば、WoodenSlab(木のハーフブロックは)mcworldだと158番ですが、Java版において158番はピストンになっているため、Java版におけるWoodenSlabのIDである126番に変換してあげなければいけません。

また、LevelDBのKeyとなっているChunkのx,zのバイト列はリトルエンディアンのため、注意が必要です。

このような注意点はありましたが、なんとか問題なく変換は行えるようになっています。

(書き出したJavaワールドは不安定なため、1.10のWorldEditで建物部分だけschematicファイルに変換し、新規生成した安定したワールドにペーストする形を取った)

(また、WSでは結局Educationを使用したので、ツールの出番はなかった)

双方向のワールド変換が安定的にできるようになれば、配布ワールドのデータをEducationで使用するなど、大規模なワールドを利用しやすくなるため、今後必要になるのではないかなと考えています。

逆方向も作っている最中なので、完成したらまた記事でも書こうかなと思います。

では