マイクラMOD制作学習#1 環境構築【ver1.21、1.21.1】【NeoForge】

はじめに

マインクラフトのMOD制作をしようと思い至り、学習を進めています。
備忘録としてこちらに記事をまとめていきます。

前提

開発環境

  • Windows 11 64bit
  • Minecraft 1.21(1.21.1にも対応)
  • Java 21
  • NeoForge 21.0.167

記事のまとめ方

  • Javaなどのプログラミングに関する解説は基本なし。
  • コードのコメントに軽い説明を記載。

参考動画

JDK(Java Development Kit)のインストール

以下のURLからインストーラーをダウンロード
https://adoptium.net/temurin/releases?packeage=jdk&version=21&os=windows&arch=x64&mode=filter

注)インストール時に以下の画面で「Set JAVA_HOME variable」を「ローカルハードドライブにインストール」に変更すること。

統合開発環境(IDE)のインストール

今回使用するのは、IntelliJ Idea。Eclipseも推奨されているようです。

以下のURLからインストーラーをダウンロード。
https://www.jetbrains.com/ja-jp/idea/download/?section=windows

ダウンロードしたexeファイルを実行して、インストール。(設定変更は特に必要なさそう)

NeoForgeのテンプレートプロジェクトを取得

以下のURLからダウンロード。※Githubアカウントが必要です。
https://github.com/NeoForgeMDKs/MDK-1.21-ModDevGradle

他のバージョンで開発する場合には、以下のURLから末尾が「ModDevGradle」のものを探す。
https://github.com/orgs/NeoForgeMDKs/repositories?

このテンプレートを使って、自分のアカウントにリポジトリを作成します。

Repository name:任意の名前(今回はNeoForge-Tutorial-1.21.X)
Choose visibility:Private(非公開)→ ページ公開のためPublicにしました。

作成されたリポジトリのURLをコピー

先ほどインストールしたIntelliJ Ideaを開き、リポジトリのクローン。

コピーしたリポジトリのURLを赤線の部分に張り付けてクローン。
(プロジェクトの保存先を変えたい場合には青枠でフォルダーを選ぶ)

GitHubと連携していない場合には、ログインして最終的に以下の画面で連携を完了させる。

以下の警告が出るので、プロジェクトを信頼。

自動でビルドが開始され、数分で完了します。
この間に、操作しやすいように以下3つの設定のチェックを外しておきます。(必須ではないけど推奨)

ビルドが失敗する場合に確認する設定+

プロジェクトのSDKの確認

左上のファイルからプロジェクト構造の設定画面を開く

SDKが以下のようにJava21となっているか確認。

Gradle設定の確認

左上のファイルから設定画面を開く。

「ビルド、実行、デプロイ」-「ビルドツール」-「Gradle」の画面でGradle JVMを確認。
JAVA_HOMEが選択されており、インストールしたJDKのバージョンが表示されていればOKなはず。
ここで表示されない場合には、IntelliJ Ideaを再起動するか、JDKのインストールからやり直そう。

Gradleプロジェクトのリロード。

テンプレートのコードを自作MOD用に修正

ExampleModファイルを開き、package名をリファクタリング(Shift+F6)する。
命名は任意だが、他のMODと被らないような名前が良いっぽい。
一般的にドメイン名などを使うことが多いみたい?
例)com.chimugame.tutorialmod

元のexampleフォルダは必要ないので削除(Deleteキー)

Tutorial.javaファイルのクラス名を「TutorialMod」にリファクタリング(Shift+F6)

  • 変数「MODID」を「MOD_ID」にリファクタリング
  • テンプレートの追加アイテム、ブロックの部分を削除、またはコメントアウト
package com.chimugame.tutorialmod;

...(中略)

// The value here should match an entry in the META-INF/neoforge.mods.toml file
@Mod(TutorialMod.MOD_ID)
public class TutorialMod {
    // Define mod id in a common place for everything to reference
    public static final String MOD_ID = "tutorialmod";
    // Directly reference a slf4j logger
    public static final Logger LOGGER = LogUtils.getLogger();
    /*// Create a Deferred Register to hold Blocks which will all be registered under the "examplemod" namespace
    public static final DeferredRegister.Blocks BLOCKS = DeferredRegister.createBlocks(MOD_ID);
    // Create a Deferred Register to hold Items which will all be registered under the "examplemod" namespace
    public static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(MOD_ID);
    // Create a Deferred Register to hold CreativeModeTabs which will all be registered under the "examplemod" namespace
    public static final DeferredRegister<CreativeModeTab> CREATIVE_MODE_TABS = DeferredRegister.create(Registries.CREATIVE_MODE_TAB, MOD_ID);

    // Creates a new Block with the id "examplemod:example_block", combining the namespace and path
    public static final DeferredBlock<Block> EXAMPLE_BLOCK = BLOCKS.registerSimpleBlock("example_block", BlockBehaviour.Properties.of().mapColor(MapColor.STONE));
    // Creates a new BlockItem with the id "examplemod:example_block", combining the namespace and path
    public static final DeferredItem<BlockItem> EXAMPLE_BLOCK_ITEM = ITEMS.registerSimpleBlockItem("example_block", EXAMPLE_BLOCK);

    // Creates a new food item with the id "examplemod:example_id", nutrition 1 and saturation 2
    public static final DeferredItem<Item> EXAMPLE_ITEM = ITEMS.registerSimpleItem("example_item", new Item.Properties().food(new FoodProperties.Builder()
            .alwaysEdible().nutrition(1).saturationModifier(2f).build()));

    // Creates a creative tab with the id "examplemod:example_tab" for the example item, that is placed after the combat tab
    public static final DeferredHolder<CreativeModeTab, CreativeModeTab> EXAMPLE_TAB = CREATIVE_MODE_TABS.register("example_tab", () -> CreativeModeTab.builder()
            .title(Component.translatable("itemGroup.examplemod")) //The language key for the title of your CreativeModeTab
            .withTabsBefore(CreativeModeTabs.COMBAT)
            .icon(() -> EXAMPLE_ITEM.get().getDefaultInstance())
            .displayItems((parameters, output) -> {
                output.accept(EXAMPLE_ITEM.get()); // Add the example item to the tab. For your own tabs, this method is preferred over the event
            }).build());*/

    // The constructor for the mod class is the first code that is run when your mod is loaded.
    // FML will recognize some parameter types like IEventBus or ModContainer and pass them in automatically.
    public TutorialMod(IEventBus modEventBus, ModContainer modContainer) {
        // Register the commonSetup method for modloading
        modEventBus.addListener(this::commonSetup);

        /*// Register the Deferred Register to the mod event bus so blocks get registered
        BLOCKS.register(modEventBus);
        // Register the Deferred Register to the mod event bus so items get registered
        ITEMS.register(modEventBus);
        // Register the Deferred Register to the mod event bus so tabs get registered
        CREATIVE_MODE_TABS.register(modEventBus);*/

        // Register ourselves for server and other game events we are interested in.
        // Note that this is necessary if and only if we want *this* class (ExampleMod) to respond directly to events.
        // Do not add this line if there are no @SubscribeEvent-annotated functions in this class, like onServerStarting() below.
        NeoForge.EVENT_BUS.register(this);

        // Register the item to a creative tab
        modEventBus.addListener(this::addCreative);

        // Register our mod's ModConfigSpec so that FML can create and load the config file for us
        modContainer.registerConfig(ModConfig.Type.COMMON, Config.SPEC);
    }

    private void commonSetup(FMLCommonSetupEvent event) {
        // Some common setup code
        LOGGER.info("HELLO FROM COMMON SETUP");

        if (Config.LOG_DIRT_BLOCK.getAsBoolean()) {
            LOGGER.info("DIRT BLOCK >> {}", BuiltInRegistries.BLOCK.getKey(Blocks.DIRT));
        }

        LOGGER.info("{}{}", Config.MAGIC_NUMBER_INTRODUCTION.get(), Config.MAGIC_NUMBER.getAsInt());

        Config.ITEM_STRINGS.get().forEach((item) -> LOGGER.info("ITEM >> {}", item));
    }

    // Add the example block item to the building blocks tab
    private void addCreative(BuildCreativeModeTabContentsEvent event) {
        /*if (event.getTabKey() == CreativeModeTabs.BUILDING_BLOCKS) {
            event.accept(EXAMPLE_BLOCK_ITEM);
        }*/
    }

    // You can use SubscribeEvent and let the Event Bus discover methods to call
    @SubscribeEvent
    public void onServerStarting(ServerStartingEvent event) {
        // Do something when the server starts
        LOGGER.info("HELLO from server starting");
    }

    // You can use EventBusSubscriber to automatically register all static methods in the class annotated with @SubscribeEvent
    @EventBusSubscriber(modid = TutorialMod.MOD_ID, bus = EventBusSubscriber.Bus.MOD, value = Dist.CLIENT)
    static class ClientModEvents {
        @SubscribeEvent
        static void onClientSetup(FMLClientSetupEvent event) {
            // Some client setup code
            LOGGER.info("HELLO FROM CLIENT SETUP");
            LOGGER.info("MINECRAFT NAME >> {}", Minecraft.getInstance().getUser().getName());
        }
    }
}

※エラーになっている箇所も一緒にコメントアウトしています。(全て削除でOKです)

gradle.propertiesを修正し、Gradleのリロード
※GitHubのソースは自由に使っていただいて構いませんので、MITライセンスに変更

Gradleのタブから「ソースのダウンロード」

TutorialMod.javaファイルの以下の部分から、BuildCreativeModeTabContentsEventクラスに飛ぶ(カーソルを合わせてCtrl+左クリック)

青いメッセージバーが表示されているはずなので、「ソースの添付」を押下

動作確認

上部のメニューからClientの実行

しばらくして、いつものNeoForgeのロード画面からマイクラが立ち上がれば成功です!

導入MODの確認画面で実装したMOD名があるか確認しよう。
(制作者名とMOD説明はgradle.propertiesでは変更できなくなった?わかったら追記します)

GitHubへコミット、プッシュ

以下のように変更をコミットする。

上部のメニューからプッシュ(そのままプッシュするならコミットとプッシュ)

多くの警告がありますが、基本的には気にしなくてもいいです。

自分のGitHubページを開いて、更新されているか確認

参考に私のGitHubページを添付しておきます。自由に使用していただいて構いません。
https://github.com/Tem238/NeoForge-Tutorial-1.21.X

タイトルとURLをコピーしました