Minecraft のマップを生成するソフトウェアを書いた

はじめまして。kofuk です。このサークルに入ったのはたしか去年の11月くらいだったのでまだ新入部員です[要出典]。

もう数か月前になりますが,Minecraft のセーブデータをパーズして上空から見た画像を生成するソフトウェアを書いたので,その紹介をします。このサークルの活動とは直接は関係がないです。

こちらがそのソースコードのリポジトリです。
残念ながら,私一人で作っているので開発リソース的に GNU/Linux にしか対応していないです。以前は Windows にも対応していたのですが,Windows で使う人がいなかったので(そう,私の知りうる範囲では私しかユーザがいなかったのです)テストするのも面倒になってやめました。ただ *nix 的な API を使っているのは一部なので,Windows に移植するのはそんなに大変じゃないと思います(Windows に詳しい人がいたらプラットフォーム依存部分の移植をお願いしたい……)。

これは私が個人的に管理している Minecraft のワールドで,Web ページでマップを見られるようにするために使っています。あと指定した座標の一番上のブロックの ID を取る機能とかも実装していて,右クリックでブロック ID を確認できたりします。x, z 座標を与えられたらその座標の一番上のブロック ID を返すというのもこのソフトウェアの機能のひとつです。

以下は需要あまりない気がするけど技術的な話をつらつらと書いていきます。

最初は Python で書いていて(というのも Python だとよさげなライブラリがけっこうあったので)遅かったので,C++ で書き直したとかいう話があったりします。ただ C++ だと良くも悪くも書いた以上のことはあまりやってくれないので別の辛さはけっこうあったりします。余談ですが,先日もとの Python ライブラリの作者に GitHub でスターをいただきました。

まず Python だと遅かったという話をすると,Python だと GIL とかがあってマルチスレッドにしてもその分のパフォーマンスは発揮できないというのがあったりします。GIL というのは Global Interpreter Lock の略でデータ競合(並列処理で別の実行コンテキストが同じメモリ領域に書き込んでしまってバグるみたいな状態)を避けるために,同時に1つの Python のコードしか実行されないようになっているということです。Python には(Python じゃなくてもできるけど)スレッドじゃなくてプロセスでやるという方法もあったりしますが,それでも処理が遅くて不満だったりしたので,やっぱり C/C++ で書き直した方がいいだろう判断して移植しました。これには私が Python があまり気に入らないという背景もけっこう関係していたりします。インデントでブロックを表現するってのがコード足したりするときにけっこう厄介で。

ただ,GIL がないということは,競合条件でバグらないように自分で書いてあげないといけないので面倒くさいです。マルチスレッドって必要ないならなるべく書きたくない機能だと思います。(ちょっと危ないコードがあったりするんですが,適当なワークアラウンドで見ないふりをしたりしています,はい,だめです)。

最近の更新としては,前から気になっていた Unit テストを書き始めたことです。とりあえず導入して新しい機能のところから書いていけばいいだろうということで,実際にはあまり書いていないですが,書いたところでも既にバグが見つかりました。やっぱりテスト書くのは大切ですね。

直近の TODO としては,Minecraft の大型アップデートに対応するということだと思います。これがブロックの追加が多そうで面倒だなという感じで見ています。

ということで,今回はこれくらいですかね。最後までお読みいただき,ありがとうございました。