Java для создания модов в Minecraft

Этот курс предназначен для новичков, желающих освоить язык Java с целью разработки модификаций для Minecraft. Вы пройдете путь от изучения синтаксиса и принципов ООП до настройки среды разработки и создания своих первых игровых предметов и блоков.

1. Основы Java: Синтаксис, типы данных и методы

Основы Java: Синтаксис, типы данных и методы

Добро пожаловать в курс Java для создания модов в Minecraft! Это первая и самая важная статья. Прежде чем мы сможем создать свой первый легендарный меч или нового моба, нам нужно выучить язык, на котором говорит Minecraft. Этот язык — Java.

Многие новички пытаются сразу копировать код из учебников по моддингу, не понимая, как он работает. Это приводит к ошибкам, которые невозможно исправить без базовых знаний. Сегодня мы заложим фундамент: разберем структуру кода, узнаем, где хранить данные (здоровье игрока, количество блоков) и как заставить игру что-то делать (методы).

Структура программы на Java

Java — это объектно-ориентированный язык. Это значит, что весь код в Java живет внутри классов. Представьте, что класс — это чертеж. В Minecraft у нас есть чертеж «Зомби», и по этому чертежу игра создает сотни конкретных зомби в мире.

Любой файл с кодом Java (с расширением .java) имеет определенную структуру.

!Структура стандартного Java-файла: от пакета до методов внутри класса.

Рассмотрим простейшую программу:

Разберем этот код по кирпичикам:

  • public class MyFirstMod: Это объявление класса. Имя класса (MyFirstMod) должно совпадать с именем файла (MyFirstMod.java).
  • { ... }: Фигурные скобки ограничивают тело класса. Всё, что находится между ними, принадлежит этому классу.
  • public static void main(String[] args): Это метод. В данном случае, это главный метод, с которого начинается запуск любой обычной Java-программы. В моддинге Minecraft мы редко используем main напрямую (там запуск берет на себя загрузчик модов, например, Forge или Fabric), но знать его структуру обязательно.
  • System.out.println(...): Команда вывода текста в консоль. Обратите внимание на точку с запятой ; в конце. Точка с запятой в Java обязательна в конце каждой команды. Это как точка в конце предложения.
  • Переменные и типы данных

    В любой игре нужно хранить информацию. Сколько у игрока здоровья? Какой у него никнейм? Включен ли режим полета? Для этого используются переменные.

    Переменная — это именованная ячейка памяти, «коробка», в которую мы кладем значение. В Java, прежде чем положить что-то в коробку, мы должны сказать, какого типа вещи там будут храниться. Это называется строгая типизация.

    Синтаксис создания переменной:

    Примитивные типы данных

    В Java есть 8 примитивных типов, но для моддинга нам чаще всего нужны следующие 4:

  • int (целое число). Используется для подсчета количества предметов, ID блоков, координат блоков.
  • double (число с плавающей точкой). Используется для точных значений: здоровье, координаты сущностей (игрок может стоять на координате 10.5), урон.
  • boolean (логический тип). Может быть только true (истина) или false (ложь). Идеально для переключателей.
  • char (символ). Хранит один символ в одинарных кавычках. В моддинге используется редко, но знать полезно.
  • Ссылочные типы данных: String

    Существуют типы данных, которые сложнее примитивов. Самый важный из них — String (строка). Это текст. Обратите внимание, что String пишется с большой буквы, так как это класс, а не примитив.

    > Важно: Текст в Java всегда пишется в двойных кавычках "...". Одинарные кавычки '...' используются только для типа char.

    !Визуализация типов данных через предметы Minecraft.

    Операторы

    С переменными можно производить различные действия.

    Арифметические операторы

    * + (сложение) * - (вычитание) (умножение) * / (деление) * % (остаток от деления)

    Пример:

    Операторы сравнения

    Используются в условиях (например, «если здоровье меньше 0, игрок умирает»).

    * > (больше) * < (меньше) * >= (больше или равно) * <= (меньше или равно) * == (равно) — обратите внимание на двойное равно! * != (не равно)

    Логические операторы

    Позволяют комбинировать условия.

    * && (И) — оба условия должны быть верны. * || (ИЛИ) — хотя бы одно условие должно быть верно. * ! (НЕ) — меняет значение на противоположное.

    Пример логики для меча:

    Методы

    Если переменные — это существительные (данные), то методы — это глаголы (действия). Метод — это блок кода, который выполняет определенную задачу. В Minecraft методами описывается всё: jump() (прыгнуть), breakBlock() (сломать блок), craftItem() (скрафтить предмет).

    Структура метода

    Разберем составные части:

  • Модификатор доступа: Обычно public (доступен всем) или private (доступен только внутри этого класса).
  • Тип возвращаемого значения: Что метод отдаст нам в результате работы? Если метод вычисляет урон, он вернет double. Если метод просто пишет сообщение в чат и ничего не возвращает, используется ключевое слово void (пустота).
  • Имя метода: Принято писать в стиле camelCase (с маленькой буквы, каждое следующее слово с большой).
  • Параметры: Данные, которые нужны методу для работы. Указываются в скобках.
  • Пример метода с возвращаемым значением

    Допустим, мы пишем мод на новую броню, которая уменьшает урон.

    * double перед именем метода означает, что в конце мы обязаны использовать команду return и вернуть число. * В скобках мы принимаем входящий урон и уровень брони.

    Пример void-метода

    Метод, который просто лечит игрока (изменяет его состояние), но не возвращает число в ответ.

    Здесь return не нужен, так как тип метода — void.

    Комментарии

    Хороший код должен быть понятен не только компьютеру, но и человеку. Для этого используются комментарии. Компилятор Java полностью игнорирует их.

    * // — однострочный комментарий. Всё до конца строки считается текстом. / ... */ — многострочный комментарий.

    Заключение

    Сегодня мы изучили алфавит языка Java. Мы узнали: * Как выглядит структура класса. * Что int — для блоков, double — для здоровья, boolean — для состояний, а String — для текста. * Как создавать методы, чтобы заставить код выполнять действия.

    Эти знания — абсолютный минимум для написания модов. В следующей статье мы перейдем к более сложной, но захватывающей теме — Объектно-Ориентированному Программированию (ООП), на котором держится весь код Minecraft.

    2. Объектно-ориентированное программирование: Классы и наследование в контексте Minecraft

    Объектно-ориентированное программирование: Классы и наследование в контексте Minecraft

    В предыдущей статье мы изучили основы синтаксиса Java: переменные, типы данных и методы. Мы научились создавать простые инструкции. Однако, если вы откроете исходный код Minecraft, вы увидите не просто список команд, а сложную структуру из тысяч файлов. Все они взаимодействуют друг с другом, образуя единую систему.

    Секрет этой системы — Объектно-Ориентированное Программирование (ООП). Это подход, на котором построен весь Minecraft. Без понимания ООП создание модов невозможно, так как любой ваш предмет, блок или моб будет являться частью этой объектной структуры.

    Что такое Класс и Объект?

    В основе ООП лежат два понятия: Класс и Объект. Чтобы понять разницу, давайте представим, что мы работаем в кузнице.

    Класс — это чертеж

    Класс — это инструкция, шаблон или чертеж. Он описывает, какими свойствами должен обладать предмет и что он должен уметь делать, но сам по себе он не является предметом в мире игры.

    Например, в коде Minecraft есть класс SwordItem (Меч). Он описывает общие правила для всех мечей: * У меча есть прочность. * У меча есть урон. * Мечом можно ломать паутину.

    Но сам класс SwordItem — это просто текст в файле. Вы не можете взять «класс» в руку в игре.

    Объект — это конкретный предмет

    Объект (или экземпляр класса) — это то, что создается по этому чертежу. Когда вы крафтите алмазный меч в игре, Java создает объект на основе класса SwordItem, присваивая ему конкретные характеристики (материал — алмаз, урон — 7).

    !Класс — это абстрактный чертеж, а объекты — это конкретные предметы, созданные по этому чертежу.

    В коде создание объекта выглядит так:

    Ключевое слово new дает команду Java: «Возьми чертеж SwordItem и построй мне один конкретный экземпляр».

    Поля и Конструкторы

    Внутри класса данные и действия разделяются на поля и методы.

    Поля (Fields)

    Поля — это переменные, которые живут внутри класса. Они описывают состояние объекта. Для нашего меча полями могут быть:

    Конструкторы

    Конструктор — это специальный метод, который вызывается один раз: в момент рождения объекта (когда мы пишем new). Его задача — настроить начальные параметры.

    Теперь, создавая меч, мы обязаны указать его параметры:

    Наследование: Главный инструмент моддера

    Представьте, что вы хотите создать свой собственный, особый меч — «Изумрудный меч». Если бы не было ООП, вам пришлось бы писать код с нуля: как меч отображается в руке, как он ломает блоки, как наносится урон, как тратится прочность.

    Но в Java есть механизм наследования. Он позволяет создать новый класс на основе уже существующего. Новый класс автоматически получает (наследует) все поля и методы родителя.

    В Java для этого используется ключевое слово extends (расширяет).

    Благодаря одной строчке extends SwordItem, наш EmeraldSword уже умеет всё, что умеет обычный меч в Minecraft. Нам не нужно учить его бить мобов или ломаться — он унаследовал эти умения от родителя SwordItem.

    Иерархия классов в Minecraft

    Minecraft построен на гигантском дереве наследования. Давайте посмотрим на упрощенную цепочку для Зомби:

  • Object (Базовый класс всей Java)
  • Entity (Любая сущность в мире: лодка, стрела, моб)
  • LivingEntity (Живая сущность: имеет здоровье, может умереть)
  • Mob (Имеет интеллект, может ходить)
  • Monster (Враждебный моб)
  • Zombie (Конкретный монстр)
  • !Иерархия наследования показывает, как класс Zombie получает свойства от всех своих предков.

    Если вы создаете своего монстра, вам не нужно наследовать его от Entity. Вы наследуете его от Monster или даже от Zombie, если хотите сделать просто усиленную версию зомби.

    Переопределение методов (@Override)

    Наследование дает нам стандартное поведение. Но что, если мы хотим его изменить? Например, мы хотим, чтобы наш меч при ударе поджигал врага.

    Для этого мы используем переопределение методов. Мы берем метод родителя и пишем свою версию. Чтобы компилятор понял наши намерения, мы ставим аннотацию @Override перед методом.

    Допустим, в классе SwordItem есть метод hurtEnemy (ударить врага). В нашем классе мы изменим его:

    Ключевое слово super

    Обратите внимание на строчку super.hurtEnemy(...).

    this — ссылка на этот* объект (наш новый меч). super — ссылка на родительский* класс (стандартный меч).

    Когда мы переопределяем метод, мы часто хотим сохранить старое поведение и просто добавить что-то сверху. Вызов super.hurtEnemy означает: «Сделай всё то, что обычно делает меч при ударе (сними прочность), а потом я добавлю свой код (поджог)».

    Если мы не напишем super, то стандартное поведение исчезнет. Меч будет поджигать врага, но не будет тратить прочность, потому что код траты прочности находится в родительском методе.

    Расчет характеристик: Пример с формулой

    В моддинге часто приходится рассчитывать баланс. Допустим, мы хотим создать систему, где урон меча зависит от уровня магии игрока. Мы можем использовать формулу внутри нашего метода.

    Рассмотрим формулу расчета итогового урона:

    Где: * — итоговый урон, который будет нанесен врагу. * — базовый урон оружия (например, 7 для алмазного меча). * — уровень магии игрока (целое число). * — коэффициент скалирования (насколько сильно магия влияет на урон).

    В коде это выглядело бы так:

    Использование простых математических моделей позволяет создавать сбалансированные RPG-моды.

    Инкапсуляция: Защита данных

    В прошлой статье мы упоминали модификаторы доступа public и private. В ООП это называется инкапсуляцией.

    Представьте, что у игрока есть переменная health (здоровье). Если сделать её public, то любой другой мод или часть кода может случайно написать player.health = -1000; и сломать логику игры.

    Поэтому важные данные делают private (частными), а для доступа к ним создают специальные методы — геттеры (get) и сеттеры (set).

    * getHealth() — узнать здоровье. * setHealth(double value) — изменить здоровье с проверкой (например, нельзя сделать здоровье меньше 0 или больше максимума).

    В Minecraft многие поля скрыты, и вам придется использовать методы доступа, чтобы взаимодействовать с ними.

    Полиморфизм: Универсальность

    Полиморфизм — страшное слово, обозначающее простую вещь: возможность работать с объектами разных типов так, будто они одного типа.

    Инвентарь игрока — это список ячеек. В ячейке может лежать меч, яблоко, блок земли или ведро лавы. Все они — абсолютно разные классы (SwordItem, ItemFood, BlockItem, BucketItem).

    Но игра хранит их всех как просто Item (или ItemStack). Игре не нужно знать, что именно лежит в слоте, чтобы просто нарисовать иконку предмета. Она вызывает метод getIcon() у предмета, и каждый предмет сам решает, какую картинку отдать.

    Для моддера это значит, что вы можете создать свой уникальный предмет, и игра автоматически примет его в свою систему, положив в инвентарь рядом с ванильными вещами.

    Заключение

    Сегодня мы разобрали фундамент архитектуры Minecraft:

  • Классы и Объекты: Различие между чертежом и зданием.
  • Наследование (extends): Способ не писать код с нуля, а расширять возможности игры.
  • Переопределение (@Override): Изменение стандартного поведения на свое.
  • super: Обращение к родительской логике.
  • Теперь вы понимаете, почему код модов выглядит именно так. В следующей статье мы перейдем к практике и разберем Среду разработки (IDE) — инструмент, который помогает писать этот код, находит ошибки и подсказывает названия методов.

    3. Подготовка инструментов: Установка JDK, IDE и настройка Forge/Fabric

    Подготовка инструментов: Установка JDK, IDE и настройка Forge/Fabric

    Поздравляю! Вы прошли теоретический этап. Вы знаете, что такое переменные, методы, классы и наследование. Теперь у вас есть знания (чертежи), но чтобы построить дом, нужны инструменты и стройматериалы.

    В этой статье мы превратим ваш компьютер в настоящую студию разработки модов. Мы установим JDK (чтобы компьютер понимал код), IDE (умный редактор кода) и настроим Forge или Fabric (фундамент для модов).

    Многие новички бросают обучение именно на этом этапе из-за технических ошибок. Читайте внимательно, и мы настроим всё правильно с первого раза.

    Шаг 1: Java Development Kit (JDK)

    Обычные игроки устанавливают просто Java (или она идет в комплекте с лаунчером). Но мы — разработчики. Нам нужен JDK (Java Development Kit) — комплект инструментов разработчика. Он включает в себя компилятор, который превращает ваш понятный человеку код в байт-код, понятный машине.

    Какую версию выбрать?

    Это самый важный вопрос. Minecraft меняет версию Java в зависимости от версии игры. Если вы установите неправильную версию, игра просто не запустится.

    | Версия Minecraft | Требуемая версия Java | | :--- | :--- | | 1.20.5 и новее | Java 21 | | 1.18 — 1.20.4 | Java 17 | | 1.17 | Java 16 | | 1.16.5 и старее | Java 8 |

    > Совет: Для современного моддинга (актуальные версии игры) вам почти всегда нужна Java 17 или Java 21. Старые версии (1.7.10, 1.12.2) требуют Java 8, но мы рекомендуем учиться на новых версиях.

    Где скачать?

    Мы рекомендуем использовать сборку Eclipse Adoptium (Temurin). Она стабильна и признана сообществом Minecraft.

  • Перейдите на сайт Adoptium.
  • Выберите нужную версию (например, Java 21 для новейших версий или Java 17 для 1.18-1.20).
  • Скачайте установщик .msi (для Windows) или .pkg (для macOS).
  • Важно: При установке обязательно поставьте галочку напротив пункта "Set JAVA_HOME variable" (Установить переменную JAVA_HOME). Это позволит другим программам автоматически находить Java.
  • Шаг 2: Среда разработки (IDE)

    Писать код можно хоть в Блокноте, но это мучение. Профессионалы используют IDE (Integrated Development Environment) — интегрированную среду разработки. Она подсвечивает ошибки на лету, подсказывает названия методов и позволяет запускать игру одной кнопкой.

    Для Java существует три гиганта: IntelliJ IDEA, Eclipse и VS Code. В мире Minecraft стандартом де-факто является IntelliJ IDEA.

    Установка IntelliJ IDEA

  • Перейдите на сайт JetBrains.
  • Вам нужна версия Community Edition. Она полностью бесплатна и содержит всё необходимое для моддинга. Версия Ultimate платная и для наших задач избыточна.
  • Скачайте и установите её, используя настройки по умолчанию.
  • Шаг 3: Выбор загрузчика (Forge vs Fabric)

    Minecraft сам по себе не умеет загружать моды. Ему нужен посредник — Mod Loader (загрузчик модов). Это специальная библиотека, которая внедряется в игру и позволяет вашему коду взаимодействовать с миром Minecraft.

    Существует два основных лагеря:

  • Minecraft Forge (или NeoForge в новых версиях). Старый, мощный, проверенный временем гигант. Большинство глобальных индустриальных и магических модов написаны на нем. Он предоставляет огромное количество готовых инструментов, но может быть тяжеловесным.
  • Fabric. Молодой, легкий и модульный загрузчик. Он обновляется мгновенно после выхода новых версий игры. Он требует установки дополнительных библиотек (Fabric API), но работает быстрее.
  • !Визуализация архитектуры моддинга: Загрузчик как мост между вашим кодом и игрой.

    Для этого курса мы будем ориентироваться на общие принципы, которые применимы везде, но в качестве примера будем использовать Forge (или NeoForge), так как он имеет более строгую структуру классов, что полезно для обучения ООП.

    Шаг 4: Создание первого проекта

    В отличие от обычных программ, проект мода не создается с нуля кнопкой «New Project». Нам нужен MDK (Mod Development Kit) — заготовка проекта, в которой уже настроены скрипты для скачивания игры и библиотек.

    Процесс настройки (на примере Forge 1.20.x):

  • Скачивание MDK:
  • * Перейдите на официальный сайт Minecraft Forge. * Выберите версию Minecraft (например, 1.20.1). * Скачайте файл Mdk (не Installer!).

  • Подготовка папки:
  • * Создайте пустую папку для вашего мода (назовите её без пробелов, например MyFirstMod). * Распакуйте содержимое скачанного архива MDK в эту папку.

  • Импорт в IntelliJ IDEA:
  • * Запустите IDEA. * Нажмите Open (Открыть). * Найдите вашу папку и выберите файл build.gradle. * Нажмите «Open as Project» (Открыть как проект).

    Магия Gradle

    После открытия вы увидите, что внизу справа появилась полоса загрузки. Это работает Gradle.

    Gradle — это система автоматической сборки. Она читает файл build.gradle и делает всю грязную работу: * Скачивает нужную версию Java (если не нашла). * Скачивает код Minecraft. * Скачивает библиотеки Forge. * Декомпилирует Minecraft (превращает непонятный код игры в читаемый Java-код), чтобы вы могли смотреть, как устроена игра внутри.

    > Внимание: Первый запуск может занять от 5 до 20 минут в зависимости от интернета и мощности процессора. Будьте терпеливы. Если процесс завершился ошибкой, проверьте интернет и попробуйте нажать кнопку «Reload Gradle Project» (значок слона со стрелочками) в правой панели.

    Шаг 5: Настройка информации о моде

    Пока Gradle работает, давайте настроим «паспорт» нашего мода. Найдите файл mods.toml (в папке src/main/resources/META-INF/) или gradle.properties (в корне проекта), в зависимости от версии MDK.

    Вам нужно изменить: * modId: Уникальный идентификатор мода. Только маленькие английские буквы, без пробелов. Например: supermod. * displayName: Красивое название, которое игроки увидят в меню модов. Например: Super Mod. * version: Версия вашего мода. Начните с 0.0.1.

    Шаг 6: Первый запуск

    Когда Gradle закончил индексацию (полоски загрузки исчезли), пора проверить, работает ли наша среда.

  • В правой части окна IDEA найдите вкладку Gradle.
  • Раскройте список: Tasks -> forgegradle runs (или просто fg_runs).
  • Дважды кликните на runClient.
  • Откроется консоль, побегут строки логов, и через минуту запустится Minecraft. Это специальная версия для разработчиков. В главном меню нажмите кнопку «Mods» — если вы видите в списке свой мод (или просто examplemod, если вы еще не переименовали главный класс), значит, вы всё сделали правильно!

    Возможные проблемы

    * Ошибка "Java version mismatch": Проверьте в настройках проекта (File -> Project Structure), что выбранная SDK совпадает с версией, требуемой для вашей версии Minecraft (см. таблицу в начале статьи). * Ошибка памяти: Если Gradle падает с ошибкой OutOfMemory, зайдите в настройки Gradle в IDEA и увеличьте выделенную память.

    Заключение

    Теперь у вас есть:

  • Установленная Java.
  • Мощная среда разработки IntelliJ IDEA.
  • Настроенный проект, который запускает Minecraft.
  • Ваша кузница готова. В следующей статье мы удалим пример кода из шаблона и наконец-то создадим наш первый собственный предмет, применив знания об ООП и наследовании на практике.

    4. Архитектура мода: Регистрация предметов, блоков и добавление текстур

    Архитектура мода: Регистрация предметов, блоков и добавление текстур

    Добро пожаловать обратно в нашу виртуальную кузницу! В прошлых статьях мы настроили рабочее место, установили JDK и IntelliJ IDEA, а также разобрались с основами Java и ООП. Теперь у нас есть инструменты и знания, но наш мод пока пуст. В нем нет ни мечей, ни руды, ни даже простого предмета.

    Сегодня мы это исправим. Мы переходим к самому сердцу моддинга — системе регистрации. Мы научимся объяснять Minecraft, что наш новый предмет существует, как он называется и как выглядит.

    Что такое Реестр (Registry)?

    Представьте, что Minecraft — это огромная библиотека. Каждая книга в ней — это блок, предмет, биом или звук. Чтобы библиотекарь (движок игры) мог найти книгу, она должна быть записана в каталоге.

    Этот каталог в Minecraft называется Реестр (Registry).

    Если вы просто создадите класс MySuperSword в коде, но не зарегистрируете его, игра никогда о нем не узнает. Это будет просто мертвый код. Регистрация — это процесс выдачи вашему объекту уникального имени (ID) и внесение его в списки игры.

    У каждого объекта в игре есть «паспортное имя», состоящее из двух частей:

  • Namespace (Пространство имен): Это ваш MODID (идентификатор мода), который мы задали в прошлой статье.
  • Path (Путь): Уникальное имя предмета внутри вашего мода.
  • Пример: minecraft:diamond (алмаз из ванильной игры) или supermod:magic_ingot (слиток из вашего мода).

    !Регистрация связывает ваш Java-код с игровым миром через уникальное имя.

    DeferredRegister: Безопасная регистрация

    В старых версиях Minecraft регистрация была хаотичной. Сейчас в Forge используется стандарт DeferredRegister (Отложенная регистрация).

    Почему «отложенная»? Потому что мы не пытаемся впихнуть наши предметы в игру сразу при запуске Java. Мы создаем список того, что хотим зарегистрировать, и просим Forge сделать это в правильный, безопасный момент времени, когда игра будет к этому готова.

    Давайте создадим наш первый регистратор для предметов. Обычно это делается в отдельном классе, например, ModItems.

    Разберем этот код: * DeferredRegister.create(...): Мы создаем пустой список для предметов, привязанный к нашему моду (examplemod). * ITEMS.register("sapphire", ...): Мы добавляем в список запись. Имя предмета будет sapphire. * () -> new Item(...): Это лямбда-выражение. Мы говорим игре: «Когда придет время, создай новый объект класса Item с вот такими настройками». * RegistryObject<Item>: Это контейнер. В момент написания кода предмета еще нет в игре. RegistryObject — это как обещание, что предмет там появится. Позже мы будем обращаться к предмету через SAPPHIRE.get().

    Не забудьте вызвать метод ModItems.register(modEventBus) в конструкторе вашего главного класса мода, иначе список так и останется лежать на столе!

    Регистрация Блоков: Двойная работа

    С блоками все немного сложнее. В Minecraft существует четкое разделение:

  • Block (Блок): Объект, который стоит в мире. Вы можете по нему ходить, сломать его. Но он не может лежать в инвентаре.
  • Item (Предмет): Объект, который лежит у вас в руке или в инвентаре.
  • Когда вы ломаете блок земли, вы подбираете предмет «Блок земли». Когда вы ставите его обратно, предмет исчезает, и появляется блок.

    Поэтому, чтобы создать новый блок, нам нужно зарегистрировать два объекта: сам блок и предмет для него (BlockItem).

    Обратите внимание на BlockBehaviour.Properties.copy(Blocks.IRON_BLOCK). Вместо того чтобы вручную настраивать прочность, звук шагов и инструмент для добычи, мы просто копируем свойства железного блока. Это сила ООП и наследования!

    Ресурсы: Текстуры и Модели

    Если вы запустите игру сейчас, ваш предмет будет работать, но выглядеть он будет как черно-фиолетовый квадрат (знаменитая текстура «нет текстуры»). Это потому, что мы написали логику (код), но не дали игре ресурсы (картинки).

    Minecraft отделяет логику от внешнего вида. Все ресурсы хранятся в папке src/main/resources.

    Структура папок должна быть строгой:

    1. JSON Модели (Model)

    Minecraft не знает, что ваш сапфир — это плоская картинка. Ему нужно это сказать через JSON-файл.

    Создайте файл src/main/resources/assets/examplemod/models/item/sapphire.json:

    * "parent": "item/generated": Мы наследуем стандартную модель плоского предмета. * "layer0": Указывает путь к картинке. Игра будет искать файл sapphire.png в папке textures/item.

    2. Текстура (Texture)

    Теперь нарисуйте (или скачайте) картинку sapphire.png размером 16x16 пикселей и положите её в папку src/main/resources/assets/examplemod/textures/item/.

    !JSON-файл модели указывает игре, в какой папке искать PNG-текстуру.

    3. Локализация (Lang)

    Чтобы предмет назывался «Sapphire» вместо item.examplemod.sapphire, нужно создать файл перевода.

    Файл: src/main/resources/assets/examplemod/lang/en_us.json:

    Data Generators: Взгляд в будущее

    Вы могли заметить, что создание JSON-файлов вручную — это утомительно. Для одного предмета это нормально, но если у вас их сотня?

    Профессиональные разработчики используют Data Generators. Это специальный код, который запускается один раз и сам генерирует все JSON-файлы моделей, рецептов и тегов. Мы изучим это в продвинутых уроках, но пока важно понимать, как эти файлы устроены изнутри, поэтому создание первого предмета вручную — обязательная практика.

    Добавление в креативную вкладку

    В версиях Minecraft 1.19.3 и новее просто регистрации предмета недостаточно, чтобы увидеть его в меню креатива. Вам нужно добавить его во вкладку через систему событий.

    В главном классе мода нужно подписаться на событие BuildCreativeModeTabContentsEvent:

    Этот код говорит: «Если игра строит вкладку Ингредиенты, добавь туда наш Сапфир».

    Заключение

    Поздравляю! Вы прошли путь от пустого проекта до реального объекта в игре.

    Мы узнали:

  • Что такое Реестр и почему без него ничего не работает.
  • Как использовать DeferredRegister для безопасного добавления предметов.
  • Почему для блока нужно регистрировать и Block, и Item.
  • Как связать код с текстурами через JSON-модели.
  • Теперь у вас есть материальная база. Но что делать с этими предметами? В следующей статье мы займемся Рецептами крафта, чтобы ваш сапфир можно было не только выдать командой, но и создать в режиме выживания.

    5. Игровая логика: Обработка событий, рецепты и сборка проекта

    Игровая логика: Обработка событий, рецепты и сборка проекта

    Приветствую вас, коллеги-разработчики! В прошлых лекциях мы создали «тело» нашего мода: настроили среду, зарегистрировали предметы и блоки, и даже нарисовали им текстуры. Но пока что наш мир мёртв. Сапфировый меч не имеет особых свойств, а новый блок — это просто декорация.

    Сегодня мы вдохнем в наш мод жизнь. Мы разберем три фундаментальные темы:

  • События (Events): Как заставить код реагировать на действия игрока.
  • Рецепты (Recipes): Как создать крафт для наших предметов.
  • Сборка (Building): Как превратить проект в готовый .jar файл, чтобы отправить его другу.
  • Система событий (Event Bus)

    Minecraft — это игра, в которой постоянно что-то происходит: игрок ломает блок, моб получает урон, чанк загружается. Чтобы ваш мод мог вмешаться в эти процессы, используется Система Событий.

    Представьте, что игра — это радиостанция, которая постоянно вещает: «Внимание! Игрок прыгнул!», «Внимание! Зомби умер!». Ваш мод — это радиоприемник. Если вы настроите его на нужную волну, вы услышите сигнал и сможете выполнить свой код.

    !Визуализация того, как игровой движок рассылает уведомления о событиях подписчикам через шину событий.

    Две главные шины событий

    В Forge (и NeoForge) существует две основные «линии передачи»:

  • Mod Event Bus: Работает только при запуске игры. Здесь мы регистрируем предметы, блоки и настраиваем клиент.
  • Forge Event Bus: Работает во время игры. Здесь мы ловим прыжки, удары, чат и взаимодействие с миром.
  • Пример: Приветствие при входе

    Давайте сделаем так, чтобы при входе в мир игроку писалось сообщение. Для этого нам нужно «подписаться» на событие PlayerLoggedInEvent.

    Создадим новый класс ModEvents:

    Разберем аннотации: * @Mod.EventBusSubscriber: Говорит Forge, что в этом классе есть методы-слушатели. * bus = Bus.FORGE: Указывает, что мы слушаем игровые события (а не события загрузки). * @SubscribeEvent: Помечает конкретный метод как обработчик события.

    Логика случайного выпадения

    Допустим, мы хотим, чтобы при ломании травы с небольшим шансом выпадал наш Сапфир. Для этого используем событие BlockEvent.BreakEvent.

    В программировании игр часто используется простая математическая модель вероятности. Вероятность события рассчитывается как:

    где — вероятность наступления события (выпадения предмета), а — коэффициент редкости (например, если , то шанс 1 к 10).

    В коде это реализуется через генератор случайных чисел:

    Кастомная логика предметов

    Не всегда нужны события. Если вы создаете свой собственный предмет, проще прописать логику прямо внутри его класса. Это называется переопределение методов (Override).

    Давайте создадим «Металлоискатель». Создадим класс MetalDetectorItem, который наследуется от Item.

    Теперь, если зарегистрировать этот класс вместо обычного Item, наш предмет обретет уникальное поведение.

    Рецепты крафта (Recipes)

    В Minecraft рецепты — это не код Java. Это файлы данных в формате JSON. Это сделано для того, чтобы игроки могли менять рецепты с помощью датапаков, не переписывая мод.

    Файлы рецептов должны лежать строго по пути: src/main/resources/data/ваш_modid/recipes/

    Структура JSON-рецепта

    Создадим файл sapphire_block_from_sapphires.json. Мы хотим, чтобы из 9 сапфиров получался 1 блок сапфира.

    Разберем элементы: * type: Тип рецепта. crafting_shaped означает, что форма важна (как верстак). Бывает еще crafting_shapeless (форма не важна). * pattern: Рисунок крафта. Каждая буква обозначает слот. Пробел — пустой слот. * key: Расшифровка букв. Мы говорим игре, что S — это наш предмет examplemod:sapphire. * result: Что получится в итоге.

    !Иллюстрация связи между визуальным расположением предметов в верстаке и строками в JSON-файле рецепта.

    > Важно: Соблюдайте синтаксис JSON. Одна пропущенная запятая или лишняя скобка приведет к тому, что рецепт просто не появится в игре, а в консоли будет ошибка при загрузке.

    Сборка мода (Build)

    Вы написали код, нарисовали текстуры и создали рецепты. В IntelliJ IDEA всё работает. Но как передать мод другу?

    Для этого нужно собрать проект в JAR-файл (Java ARchive). За этот процесс отвечает Gradle.

    Процесс сборки

  • Откройте панель Gradle в правой части IntelliJ IDEA.
  • Перейдите в папку Tasks -> build.
  • Дважды кликните по задаче build.
  • Gradle начнет компилировать код, сжимать ресурсы и упаковывать всё в архив. Это может занять от 10 секунд до минуты.

    Где искать файл?

    После успешного завершения (надпись BUILD SUCCESSFUL в консоли), ваш мод появится в папке проекта: build/libs/

    Там вы увидите файл с названием вроде examplemod-0.0.1-SNAPSHOT.jar. Это и есть ваш готовый мод! Его можно скопировать в папку mods любого обычного Minecraft лаунчера (при условии, что там установлен Forge той же версии).

    Заключение

    Сегодня мы превратили набор картинок и названий в настоящий игровой контент.

    Мы изучили: * Как слушать «радио» событий Minecraft через EventBus. * Как создавать уникальное поведение предметов через переопределение методов. * Как писать рецепты на языке JSON. * Как собрать финальный файл мода.

    Теперь вы полноценный разработчик. Ваш мод можно установить и играть. В следующих статьях мы углубимся в создание сложных блоков, которые могут хранить предметы (как сундуки) и иметь свой интерфейс.

    Удачи в коде!