Skip to content

Instantly share code, notes, and snippets.

@karakufire
Last active September 8, 2022 08:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save karakufire/b53b15d72cf7e91a0491caa8872eaf63 to your computer and use it in GitHub Desktop.
Save karakufire/b53b15d72cf7e91a0491caa8872eaf63 to your computer and use it in GitHub Desktop.

Forge1.18.xデータ自動生成まとめ

導入

MC1.14以降のForgeにはデータファイルの自動生成機能(Data Generation)が搭載されている。

例えば1.16.5などに対応した他人のModのプロジェクトで、src/generatedってディレクトリを見たことある人も少なくないだろう。このディレクトリは正しくその自動生成されたデータファイルが格納されるのである。

ここでは、Minecraft 1.18.x用のMinecraft Forge(確認はMinecraft Forge 1.18.2-40.1.51)での使用方法をまとめている。

概要

gradle runDataを実行すると、以下ようなクラスが存在する場合、これに則ってデータファイルが自動生成される。ここでは、クラス名はExampleDatagenとしている。

テクスチャや音声ファイルなどは自動生成されない。

それぞれの自動生成方法は別個説明する。

言語ファイル

  1. net.minecraftforge.common.data.LanguageProviderを継承するクラスを作成する
  2. LanguageProvider#addTranslationsを実装し、そこにどのアイテムやブロック、字幕や進捗がどの文字列でゲーム中に表記されるかを記述する。
  3. ExampleDatagen#gatherData(GatherDataEvent)にてイベントにプロバイダクラスを登録する
package com.example;
import net.minecraft.data.DataGenerator;
import net.minecraftforge.common.data.ExistingFileHelper;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.forge.event.lifecycle.GatherDataEvent;
/**
* `gradle runData`で実行されるデータジェネレータークラス
* これそのものは特に何かを継承する必要は無いが、
* Mod.EventSubscriberアノテーションを付ける必要がある
*
* Mod.EventSubscriberアノテーションは
* イベントバスを監視するクラスのアノテーションである
* アノテーション内引数busでどのイベントバスを監視するかを指定する
* データ自動生成においては、MODイベントバスを監視する
*/
@Mod.EventSubscriber(bus = Mod.EventSubscriber.Bus.MOD)
public class ExampleDatagen{
/**
* データ自動生成に使用する生成プロバイダクラスを登録するためのメソッド
* GatherDataEventのイベントハンドラであればよいので
* 特にメソッド名をgatherDataとする必要は無いが、大体この名前になってる
*/
@SubscriberEvent
public static void gatherData(GatherDataEvent event){
DataGenerator generator = event.getGenerator();
// テクスチャや音声ファイルなどのファイルが、
// それぞれプロバイダに記述した通りの箇所に存在するかを検証するクラス
ExistingFileHelper helper = event.getExistingFileHelper();
if (event.includeServer()){
// サーバーデータの作成プロバイダの登録ロジックを記述
// レシピ、ルートテーブル、タグ、進捗、Global Loot Modifiers
}
if (event.includeClient()){
// クライアントアセットの作成プロバイダの登録ロジックを記述
// モデル、言語ファイル、音声、ブロックステート
// 言語ファイル生成プロバイダ追加
generator.addProvider(new LangData(generator));
}
}
}
package com.example:
import net.minecraft.data.DataGenerator;
import net.minecraftforge.common.data.LanguageData;
/**
* 言語ファイルの生成プロバイダ
* LanguageProviderを継承し、LanguageProvider#addTranslationsを実装して
* そこに文字列を指定するロジックを記述する
*/
public static class LangData extends LanguageProvider{
/**
* インスタンス化にはgen、modid、localeが必要である
* LanguageProviderは抽象クラスのため、
* コンストラクタでスーパークラスのコンストラクタに渡す必要がある
*
* また、LanguageProvider.localeは直接取れないため、
* 独自にロケールを保持するメンバー変数を用意するか、
* LanguageProvider#getNameからよしなにしよう
*/
public LangData(DataGenerator gen, String modid, String locale){
super(gen, modid, locale);
}
/**
* この例のように、MOD IDとロケールを決め打ちでやってもいい
*/
public LangData(DataGenerator gen){
super(gen, "examplemod", "en_us");
}
/**
* 文字列の登録メソッド
*
*/
@Override
public void addTranslations(){
add("item.examplemod.hoge", "HOGEHOGE");
// ascii文字以外の文字はUnicodeエスケープされる
// この例では、実際のファイルでは"\u3075\u304C\u3075\u304C"となる
add("block.examplemod.fuga", "ふがふが");
}
}
@karakufire
Copy link
Author

1.18.x版Minecraft Forgeでの記述なので、1.16.5版とかの場合は公式のドキュメントとかで確認してくださいね
1.19.x版のMinecraft Forgeなら多分ある程度記述方法が共通しているかもしれませんね

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment