2017年12月16日土曜日

Forge MDK を使って簡単な独自 Mod を開発してみた

概要

前回 Forge MDK + eclipse をインストールして Mod を開発する環境を構築してみました
今回はそこから簡単な独自 Mod を作成するところまでやってみました
origin_ingot2.png

環境

  • macOS X 10.13.2
  • Minecraft 1.12.2
  • Forge 1.12.2 - 14.23.1.2555
  • Forge MDK 1.12.2 - 14.23.1.2555
  • Java 1.8.0_151
  • eclipse Oxygen.1a Release (4.7.1a)

各種 Java ファイルの作成

まずはコードを書いていきます

com.sample.mod パッケージの作成

  • Reference.java
package com.sample.mod;

public class Reference {
    public static final String MODID = "sm";
    public static final String NAME = "Sample Mod";
    public static final String VERSION = "0.1";
    public static final String CLIENTPROXY = "com.sample.mod.proxy.ClientProxy";
    public static final String COMMONPROXY = "com.sample.mod.proxy.CommonProxy";
}

各種 mod に必要な情報を定義するクラスです

  • SampleMod.java
package com.sample.mod;

import com.sample.mod.proxy.CommonProxy;

import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.SidedProxy;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;

@Mod(modid = Reference.MODID, name = Reference.NAME, version = Reference.VERSION)
public class SampleMod {

    @SidedProxy(clientSide = Reference.CLIENTPROXY, serverSide = Reference.COMMONPROXY)
    public static CommonProxy proxy;

    @EventHandler
    public static void preInit(FMLPreInitializationEvent event) {
        proxy.preInit(event);
    }

    @EventHandler
    public static void init(FMLInitializationEvent event) {
        proxy.init(event);
    }

    @EventHandler
    public static void postInit(FMLPostInitializationEvent event) {
        proxy.postInit(event);
    }
}

メインクラスです
ここでは各種ハンドラの処理やアイテムを生成する処理をコールしているだけです
実際の処理は別のパッケージで定義していきます

com.sample.mod.handlers パッケージの作成

  • RegistyHandler.java
package com.sample.mod.handlers;

import com.sample.mod.init.ItemInit;

public class RegistyHandler {

    public static void Client() {
    }

    public static void Common() {
        ItemInit.init();
        ItemInit.register();
    }
}

各種アイテムなどを登録する処理を定義するクラスです
init および register は Common 側でコールしましょう
v1.11 の場合は register は Client でコールしますが、v1.12 の場合は Common 側でどちらもコールします
ItemInit クラスはこの後作成します

com.sample.mod.init パッケージの作成

  • ItemInit.java
package com.sample.mod.init;

import com.sample.mod.init.items.CustomIngot;

import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.item.Item;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.fml.common.registry.ForgeRegistries;

public class ItemInit {

    public static Item sample_ingot;

    public static void init() {
        sample_ingot = new CustomIngot("sample_ingot");     
    }

    public static void register() {
        registerItem(sample_ingot);
    }

    public static void registerItem(Item item) {
        ForgeRegistries.ITEMS.register(item);
//      Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(item, 0, new ModelResourceLocation(item.getRegistryName(), "inventory"));
        ModelLoader.setCustomModelResourceLocation(item, 0, new ModelResourceLocation(item.getRegistryName(), "inventory"));
    }
}

アイテムを生成しマインクラフトの世界に追加します
今回はインベントリに追加します
またここでポイントですがマインクラフトの世界にアイテムを追加する場合は ModelLoader.setCustomModelResourceLocation を使います
コメントアウトしている Minecraft.getMinecraft() は v1.11 だと動作するのですが、v1.12 だと動作しないので注意してください (NullPointerException が発生します)

com.sample.mod.init.items パッケージの作成

  • CustomIngot.java
package com.sample.mod.init.items;

import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.Item;

public class CustomIngot extends Item {

    public CustomIngot(String name) {
        setUnlocalizedName(name);
        setRegistryName(name);
        setCreativeTab(CreativeTabs.MATERIALS);
    }
}

今回はインゴットを追加してみます
なのでカスタムするインゴット用のクラスを作成します
名前の登録とクリエイティブの設定を行います
今回は MATERIALS のタブ内にアイテムを追加します

com.sample.mod.proxy パッケージの作成

  • ClientProxy.java
package com.sample.mod.proxy;

import com.sample.mod.handlers.RegistyHandler;

import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;

public class ClientProxy extends CommonProxy {
    public void preInit(FMLPreInitializationEvent event) {
        super.preInit(event);
    }

    public void init(FMLInitializationEvent event) {
        super.init(event);
        RegistyHandler.Client();
    }

    public void postInit(FMLPostInitializationEvent event) {
        super.postInit(event);
    }
}

クライアントで動作させる場合の初期化処理を定義します

  • CommonProxy.java
package com.sample.mod.proxy;

import com.sample.mod.handlers.RegistyHandler;

import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;

public class CommonProxy {
    public void preInit(FMLPreInitializationEvent event) {
        RegistyHandler.Common();
    }

    public void init(FMLInitializationEvent event) {
    }

    public void postInit(FMLPostInitializationEvent event) {
    }
}

サーバまたはクライアント上で動作する際の共通処理を定義します
RegistyHandler.Common() をコールすることでゲーム開始時に今回追加するアイテムの登録処理を行います

各種リソースファイルの作成

次に各種リソースファイルを作成します
リソースファイルとは mod の画像や定義情報のことを指します

assets.sm.lang

  • en_us.lang
item.sample_ingot.name=Sample Ingot

mod の名前を定義するファイルです
各言語ごとにファイルを用意すればローカライズされたときに適切な名前を返すことができます

assets.sm.models.item

  • sample_ingot.json
{
    "parent": "item/generated",
    "textures": {
        "layer0": "sm:items/sample_ingot"
    }
}

mod の定義ファイルです
今回や画像情報しか定義しませんがここにアイテムの効果や使われ方、クラフト方法を定義することもできます

assets.sm.textures.items

  • sample_ingot.png

sample_ingot.png

既存の鉄インゴットの画像を適当に編集して作成しました

その他

  • mcmod.info
[
{
  "modid": "sm",
  "name": "Sample Mod",
  "description": "This is my sample mod.",
  "version": "${version}",
  "mcversion": "${mcversion}",
  "url": "",
  "updateUrl": "",
  "authorList": ["hawksnowlog"],
  "credits": "hawksnowlog",
  "logoFile": "",
  "screenshots": [],
  "dependencies": []
}
]

mod 全体の情報を定義します
Forge の Mods 一覧に表示される際の情報になります

全体としてプロジェクトエクスプローラが以下のようになっていれば OK です
origin_ingot0.png

動作確認

プロジェクトを右クリックして Client で動作させてみましょう
起動後インベントリを開いて Materials のシークバーを一番下に持っていって最後に追加した mod があれば成功です
origin_ingot1.png

最後に

独自の mod を作成してみました
今回は本当にただ追加しただけなので何も効果のないアイテムになっています
ここからクラフト情報などを追加していく必要はあります

参考サイトにありますが動画のチュートリアルが非常に参考になります
ただ、Minecraft のバージョンによって動作する API がだいぶ変わっているので注意が必要です

Java で書くのが少し辛いですが API や開発方法には一定のパターンがあるのでイベントハンドリングやリソースファイルの配置などを覚えれば結構簡単に作れるようになると思います
あとは Web 上に先人の方が作られた mod のサンプルがたくさんあるのでそられを参考に頑張れば何とかなると思います

参考サイト

0 件のコメント:

コメントを投稿