LoginSignup
4
2

【Minecraft】Mod開発の必須技術「Mixin」とは?

Posted at

はじめに

Minecraft Java版のMod開発における「Mixin」をご存知ですか?

MixinはModdingをする上での必須技術と言っても過言ではありません。

この記事では、このMixinについて簡単にご紹介したいと思います。

対象読者

  • ForgeまたはFabricのMod開発をしている
  • Mixinについて知らない

この記事では扱わないこと

  • Mixinの環境構築、コーディングの解説
  • Forge、FabricなどのMod作成の解説

Mixinとは?

Minecraft Java版の既存のソースコードを、実行時に変更することができるフレームワークです。

  • Mod開発で利用される
  • SpongePoweredが開発

できるようになること

Mixinを使わない場合

Mixinを使わないでMod開発をする場合、

  • イベントシステム
  • タスクシステム
  • イニシャライザー

などの、APIよりあらかじめ提供されているエントリーポイントに沿って、オリジナルの処理を加えていくことになるでしょう。

しかしながら、こんなときはどうすればいいでしょうか?

「○○の部分に処理を加えたいのに、いい感じのイベントがない!!」

「既存の○○を無効化したいのに、APIでサポートされてない!!」

このように、APIでサポートされていない機能に対してModを適用する場合、複雑な実装になりがちです。

Mixinで解決

Mixinはこれらの問題を解決します。
Mixinにより可能になる主なことを、まとめます。

  • ソースコードの任意の場所に、自由に処理を加えられる

  • ソースコード上のメソッドの呼び出しや、フィールド、変数へのアクセスを書き換えられる

  • privateなメソッド、フィールドへのアクセサーを追加できる

※正確には他にもあります

ひとつずつ簡単に説明します。

1. 【Inject】処理の追加する

MixinではInjectと呼ばれます。

これは、マインクラフト内部のmethod()の中へ、オリジナルの処理injected()を追加する例です。

  // マインクラフト内部のメソッド
  public void foo() {
    // Modにより追加された処理
+   injected(new CallbackInfo("foo", false));
    // 元からある処理
    doSomething1();
    doSomething2();
    doSomething3();
  }

// https://fabricmc.net/wiki/tutorial:mixin_examplesより引用

他にも、次のようなことも可能です。

  • 任意の場所でreturn;する
  • メソッドの返し値を書き換える

2. 【Redirect】呼び出しを変更する

MixinではRedirectと呼ばれます。

  // マインクラフト内部のメソッド
  public void foo() {
    doSomething1();
    Something something = new Something();
    // 元からある処理は削除される
-   int i = something.doSomething(10);
    // Modにより定義された処理に置き換わる
+   int i = injected(something, 10);
    doSomething2();
  }

// https://fabricmc.net/wiki/tutorial:mixin_examplesより引用

正確には異なる機能ですが、似たようなもので次のものもあります。

  • int i = 4;4といった定数の部分を置き換えるModifyConstant
  • doSomegthing(i);iといったメソッドの引数を置き換えるModifyArg ModifyArgs
  • ローカル変数を書き換えるModifyVariable

3. 【Accessor】privateへのアクセサーを追加する

MixinではInvokerAccessorと呼ばれます。

privateなメソッドを呼び出せるようにする

EndermanEntity enderman = ...;
// EndermanEntityInvokerを経由して、通常では呼び出せないprivateメソッドを呼び出せる
((EndermanEntityInvoker) enderman).invokeTeleportTo(0.0D, 70.0D, 0.0D);

// https://fabricmc.net/wiki/tutorial:mixin_accessorsより引用

privateなフィールドにアクセスする

// 通常ではアクセス出来ないフィールド、itemUseCooldownにアクセス
int itemUseCooldown = ((MinecraftClientAccessor) MinecraftClient.getInstance()).getItemUseCooldown();

// https://fabricmc.net/wiki/tutorial:mixin_accessorsより引用

「リフレクションを使えばいいのでは?」

と言われそうですが、リフレクションにはない次のメリットがあります。

  • リフレクションに比べて早い
  • アクセサーの定義はコンパイル時なので型安全

最後に

Mixinを扱えるようになると、Modで作れるものが大幅に増えます。
まだまだ日本語の文献が少ない状況ですが、みなさんも是非学んでみてください。

おまけ

Mixinの実装はKotlin、Scalaなどで行えません;;
一度はJavaの沼から抜け出した皆さんも、再びJavaを書くチャンスです!やったね!

あと詳しくは知らないけど、Mixinはサーバープラグインにも適用できるらしい。

参考資料&補足資料

FabricMCによる解説

今すぐMixinを使いたいならこっちがおすすめ。

開発元SpongePoweredによるドキュメント

技術的な内容ばかりで、実践的なことは書かれてないかも。

数少ない日本語文献

宣伝

Youtubeチャンネル

自作Modを遊ぶゆっくり実況動画を投稿しています。
登録者は15万人ほどです。

X(旧Twitter)

技術に関する投稿をしています。

Discordサーバー

マイクラ技術系をメインに交流できるサーバーです。
多少内輪ノリがありますが、興味があればどうぞ。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2