注意!!
この記事の内容はMinecraft Ver.1.20.1、Forge Ver.47.3.0上で確認した内容になっています。
バージョンが異なると仕様が変更されている場合があります。
MOD開発のお話なので、プレイオンリーの人には興味のない話です。 すいません。
今回はmod開発におけるデータ管理方法について自分がやりやすい方法を考えました。 先に言ってしまうと追加ブロックとかのデータをCSVで管理したいんです。
前提として、僕はJAVAもmod開発もほぼ経験がないので正しい保証も本当に効率がいいのかも全く不明です。 ご了承ください。
modにおけるデータ管理
modのデータ管理は今のところこんな↓認識です。
- 昔はJAVAコードでデータ管理をしていた
- 今はJSONで管理されている
- 両者をつなぐJSONジェネレータが実装されている
JAVAコードで管理はこんな↓の。
JSONはこんな↓のです。
JSONは構造を持ったデータなので、視覚的にかなり分かりやすくなっています。 ゲームに限らず最近はいろんなところで見るデータ形式です。
それらをつなぐジェネレータ、要は従来のコード管理のものをJSONに変換して出力する仕組みを用意することで、コードでもJSONでもどっちで書いてもいいよ、というのが現状だと理解しています。
おそらくJSONになったことでメンテナンス性は飛躍的に向上したと思うんですが、
僕にはこれが非常に非効率に思えてですね。
昔からmodのソース見てデータ集める時とかクソ面倒でした。 JSONになるとプログラムに放り込んで処理できるのでかなりマシになりましたが。
さらにですね、自分でmod作って分かったんですが、例えば自前でブロックを追加する場合、ID登録する場所とタグ登録する場所が違うんですよ。 さらに破壊時のドロップやテクスチャの設定場所も違う。
こういうの一括管理したくならないですか?
CSV管理の方が絶対に楽じゃない?
そう、CSV、要はExcelでデータ管理できるようにしたいんですよ。
こんな↓風に管理するよりも、
絶対こう↓がいいと思うんですよね。
JSONはけっこう管理しやすいですが、こういう同系統のデータ管理をする場合、隣合うデータの場所が離れるので、CSV管理が一番いいと思うのです。 データ漏れも起きにくいし、バランス調整もしやすい。
あと、同じブロックのデータをIDとかドロップとかばらけて登録しないといけないのもなんだかイヤで、僕みたいないい加減なタイプは絶対に「IDは追加したけどタグの登録を忘れた」とか起きます。
起こす自身があります!
CSV管理なら1箇所で全てを定義しておけるので、この手のミスは起きにくくなります。
今テストしてる段階だとブロックデータにはこの↓ような項目を持たせています。
- id
- en_us
- ja_jp
- mapColor
- strength
- durability
- requiresTool
- requiresGrade
- loot
- oreRates
- oresInGround
- oresSize
- discardChanceOnAirExposure
- oresCount
- minInclusive
- maxInclusive
- biomeType
- tags
これらは、ブロック登録、名前登録、ドロップ登録、テクスチャ登録、タグ登録、鉱石生成登録と複数箇所で使用されてて、何かブロックを追加する時に全箇所に忘れずに登録するとか僕には絶対無理です。 CSVだとまぁ忘れないでしょう。
反面、テーブル管理が難しいデータ構造だと不向きですが、最悪セルにJSONを記述してJAVA側でデコードしてやればなんにでも対応できるので、デメリットはあまりないんじゃないかなーと思ってます。 定型クラフトレシピ登録とかはちょっと頭を使わないといけなさそう。
CSVを読み込むクラス
というわけでCSVを読み込んでPHPの連想配列みたいにアクセスできるようなクラスを作りました。
GitHubで公開していますが、僕はJAVAが全然わからなくて、思った通りに動くまでChatGPTくんに文句を言い続けたコードなので質は問わないでください。 もっとスマートなやり方がありそう。
使い方は簡単で、ここ↓に変数と読み込みを追加するだけ。
public static final List<Map<String, String>> RAWS;
static {
RAWS = loadCsv("/data/raws.csv");
}
ブロックとアイテムを追加するとこんな↓感じ。
public static final List<Map<String, String>> RAWS;
public static final List<Map<String, String>> BLOCKS;
public static final List<Map<String, String>> ITEMS;
static {
RAWS = loadCsv("/data/raws.csv");
BLOCKS = loadCsv("/data/blocks.csv");
ITEMS = loadCsv("/data/items.csv");
}
この段階ではただの連想配列で、特定の型を持たないので汎用的に使えます。
肝心のCSVファイルは「src\main\resources\data」に置いています。 ファイルの参照先は「src\main\resources」からだそうなので、それ以下ならどこに置いてもよさそう。 JAVAの勝手が分からないので、上ではChatGPTくんの指示通りにdataフォルダに入れています。
あとはCSVの内容を使いたいところでこんな↓風にループを回してデータを取得するだけ。
for (Map data : CsvData.RAWS) {
String id = data.get("id");
float exp = Float.parseFloat(data.get("exp"));
int time = Integer.parseInt(data.get("time"));
}
追加でprocessTagsという関数がありますが、これはタグ登録のテキストを分割する関数です。
「forge:ores/amber」というタグの場合「forge:ores」「forge:ores/amber」と分割して登録します。 複数のタグ設定をする場合はセミコロンで区切ります。
最後に
JAVAコードやJSONじゃなくて、CSVでデータ管理することで、個人的には破壊的に開発効率が上がりました。
ただまぁやってる内容がまだまだしょぼいのでこう感じている可能性はあります。 今予定してるのでも定型のクラフトレシピ登録はめんどくさそう。
誰かの何かの役に立つと幸い。
PR お手軽にマルチサーバでプレイしませんか?
処理性能No.1!快適なゲーム環境なら「Xserver for Game」
月額1000円くらいでオンラインにサーバを置いてMinecraftをマルチプレイできます。 統合版、Java版、Forgeに対応。
いやー僕はオンラインサーバって試したことなくて。
プレイ期間は24時間PC起動してたんですけど、電気代考えると1000円ならオンラインに置いた方が快適なのでは…?
過去のサーバデータを見たら1.12未満では500MB未満、1.12~1.18で1.5~2.0GB、1.19で3.0~3.5GBくらいだったので最安プランで問題なさそう。 スペック的にもマイクラは大丈夫みたいです。
僕も興味を持ったのでどういうサーバにするか考えた上でレビューしたいと思います。 マイクラ以外にもARK、テラリア、7 Days to Dieとかもいけるみたい。