注意!!
この記事の内容はMinecraft Ver.1.20.1、Forge Ver.47.3.0上で確認した内容になっています。
バージョンが異なると仕様が変更されている場合があります。
いきなり何事かと思うかもですが。
実はmodの開発に手を出してまして、いつものmod攻略とかじゃないのでプレイオンリーの人には興味のない話です。 すいません。
いろいろ記事も書こうとしてるんですが、何分Javaもマイクラのmodも開発経験が全くなかったのでかなり難航してまして。 うまく言ってない理由は文献がほとんどない?ことでして、今回は
なんでこんなところでつまずくねん!!
と、これだけで1週間以上時間を取られた「開発環境で他のmodをロードできない」問題を解決しますよー。
やろうとしていたこと
いくつかのコンセプトでmod開発テストをしていて、とりあえず実戦投入が早そうな「原石ブロックを直接焼いてインゴットのブロックを得る」というmodを作ろうとしていた時のお話。
レシピ導入は割と簡単にできました。 SimpleCookingRecipeBuilderでsmeltingするとかまどレシピ、blastingすると溶鉱炉レシピです。 マイクラ本家だと鉄と金と銅の3つしかないので、3種実装して終わりです。
この状態のmodはひとまず公開してみました。
で、これだけだと物足りないので、今のサーバに入っているAd Astra、DivineRPG、Ice and Fire: Dragonsあたりにも対応しようとしたわけなんです。
そこでプロジェクトフォルダにある「run/mods」にmodのJARファイルを置いて、ひとまず開発環境でmodありで起動してみました。
たったそれだけだったのに…。
InvocationTargetExceptionやらNoSuchFieldErrorやらNoSuchMethodErrorやらのエラー多発で起動すらできなかったわけです。
開発環境用の特殊なやり方があるんだろうと思い、Googleくんを開いたわけですが、検索すれども検索すれどもさっぱり分からん。 ChatGPTくんに聞いてもよく分からんくて、どうにか解決までこぎ着けようというのが今回の目的です。
例外が出る原因
例外を詳細を見ていると関数やら変数やらが見つからんって内容なんですが、その見つからんものの名前が「f_256764_」とか可読性が低いものになってたんですよね。
これはたぶん難読化されたやつ。
日本語/英語問わず例外名やら状況やらを入れて検索しているとココが見つかりました。
「プレイ用のjarパッケージはメンバ名にマッピングが施されるためそのままでは開発環境に入らないです」と今の僕には意味が分からないことが書いてあって、解決策としてmodのソースを自分のプロジェクトにぶっこめと。
いやー、一部APIとかで他modのソースを含んでるソースは見たことありますが、併用modのソースをまるごと含んでるmodなんて見たことなくて、まぁでもGitに上げる前にそこだけ除外してるとか、そんな感じなのかなとChatGPTくんに補助してもらいながら試したけど、むしろエラー範囲が拡大しただけで全く解決できず。
で、さらに検索を続けるとこんな記事を見つけました。 開発環境にはソレ用のdev版を入れる、と書いてあるんですね。
そういえばdevって付いてるファイルを昔見たな!
つまりですね、
- 普通にビルドしたJARファイルは難読化されている
- 開発環境では難読化されていない
- そのまま開発環境に入れると難読化のせいで参照先が見つからない
- 開発環境では難読化前のdev版が必要
ということみたいです。
通常のプレイで使っているのは難読化済みのObfuscated版で、難読化されていないものがDeobfuscated版。 略してdeobf版とかdev版とか呼ぶみたい。
以下、deobf版と呼びます。
deobf版の入手方法
昔、JARファイルの末尾に「-dev」みたいなのがくっついたmodを見た事あった気がしたんですが、今回チェックした3つのmodでは見つからず。 他のmodでも最近は見たことない気がします。
そこでChatGPTくんに聞いてみると、
- そのmodのソースコードを入手してこい
- ビルド時にdeobfオプションを付けてビルドしろ
とのことでした。
注意!必読!
このやり方は嘘ではなかったんですが、とてもとても効率が悪いです。 後で簡単なやり方が出てくるので興味ない人はすっ飛ばしてください。
ソースコードの入手
ソースコードの入手はCurseForgeのmodのページに行くと、mod名の下のメニューに「Source」ってリンクがあるので、クリックするとGitHubに飛びます。
右上らへんにある緑の「Code」ボタンを押して、「Download ZIP」を選択するとソースコードがダウンロードできます。 左上のBranchのところがバージョンになっていると思うので、開発しているマイクラのバージョンに合わせてください。
「Source」ボタンはない場合があって、その場合はこのやり方が使えません。 今回テストしたやつだとIce and Fire: Dragonsがソース非公開でした。 公開してるやつがdeobf版かと思ったけどそういうわけでもなかったです。
deobf版のビルド
全部ChatGPTくんに聞いたのでセオリー通りかどうかは分かりません。 とりあえず動きましたという例です。
まず、プロジェクトルートにあるbuild.gradleを開きます。
末尾に以下のコードを追加します。
tasks.register('buildDeobf', Jar) {
group = 'build'
archiveClassifier.set('deobf')
from sourceSets.main.output
finalizedBy 'reobfJar'
}
ごめん、コードの意味は全然わからん。
これを追加すると、Gradleタブのbuildメニューの中に「buildDeobf」が登場します。 あとはこれでビルドすると「build/libs」の中に末尾「-deobf」のdeobf版が出来上がり。
これを開発環境のrunとかrun-dataのmodsフォルダへ入れると無事に起動できました。
deobf版の簡単入手
ソースからdeobf版をビルドする方法を学んだわけですが、
いやいやいやいや!
mod10個あったら10個これをやらないといけないの!?
たかだか併用modのテストをするだけでこのコストはありえないと思ったんですよ。 こんなにめんどくさくて、ソース公開が前提で、しかもローダ(Forge)が一致したバージョンのソースを入手してこないといけないとか、どう考えてもハードルが高すぎますよ。
と思ってですね、ChatGPTくんをかなり問い詰めたんですけど答えは出てこなくて。
mod開発のきっかけになったProductive Beesのソースを見てたらこんなのを見つけたんですよ。
dependenciesのところにこんな↓コードがあります。
implementation fg.deobf("curse.maven:jei-238222:4712868")
implementation fg.deobf("curse.maven:jade-324717:5072729")
implementation fg.deobf("curse.maven:the-one-probe-245211:4579432")
implementation fg.deobf("curse.maven:emi-580555:5204261")
implementation fg.deobf("curse.maven:curios-309927:4985525")
implementation fg.deobf("curse.maven:corail-woodcutter-331983:4573934")
implementation fg.deobf("curse.maven:create-328085:4626108")
jei、the-one-probe、curios、createと見たことあるmodの名前が挙がってます。 しかも「deobf」とついてて、あたかもdeobf版のバイナリをネットからダウンロードしてきてるような書き方です。
これについて調べていくと
まさにそういう効果でした!
後ろの部分の意味はおそらくmodのIDとバージョンかなと思って、IDはともかくバージョンがmodページで表記のものとは全然違います。 最初はそのmodを使用してる別modのソースからコード取得しようとしてたんですが、
Curseforgeにコードが公開されてました。
例えば、Productive BeesのCurseforgeのダウンロードページを開いてもらうと、ここは基本的にmodのダウンロードに使うと思うんですが、「Curse Maven Snippet」というのがちょっと下にあるんですね。 ここを右の矢印ボタンで展開すると、こんな↓コードが表示されました。
implementation fg.deobf("curse.maven:productivebees-377897:5566102")
コレやん!!
というわけで、別に自分でコンパイルする必要なんかなくて、併用テストしたいmodはbuild.gradleを開いて、dependenciesのところにこんな↓風に追記してやればいいだけみたいです。
dependencies {
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
implementation fg.deobf("curse.maven:official-divinerpg-363543:5049334")
}
このままだと参照リポジトリがなくてエラーが出るので、repositoriesにこれ↓を追加してください。
repositories {
maven { url "https://www.cursemaven.com" }
}
このやり方だと非常に楽なので、ぽんぽんmodを追加できるようになりました。 テスト用にJEIとかずっと欲しかった。
この問題で2週間近く頭を悩ませたのに、検索しても文献が見つからず(オレが無能)、ChatGPTくんに聞いても分からず(ChatGPTくんが無能)。 やっぱり簡単な導入方法があったわけです。
依存modはどうなるの?
依存modというのは、例えば今回調べたIce and Fire: DragonsだとCitadelが必須modとして指定されてるわけですが、当然ないとダメでした。
なので依存modもそのCurseforgeから「Curse Maven Snippet」を調べて追加してください。
どんなmodも「Curse Maven Snippet」があるの?
確証はないですけどたぶんあると思います。
というのも、僕が公開したゴミmodもCurseforgeで「Curse Maven Snippet」が登録されてました。
アップロード時のオプションでこういう設定をした覚えもないし、当然自分でdeobf版をアップロードもしてないので、Curseforgeで公開すれば自動で登録されるんだと思います。
最後に
開発環境にmodを入れるやり方をまとめました。
たったこれだけのことでこんなにも苦労するとは思ってもみませんでした。 やり方が分かれば簡単。
注意点として、今回のことは依存mod(ライブラリとか前提modとかいうやつ)を設定するものではありません。 あくまで開発環境で動くmodの導入だけ。
依存modはまた別の設定が必要そうなので、開発シリーズが続くならその時に。
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とかもいけるみたい。