2025年2月5日水曜日

forge Mod を最新版にマイグレーションする方法

forge Mod を最新版にマイグレーションする方法

概要

マインクラフトのバージョンを 1.20.6 から 1.21.4 に上げ forge Mod のバージョンを 50.1.0 から 54.0.18 にマイグレーションしてみたのでその方法を紹介します

環境

  • macOS 15.2
  • Java 21.0.5
  • forrge MDK 1.20.6-50.1.32
  • minecraft 1.20.6

最新版の MDK のダウンロード

執筆時点での最新版は https://files.minecraftforge.net/net/minecraftforge/forge/index_1.21.4.html ここにあるのでダウンロードします
デフォルトだと安定版をダウンロードすることになっているので最新版をダウンロードしたい場合にはバージョンを指定しましょう

バックアップ

MDK の作業ディレクトリをバックアップしておきましょう
git なりで管理していればすぐに戻せるのでおすすめです
git など SCM で管理していない場合はディレクトリごとコピーしましょう

src ディレクトリの移動

基本的には自分で実装したファイルを最新の MDK に展開するだけです

  • cp -ipr src /tmp
  • cp README.txt /tmp

など自分で編集したファイルをどこかに移動しましょう
gradle.properties や build.gradle なども編集している場合は移動しておきましょう

一旦すべて空にする

MDK の作業ディレクトリを一旦すべて空にしましょう

  • rm -rf *

新しい MDK を展開する

ダウンロードした zip ファイルを展開します

  • mv ~/Downloads/forge-1.21.4-54.0.18-mdk.zip .

展開できたら移動していたファイルを戻します

  • cp -ipr /tmp/src .
  • cp /tmp/README.txt .

差分を確認する

git diff などで差分を確認します

  • 元のやつに戻したい場合は git checkout や手動で追記します
  • BOM 文字が入っているファイルがあるので削除します (vim で set nobomb)
  • 改行コードが CRLF になっているのを LF に修正します (nkf -Lu --overwrite build.gradle)

gradle.properties にはバージョン情報が記載されているので必ず差分がでます

ちなみに今回の 50.1.0 から 54.0.18 のマイグレーションでは「changelog.txt」と「gradle.properties」のみ差分が出たので最悪手動でも何とかなったかもしれません

  • git diff gradle.properties
diff --git a/gradle.properties b/gradle.properties
index 6c23fa8..810b037 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -7,13 +7,13 @@ org.gradle.daemon=false
 ## Environment Properties
 
 # The Minecraft version must agree with the Forge version to get a valid artifact
-minecraft_version=1.20.6
+minecraft_version=1.21.4
 # The Minecraft version range can use any release version of Minecraft as bounds.
 # Snapshots, pre-releases, and release candidates are not guaranteed to sort properly
 # as they do not follow standard versioning conventions.
-minecraft_version_range=[1.20.6,1.21)
+minecraft_version_range=[1.21.4,1.22)
 # The Forge version must agree with the Minecraft version to get a valid artifact
-forge_version=50.1.0
+forge_version=54.0.18
 # The Forge version range can use any version of Forge as bounds or match the loader version range
 forge_version_range=[0,)
 # The loader version range can only use the major version of Forge/FML as bounds
@@ -35,7 +35,7 @@ loader_version_range=[0,)
 mapping_channel=official
 # The mapping version to query from the mapping channel.
 # This must match the format required by the mapping channel.
-mapping_version=1.20.6
+mapping_version=1.21.4

動作確認

再度ビルドして問題なく動作すれば OK です

  • ./gradlew clean && ./gradlew build && ./gradlew runData && ./gradlew runClient

コード修正

非互換になったメソッドなどがある場合はコードも修正する必要があります
自分の場合は以下の修正が必要だったので紹介します
基本的には IDE や lsp-java を使っていればエディタ側で警告してくれるのでそれに沿って手動でコードを修正する感じです

src/main/java/com/example/examplemod/Config.java

これは自分は編集してなかったので最新版をそのまま持ってきました

src/main/java/com/example/examplemod/ExampleMod.java

ビルドのエラーと最新版のファイルと古いファイルを見比べつつエラーを解消させるしかありません (このあたりもっと簡単にできないだろうか)

  • public ExampleMod() が引数付きになっていたので修正 public ExampleMod(FMLJavaModLoadingContext context)
    • modEvnetBus の取得方法も変わっていたので修正 IEventBus modEventBus = context.getModEventBus();
    • ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, Config.SPEC); -> context.registerConfig(ModConfig.Type.COMMON, Config.SPEC);
  • ResourceLocation がプライベートメソッドになって使えなくなっていた
    • new ResourceLocation("examplemod", "laser_fire") -> ResourceLocation.fromNamespaceAndPath("examplemod", "laser_fire")
  • java.lang.NullPointerException: Block id not set
    • ブロックを定義する際に .setId(BLOCKS.key("example_block")) という感じでブロックIDを定義するようになっている
    • ブロックやアイテムを登録するときに設定するプロパティの挙動はカスタムクラス側ではなく Mod メイン側全部やるようにしたほうがいいかもしれない

src/main/java/com/example/examplemod/LaserGunItem.java

  • net.minecraft.world.InteractionResultHolder の廃止
    • use などのメソッドがだいぶ変わっている
    • InteractionResult.sidedSuccess などもなく InteractionResult.SUCCESS を直接 return するように修正
  • The method hurt(DamageSource, float) from the type Entity is deprecated
    • 以下のように修正
livingEntity.hurtServer(
        (ServerLevel) world,
        livingEntity.damageSources().playerAttack(player),
        amountOfdamage);

テクスチャが当たらない

models がうまく当たらなかったです
lang や sound、blockstates は問題なかったです

トラブルシューティング

今回は特にエラーなくマイグレーションできましたがエラーが起きるケースとして以下があるので注意しましょう

  • Java のバージョンのアップグレード
    • Java21 でもともと開発していたが MDK をアップグレードしたら Java23 が必要になった
    • その場合はビルド時にコケるので MDK のドキュメントと照らし合わせて Java もアップグレードする

キャッシュの削除

  • rm -rf ~/.gradle/caches && rm -rf build/*

最後に

かなり面倒な印象です
しかも forge Mod はかなりのペースで更新されているので更新されるたびにマイグレーションするのは大変かなと思います
メジャーバージョンが上がったりしたタイミングで上げるのがいいかなとは思います

もっと簡単にマイグレーションできる方法はないのでしょうか
もしくは NeoForge に移行するべきなのでしょうか

参考サイト

0 件のコメント:

コメントを投稿