Структура мода#
Fabric использует автоматический сборщик Gradle, поэтому нам стоит придерживаться определенной структуры папок:
└── src
└── main
├── java
└── resources
В java хранится весь Ваш исходный код. В resources хранятся текстуры, модели, звуки, рецепты и прочее.
fabric.mod.json#
Fabric использует файл fabric.mod.json для обнаружения и загрузки Вашего мода. Он должен обязательно находится по пути src/main/resources.
Файл определяет данные Вашего мода: ModId, название, зависимости, точки входа, Mixins, авторов и так далее.
Примерный fabric.mod.json выглядит так:
{
"schemaVersion": 1,
"id": "fabrictut",
"version": "1.0-SNAPSHOT",
"name": "FabricTutorial",
"description": "My awesome mode!",
"authors": [
"jjigem"
],
"contact": {},
"license": "MIT",
"icon": "assets/fabrictut/icon.png",
"environment": "*",
"entrypoints": {
"main": [
"ru.mcmodding.fabrictut.FabricTutorial"
]
},
"mixins": [
"fabrictut.mixins.json"
],
"depends": {
"fabricloader": ">=0.10.8",
"fabric": "*",
"minecraft": "1.16.3"
}
}
Параметры name, description и authors могут содержать коды цветового форматирования.
| Параметр | Описание | Обязательный? | Пример |
|---|---|---|---|
| schemaVersion | Обозначает версию формата json-файла Тип: число |
Нет (0 если не указано) | "schemaVersion": 1 |
| id | Обозначает идентификатор мода (MOD_ID) Тип: строка |
Да | "id": "myawesomemod" |
| version | Версия Вашего мода Тип: строка |
Да | "version": "1.0-SNAPSHOT" |
| name | Имя Вашего мода Тип: строка |
Нет | "name": "More Food" |
| description | Описание Вашего мода Тип: строка |
Нет | "description": "Супер мод на еду из медных слитков" |
| authors | Авторы мода Тип: массив строк или объектов Person |
Нет | "authors": ["jjigem", "Notch"] |
| contributors | Внесшие вклад в мод Тип: массив строк или объектов Person |
Нет | "contributors": ["Mumfey"] |
| license | Лицензия для Вашего мода Тип: строка |
Нет | "license": "MIT" |
| icon | Путь к иконке для Вашего мода. Иконка должна быть в формате PNG. Тип: строка |
Нет | "icon": "assets/myawesomemod/icon.png" |
| depends | Зависимости мода Тип: массив пар строка-строка (ID - Версия) |
Нет | "depends": |
| recommends | Рекомендации для мода. То же, что и зависимости, но не остановят игру, а покажут предупреждение Тип: массив пар строка-строка (ID - Версия) |
Нет | "recommends:" |
| conflicts | Конфликты модификаций. При запуске Вашего мода с конфликтным будет предупреждение о несовместимости Тип: массив пар строка-строка (ID - Версия) |
Нет | "conflicts": |
| breaks | Конфликты модификаций, которые не дадут запустить игру. Тип: массив пар строка-строка (ID - Версия) |
Нет | "breaks": |
| entrypoints | Точки входа для мода | Да | "entrypoints": |
| environment | Игровое окружение | Да | "environment": "*" |
| mixins | Файлы Mixins для мода Тип: массив строк |
Нет | "mixins": ["modid.mixins.json"] |
| accessWidener | Файл accessWidener для мода. О нем подробнее позже Тип: строка |
Нет | "accessWidener": "modid.accesswidener" |
Это далеко не все параметры, а лишь основные из них.
Главный класс мода#
Мы знаем как правильно выглядит файл fabric.mod.json, создали его и заполнили, как нам нужно, но мод все еще не будет инициализирован.
Точки входа#
Fabric использует точки входа для разделения клиента и сервера.
Допустимые точки входа: client, server, main.
main используется для инициализации вещей, которые могут происходить как на клиенте, так и на сервере, например, регистрация предметов и существ.
client используется для всего того, что не может происходить на сервере, например, регистрация рендера существ. client ни за что не будет использован на сервере.
server используется для сервера, и не будет использоваться на клиенте.
Вы наверное спросите, зачем нужен server, если можно использовать main? Дело в том, что server используется для выделенного (Dedicated) сервера, а не для встроенного (Integrated).
Итак, как создать точку входа: создаем класс в пакете нашего мода, реализуем нужный интерфейс и переопределяем метод.
| Интерфейс | Метод | Сторона |
|---|---|---|
| ModInitializer | onInitialize() | Клиент-сервер |
| ClientModInitializer | onInitializeClient() | Клиент |
| DedicatedServerModInitializer | onInitializeServer() | Сервер |
Обычно моды содержат либо реализацию ModInitializer и ClientModInitializer, либо только ModInitializer.
Для начала мы сделаем самый простой мод, реализовав ModInitializer. В отличие от Forge, нам не нужны никакие дополнительные аннотации вроде "@Mod", достаточно лишь указать, что мы реализуем интерфейс.
Создаем класс нашего мода по пути наш_домен/никнейм/ID_мода, например ru/mcmodding/fabrictut. Конечно, можно использовать абсолютно любой путь, но это не очень правильно.
Назовем класс FabricTutorial и укажем, что мы реализуем интерфейс ModInitializer. Затем нам нужно переопределить метод onInitialize(), иначе будет ошибка.
В итоге у нас получится такой класс:
package ru.mcmodding.fabrictut;
import net.fabricmc.api.ModInitializer;
public class FabricTutorial implements ModInitializer {
@Override
public void onInitialize() {
}
}
Структура файлов при этом будет выглядеть так:
└── src
└── main
├── java
│ └── ru
│ └── mcmodding
│ └── fabrictut
│ └── FaricTutorial.java
└── resources
└── fabric.mod.json
Не забывайте, что указанные тут имена классов и пакетов - всего лишь пример для урока.