Adventures in building a Minecraft mod
Recently, I have been hard at work building Twitch Vs Minecraft, my first ever mod for Minecraft Forge. In this post, I will be showing you how to create your first Minecraft mod using the Forge API for Minecraft 1.12.2, and I will answer some of the most commonly asked modding questions with full code.
Before reading, make sure you have some basic knowledge of Java. Some Java tutorials will be linked below.
DISCLAIMER: THIS TUTORIAL CODE WILL NOT WORK IN VERSIONS ABOVE 1.12.2, AND HAS NOT BEEN TESTED WITH ANY VERSION BELOW.
Getting Started
First, you will need to head over to the Minecraft Forge Website and download the recommended MDK version. Once you have the zip file, extract it into a folder. Next, open a terminal in that folder and type the following command:
If you’re using Eclipse, you will then want to type:
to generate the correct files. If you’re using IntelliJ IDEA (which is highly recommended), you can instead import the build.gradle file as a project.
You will then want to run:
This can also be found in the Gradle tab on the right of the screen.
When moving over to IDEA from Eclipse, follow the above steps and then run cleanEclipse from the Gradle tab to remove all of Eclipse’s files.
The Example Mod
When you first set everything up, you will be given an example mod. It is located in com.examplemod.examplemod . Here’s what that looks like:
While you most likely want to delete this, it’s a good example of how to create a main class.
Build.gradle
This file contains details such as your mod’s name, package name, author name, and version. You will need to change these values:
Here’s an example taken from Twitch Vs Minecraft:
Remember, the archivesBaseName property needs to be the same as the last part of the group property.
Mcmod.info
This file is no longer found in newer versions of the MDK, and is instead replaced with mods.toml. However, for this tutorial we are using 1.12.2.
This file also contains information for your mod, specifically the info that is displayed in the Mods menu in-game. This page tells you everything you need to know about using this file.
Running the mod
While making your mod, you will want to be able to run it. To do this, click the Debug icon with the runClient configuration enabled. You can alternatively run the game from a terminal, or use the Run option rather than debugging.
While changed classes are automaitcally reloaded when debugging in Eclipse, IntelliJ IDEA doesn’t have this by default.
To enable Reloading changed classes using a keyboard shortcut, go to File -> settings and search for “keymap” when in the keymap menu, search for “Reload” and find “Reload changed classes”, which is located under “Run”. I personally have this bound to ctrl + alt + r . While this may not always work, it helps when making quick edits to your mod.
When loading into a game, you will be logged in as a random username. You can set it up to use your Minecraft account, but this is not recommended, as it can cause security issues, and is usually not needed.
Creating a main class — Forge events
So now we need to create our main class. As a starting point, you can use the example mod shown earlier. The FMLInitializationEvent happens when the mod is loading, so we will see the output somewhere around the main menu. There is also the FMLpreInitializationEvent event, which as the name implies, is called before the Initialization event.
The Pre-Initialization event is used for setting up the Logger. This is useful for outputting information to the console. The event can also be used for loading Config Files. Here’s an example of what that looks like:
ConfigManager appears later in the tutorial.
To use the logger, we will use:
You can also make the logger output warnings and errors.
The ServerStarting event is used to register commands. Here’s an example:
Creating a command
Let’s create our own command that we can register from our main class just like that one. First of all, we’ll create a package called command. This is just a standard way of keeping things neat and easy to access. We then create a class called TutorialCommand and extend it from CommandBase by adding extends CommandBase to the end of our public class TutorialCommand .
Now we want to create a list of aliases: private final List aliases; . To use the list of aliases, add this code:
This piece of code adds the alias “tut” to our command. But we don’t have a default command name yet. Next, we will add this:
This is the default command. Now, the player is able to type either “/tut” or “/tutorial” in chat to use the command. However, if the user uses the command wrong, we will want to output an error. To do this, use:
Next, we want to register the aliases we added earlier, so we add:
(This code won’t change for you — every command has this.)
Next up is checkPermission. You can use this to determine who is allowed to use your command, or if it is considered a “cheat”. To let everyone use your command in any gamemode, use:
You can play around with the value it returns yourself, and see what you like best.
Now, we can add Tab Completions. This essentially works like AutoCorrect, where the player presses tab to finish typing an argument, or get a list of all the arguments they could use.
This code will use a list called autocomplete to get its corrections, but we haven’t created that yet. We can add that just underneath our private final List aliases; as
You will need to replace the arguments with your own. You can have as many of these as you like, just continue adding values to the list.
Now, for the real meat of the command: the execute event. This is where whatever code you want to execute when your player uses your command goes. Here’s how you implement it:
You can check for arguments to, by using this if statement:
You can also replace .equals() with .equalsIgnoreCase() if you don’t want your command to be case-sensitive.
You can also use sender.sendMessage() to reply to a command, like this:
TextFormatting is used here to change the colour of the text in the chat.
Creating blocks and items
For this section, there is a really nice YouTube tutorial by Harry Talks. Click Here to watch it. Both blocks and items are covered by the video. You can also check the links below for written tutorials.
Creating a GUI Overlay
GUI overlays appear on the player’s screen, but don’t enable the mouse. Think of them as custom HUD elements.
To get started with creating one, I will create my TutorialOverlay class inside a package called gui . Here’s what the class will look like:
This code renders the text “Hello world!” in dark red in the top left corner of the screen. Replace condition goes here with a valid boolean to be able to enable and disable the GUI.
Creating a GUI Screen
GUI Screens are like Overlays, but the mouse is enabled and the player can interact with the GUI. An example of this is the game’s pause menu.
First, we start off by extending our class from GuiScreen .
Now we need to set some variables:
We can change if the GUI pauses the game in Singleplayer mode by changing this code:
We can add buttons to our Button List for use later on, as seen here:
This button will close our GUI.
Now we need to create our drawScreen event. This GUI opens a box with a message that wraps around, and has a button that closes the GUI. The variable message will need to be set beforehand, and I do this from whatever class actually opens the GUI, hence why it is public and static.
drawDefaultBackground draws the transparent grey background seen in every GUI screen in Minecraft. width and height refer to the width and height of the game window, which in fullscreen for me is 1920×1080. By dividing the width and height by 2, we get the center of the screen. This is then adjusted for the texture, because otherwise the top-left corner would be in the center, rather than the actual center of the image. 4210752 is the colour code used for GUI screen titles in Minecraft. super.drawScreen is used to essentially loop this funtion until displayGUI is false.
Now let’s make our button functional:
When the button is clicked, it sets a boolean called displayGUI to false, and in the drawScreen function we say that if the variable is false, we close the screen.
The background image I used for the GUI (“textures/gui/messagebox_background.png”) can be found here. It is based on the Crafting Table GUI.
Creating a custom crafting recipe
To create a custom crafting recipe, you want to first go to your resources folder (usually src/main/resources) and create a folder named recipes. Create a json file with whatever name you want, but make it something sensible and memorable, like your item name followed by the word “recipe”. Then, head over to this website and copy and paste the output json into your blank json file. because we are using 1.12.2, some items, blocks and crafting methods, for example the Stonecutter and Blast Furnace are unavailable. Make sure you only use what is available in your Minecraft version.
If you want your crafting recipe to make a custom item, you can use a placeholder item. For example, I will make the output of my crafting recipe on the website TNT, and then replace where it says minecraft:tnt in the output json to tutorialMod:tutorialItem .
Config files
Configuration files are stored in the config folder, as <modname>.cfg . To save and load a configuration file, we will create a ConfigManager class. I am creating under the package util .
Here’s what it should look like:
Now we will replace properties go here with our properties. Properties are how variables are stored inside the file.
Paste this property inside both the loadConfig() and saveConfig() functions. Underneath it in loadConfig , we will add:
Here, our tutorialVariable is part of another class, called tutorialClass . Because our variable is a string, we use .getString() to return the value. You can also use .getInt() , .getBoolean() etc. depending on the data type.
Now we move on to saving to the config file. Underneath our property in saveConfig() , we will set our property to the value of tutorialClass.tutorialVariable — the reverse of what we just did in loadConfig() .
It’s really that simple! We can call saveConfig() from other classes — this is best done using a command.
Building the mod
So, you have now tested your mod thoroughly, it works great, and you are happy with it. But you want to be able to upload the mod to CurseForge, or another similar website. To build your mod’s Jar file, use the following command in your project’s root directory:
You can also run this from the Gradle tab in IntelliJ IDEA.
This will generate two files: one is your mod’s Jar, and another has the same name, but with “-sources” on the end. The sources file is not a mod! You can ignore and/or delete this file.
Создание модификаций с помощью Forge/1.12+
В этой статье описывается создание модификаций на основе Minecraft Forge с использованием Eclipse для версий Minecraft с 1.12.
Содержание
Установка Forge Gradle [ ]
Для начала работы, создайте папку с названием вашей модификации избегая кириллицы. Если ваш мод имеет название из двух слов, желательно называть папку без пробелов, к примеру Tutorial-Mod или TutorialMod. Далее перейдите на официальный сайт Forge и скачайте версию с пометкой MDK (Modder Development Kit). Из загруженного архива извлеките папку gradle и файл build.gradle в папку модификации, остальные файлы сохранены для совместимости и/или дополнительных функций и для начала не понадобятся. Далее импортируйте в Eclipse проект как Existing Gradle Project указав папку модификации. Затем в колонке Gradle tasks поочерёдно выполните setupDecompWorkspace из набора forgegradle и eclipse из набора ide (Для пользователей IntelliJ IDEA task genIntelliJRuns), и обновите среду (ПКМ по проекту и Refresh). Теперь можно удалить два файла с расширением .launch, так как для тестовых запусков мы будем использовать задачи Gradle. Для настройки папок ресурсов создайте в папке проекта два каталога: src\main\java и src\main\resources после чего выделите их и по ПКМ найдите пункт Build Patch и нажмите Us as source folder.
Не забудьте! Далее, все связанное с Java кодом мы будем делать в каталоге src\main\java, а остальное в src\main\resources.
Примечание! Для установки потребуется компьютер с минимальным объёмом ОЗУ от 4Гб! Если у вас недостаточно ОЗУ, добавьте необходимый объём из файла подкачки, но такой метод работает лишь на 64-битных системах.
Создание модификации [ ]
build.gradle [ ]
Это файл, который задает свойства проекта и его нужно немного подправить:
Если вы используете IntelliJ IDEA, то в конец build.gradle дополнительно добавьте это:
pack.mcmeta [ ]
Этот файл нужен для корректной работы игры с ресурсами модификации, такими как локализации, модели, рецепты, таблицы добычи и так далее. Заполняется следующим образом:
mcmod.info [ ]
Этот файл задаёт более подробную информацию о модификации и заполняется следующим образом:
Класс модификации [ ]
Данный класс создается в патче и является главным файлом, благодаря которому игра видит нашу модификацию. Заполняется следующим образом:
Класс блока [ ]
Для создания блока создайте класс с названием блока в стиле TutorialBlock в пакете патч.blocks и заполните его следующим образом:
Примечание регистрируемое имя и ключ локализации указывать только в нижнем регистре, используя при надобности нижнее подчёркивание!
Модель [ ]
Модель (которую, например, можно создать здесь) решает то, как наш блок будет выглядеть. Важно знать, что для блоков используется две модели. Одна задает вид блока, поставленного в мире, а вторая, его иконку в инвентаре. Это дает нам возможность сделать блоку отдельную иконку для инвентаря. Сами же модели для блока подключаются к нему как состояния, normal для блока в мире и inventory для его иконки в инвентаре. Поэтому для начала создадим файл идентификатор_блока.json в пакете assets.идентификатор_мода.blockstates, который и подключит наши модели.
Теперь подключим модели. Для этого создайте файл регистрируемое_имя.json в пакете assets.идентификатор_мода.models.block со следующим содержимым:
Теперь зададим иконку блока в инвентаре в пакете assets.идентификатор_модификации.models.block с именем идентификатор_блока.json со следующим содержанием:
Регистрация [ ]
Наш блок имеет текстуры и свойства, но его нужно зарегистрировать в игре. Создадим в пакете домен.автор.мод.init класс BlocksInit :
Теперь в главном классе в методе preInit добавьте инструкцию BlocksInit.registerBlocks а в методе init BlocksInit.registerBlocksRender .
Предмет [ ]
Основное [ ]
Класс предмета [ ]
Для создания предмета создадим класс с именем TutorialItem:
Регистрация [ ]
Для регистрации предмета создадим класс ItemsRegister:
В классе CommonProxy, в методе preInit() добавляем строку ItemsRegister.register(); , а в методе init() ItemsRegister.registerRender(); .
Модель [ ]
Теперь у нас есть предмет, однако если мы запустим игру и выдадим себе его, то он будет выглядеть как куб с фиолетовыми и черными клетками. Это говорит о том, что игра не нашла модель предмета. Для исправления этой проблемы создаём в папке src/main/resources/assets/имя_мода/models/item файл с расширением .json и пишем в нём следующий текст:
Примечание: название файла модели должно совпадать с RegistryName предмета
Второй вариант используется для моделей инструментов и оружия. Однако теперь, когда у нас есть модель для предмета, осталось добавить текстуру по пути src/main/resources/assets/имя_мода/textures/items дав ему имя, идентичное указанному в файле модели.
Создание мода Minecraft с использованием Java и Fabric
Несколько недель назад YouTube порекомендовал мне видео Minecraft с канала Dream, в котором он пытался… С тегами учебник, новички, java, minecraft.
- Автор записи
Несколько недель назад YouTube порекомендовал мне видео Minecraft с канала Dream , в котором он пытался победить в игре, в то время как его друг Джордж пытался остановить его. Это видео было действительно забавным и заставило меня изучить больше их контента.
Прямо сейчас есть куча людей, которые записывают и загружают видео Minecraft на YouTube, но эти двое нашли способ сделать свой контент другим. В принципе, они создают свои собственные плагины для изменения правил игры а затем они записывают себя, пытаясь победить в измененной игре. Все, что я могу сказать, это то, что мне нравится их контент, и это потрясающе – видеть, чего вы можете достичь с помощью кода.
Несколько дней спустя у меня появилась идея разработать мод для Майнкрафта и я подумал Почему нет? Это будет весело!
Выбор инструментов
Как и в Minecraft, нам нужны некоторые инструменты, но в этом случае они помогут нам в процессе создания нашего первого мода.
Несколько инструментов помогут вам создавать моды Minecraft, и я выбрал Fabric , потому что один из модов, с которыми я обычно играю, был создан с его помощью.
Minecraft использует Java, как и Fabric, что означает, что нам также необходимо установить набор для разработки Java или JDK. Чтобы быть более конкретным, нам нужен JDK 8, чтобы иметь возможность скомпилировать наш мод. Вы можете скачать его на этой странице .
И последнее, но не менее важное: нам нужно выбрать редактор кода, в данном случае я выбрал Код Visual Studio , потому что это мой любимый редактор. Тем не менее, вы можете использовать для этого руководства любой редактор, который вам нравится, так как большинство шагов будет выполнено в командной строке.
Настройка проекта
В этом руководстве мы будем использовать стартер, чтобы быстро перейти к созданию нашего первого мода. Давайте пройдем через следующие шаги:
Структура мода#
API Minecraft Forge предлагает нам использовать следующую структуру проекта мода:
- «src» содержит «наборы» для исходного кода и ресурсов. Это может пригодиться, чтобы, например, не смешивать код программы и код для её тестирования. Основой код размещается в модуле «main».
- «java» содержит исходный код соответствующий своему названию языка программирования. Помимо Java, Minecraft Forge предоставляет из коробки возможностью написания модов на Scala (исходный код размещается в каталоге src/main/scala ).
- «resources» содержит ресурсы, а ими в свою очередь являются: текстуры, файлы локализации, звуки и так далее.
Приведённые выше папки поставляются сразу с MDK и содержат официальный мод-пример, но мы их удалили на этапе подготовки, поэтому пересоздайте их. С данным учебником поставляемый мод-пример не нужен.
IDEA автоматически распределит значения источников кода и ресурсов папкам «src» и «resources» соответственно.
В случае Eclipse, выдайте им эти значения вручную: ПКМ по папке → Build Path → Use as Source Folder
По умолчанию Gradle предоставляет наборы: «main» для кода программы и «test» для кода её тестирования (например, для unit-тестов). Minecraft Forge также предоставляет набор «api», файлы которого не будут добавляться в итоговый файл мода, но могут быть использованы во время сборки.
Подробно про наборы исходного кода вы можете прочесть на странице документации Gradle.
Главный файл мода#
В папке «java» создайте базовый пакет вашего мода. Если у вас уже есть домен для мода, то отличным названием для пакета будет что-то вроде ru.mcmodding.tutorial . Если домена у вас нет, вполне подойдет использование вашего никнейма, как название пакета верхнего уровня: mcmodding.tutorial .
Для данного урока мы будем использовать пакет: ru.mcmodding.tutorial .
Теперь создадим в нем класс с названием вашего мода, для урока: McModding . Это и будет главным классом нашего мода.
Для того чтобы Minecraft Forge понял, что данный класс действительно является модом, мы должны пометить данный класс аннотацией @Mod :
Аннотация имеет один единственный параметр modid – уникальный идентификатор мода. В ModID рекомендуется использовать только латиницу в нижнем регистре, никаких пробелов, подчеркиваний и прочего. Крайне не рекомендуется изменять ModID в дальнейшем, так как это приведёт к потере игровых данных, созданных модом.
Minecraft Forge допускает возможность наличия в проекте нескольких классов с аннотацией @Mod , каждый из которых должен иметь свой modid и будет считаться отдельным модом. Автор учебника не знает, зачем это может пригодиться, кроме как для накрутки счётчика загруженных модов.
Разбору полей аннотации @Mod посвящена отдельная статья. Если Вы не собираетесь использовать файл mcmod.info рекомендуется также заполнить такие поля аннотации как name и version .
Файл mcmod.info#
Этот файл определяет метаданные нашего мода: идентификатор, название, авторов, зависимости и так далее. Это обычный JSON файл, хотя он и имеет расширение .info .
Файл mcmod.info является необязательным и в основном служит для оформления странички мода на экране «Mod List».
Создадим в папке «resources» файл mcmod.info .
Минимально правильный mcmod.info файл должен содержать следующее:
Где параметр modid — идентификатор мода, а name отвечает за красивое название вашего мода, которое видит пользователь.
Естественно, что поле modid в аннотации должно соответствовать modid в @Mod . В противном случае мод будет распознан, но выведется сообщение о том, что mcmod.info не найден. Впрочем, на работу мода это никак не повлияет.
Следует обратить внимание, что корневой элемент структуры файла является массивом. Это сделано для возможности описать все моды в одном файле, если проект содержит несколько классов, аннотированных @Mod .
Доступные параметры#
| Параметр | Описание |
|---|---|
| modid | Уникальный идентификатор мода |
| name | Название мода |
| description | Описание мода в 1-2 абзаца |
| version | Версия мода, рекомендуем придерживаться семантического версионирования |
| url | Ссылка на сайт мода, например CurseForge или GitHub |
| updateUrl | Ссылка для обновления мода |
| authorList | Список имен авторов |
| credits | Строка для выражения благодарностей, например тем, кто помогал с модом |
| logoFile | Путь к логотипу мода |
| screenshots | Массив путей к скриншотам мода. В данный момент не поддерживается |
| parent | Уникальный идентификатор родительского мода, в списке модов ваш будет отображён как дочерний у родительского |
| useDependencyInformation | Если true, то следующие три параметра будут учитываться |
| requiredMods | Массив уникальных идентификаторов модов, которые требуются для работы вашего мода. Если данные моды не установлены, то произойдёт краш игры. Данный параметр не указывает порядок загрузки модов. Используйте для этой цели параметр dependencies и dependants |
| dependencies | Массив уникальных идентификаторов модов, которые должны быть загружены до загрузки данного мода |
| dependants | Массив уникальных идентификаторов модов, которые должны быть загружены после загрузки данного мода |
Пример заполненного файла:
Мы создали базовую структуру любого мода для Minecraft. Выглядит она следующим образом: