RingoWay Developer

RingoWay Developer 

Разработчик майнкрафт модов

70subscribers

44posts

goals1
6 of 100 paid subscribers
Лекции по NeoForge 1.21.10

Forge Моддинг 1.20.1 — Лекция 3: Создание предмета

Приветствую, друзья!
Предыдущая лекция:
Forge Моддинг 1.20.1 — Лекция 2: Структура пакетов (папок)
Цель лекции
В этой лекции я расскажу, как создать первый предмет для твоего Minecraft мода и добавить его во вкладку из ванильного Minecraft. Мы пройдем все шаги: от создания классов до настройки необходимых файлов. Создадим обычный предмет без какой-либо специфичной логики.
Важно: В дальнейшем все «папки» я буду иногда называть пакетами, так как в Java именно так называются логические группировки классов, организованные в иерархическую структуру, аналогично файловой системе. (К resources это не относится)
Создавать пакеты и классы нужно с помощью ПКМ по нужной папке.
1. Структура классов и пакетов
1.1. Пакет core
Первым делом создаём пакет core в корневой папке проекта (та папка, которая имеет название айди вашего мода). В этом пакете располагается базовая логика инициализации, регистрации и настройки всех основных компонентов проекта. Именно здесь «запускается» наш мод — от него зависит, как будут работать все остальные части проекта.
1.2 Пакет registry
Далее создаём пакет registry внутри core. В этом пакете будут находиться все классы, отвечающие за регистрацию различных игровых объектов, таких как:
• Предметы
• Блоки
• Эффекты
• Жидкости и т.д.
Суть в том, что вся регистрация компонентов происходит централизованно именно здесь, что помогает держать основной код мода (например, игровой процесс) отделённым от процесса инициализации.
1.3. Создание и название класса регистрации предметов
Теперь перейдём к созданию класса регистрации предметов. Я придерживаюсь практики, когда в названии классов регистрации использую заглавные буквы, соответствующие названию проекта. Это позволяет сразу понять, к какому моду принадлежит данный класс.
Примеры:
• Если мод называется Redstone Revolution, я назову класс регистрации предметов RRItems.
• В моём лекционном проекте, который называется Rinova, класс регистрации предметов будет называться RItems. 
Для справки: многие мододелы, если название проекта короткое, используют имена вроде ExampleItems или ExampleBlocks. Лично мне удобнее применять систему с заглавными буквами, поскольку это помогает избежать путаницы. Кстати, изучая проект GregTech, я заметил, что автор использует похожий подход — например, GTItems, GTBlocks и GTBlockEntities.
И так, мы создали наш класс RItems...
2. Класс регистрации предметов
2.1. Объявление переменной ITEMS.
Первым делом нам необходимо создать переменную ITEMS, через которую мы будем регистрировать наши предметы. Это делается с помощью класса DeferredRegister<Item>. Он помогает отложить регистрацию до нужного момента загрузки мода. 
Импортируйте необходимые классы (обычно IDE предлагает автодополнение — нажмите TAB или дважды ЛКМ по имени класса для автоматического импорта).
Код:
Пояснения:
• DeferredRegister<Item> — это «контейнер» для ваших предметов, в который вы будете добавлять новые объекты.
• ForgeRegistries.ITEMS — указывает, что регистрировать мы будем именно предметы.
• Rinova.MOD_ID — идентификатор вашего мода (например, "rinova"), необходимый для корректной регистрации. Он нужен для того, чтобы Forge знал, к какому моду принадлежит данный DeferredRegister.
2.2. Совет для новичков (для тех кто не работал в средах разработки)
Когда вы начинаете набирать слово DeferredRegister, ваша IDE (например, IntelliJ IDEA или Eclipse) должна показать список доступных классов. Вы можете нажать TAB для автодополнения или дважды щёлкнуть ЛКМ по имени класса — так все необходимые импорты добавятся автоматически:
Если вы вдруг скопировали код из git, то вам необходимо импортировать нужные классы, для этого наведитесь на то, что горит красным и нажмите Alt+Enter.
2.3. Что такое DeferredRegister?
DeferredRegister<Item> — это специальный помощник в Forge моддинге для регистрации предметов (и не только), который делает этот процесс безопасным и упорядоченным.
Представьте:
Вы собираете все свои новые предметы в список, но регистрировать их в игру нужно в строго определённое время (во время загрузки мода). DeferredRegister позволяет вам «отложить» регистрацию до нужного момента, когда игра готова принять новые объекты.
Основные моменты:
• Deferred (отложенная регистрация): Вы создаёте список предметов, а Forge сам зарегистрирует их, когда наступит нужное время.
• Типизация <Item>: Указывает, что в этот DeferredRegister будут добавляться объекты типа Item.
• Удобство: Вам не нужно самостоятельно следить за моментом регистрации — всё происходит автоматически в рамках жизненного цикла загрузки мода.
2.4. Регистрация первого предмета!
Теперь мы начинаем регистрацию уже самого предмета. Делаем это мы через RegistryObject<Item>. (скрин переменной будет ниже).
На новой строке пишем:
Ключевые слова public static final
• public — предмет доступен из других классов
• static — объект создаётся один раз при загрузке мода (в контексте Forge)
• final — переменная не может быть изменена после инициализации
Совет: В IntelliJ IDEA можно использовать шорткат psf + Tab для быстрого написания.
RegistryObject<Item>
• Это контейнер для вашего предмета, который Forge будет использовать для регистрации
• <Item> в угловых скобках указываем тип объекта (в данном случае — обычный предмет)
Именование переменной
• Рекомендуется использовать UPPER_SNAKE_CASE (капс и нижние подчёркивания вместо пробелов)
(пример: PINKYLITE_CRYSTAL)
В Java принято писать константы капсом.
• Название должно отражать функционал предмета для удобства разработки
Через знак равно начинаем присваивать значение. После через переменную ITEMS, которую мы создали обращаемся к методу register.
Метод register()
• Первый аргумент ("pinkylite_crystal") — уникальный ID предмета:
- Только строчные буквы и нижние подчёркивания (никаких пробелов и дефисов!)
- Рекомендуется использовать тот же ID, что и в названии переменной, но в snake_case (нижний регистр и нижние подчёркивания)
• Второй аргумент (() -> new Item(...)) — лямбда-выражение:
- Это "фабрика", которая создаст объект предмета, когда Forge будет готов. 
- Простыми словами: "Отложенное создание" чтобы избежать ошибок при загрузке. 
Для знающих Java: Supplier поможет задержать создание предмета, чтобы исключить ошибки 
Item.Properties()
• Здесь настраиваются свойства предмета:
- Максимальный размер стопки
- Прочность (для инструментов)
- Горение в лаве
• Для обычного предмета оставляем пустым — new Item.Properties()
В следующих уроках я расскажу о всех параметрах предметов более подробно
Так выглядит итоговый код
Частые ошибки:
• "pinkylite-crystal" (дефисы вместо подчёркиваний)
• Пропуск RegistryObject<> (без этого предмет не зарегистрируется)
• Использование new Item() напрямую (без лямбда-выражения).
Упрощение регистрации
Так же мы можем написать для удобства отдельный метод Java для такого типа предметов, чтобы можно было просто писать id и всё.
Грубо говоря мы создали "функцию" (в java - это методы), которая в закулисье принимает строку, создаёт предмет и возращает уже зарегистрированный предмет. Обьяснять подробно не буду, это уже принципы Java.
2.5. Регистрация класса регистрации предметов
Для того, чтобы зарегистрировать наш класс RItems, необходимо создать специальный метод, который будет регистрировать наш созданный класс в главном классе, выглядит он следующим образом:
Метод register нужен для того, чтобы зарегистрировать ITEMS в системе событий (IEventBus). IEventBus — это механизм, который позволяет объектам подписываться на события и реагировать на них.
Теперь переходим в главный класс и регистрируем наш класс RItems внутри конструктора RinovaMod():
Передаём переменную eventBus в метод register. Таким образом наш мод видит существование класса RItems и регистрирует предметы.
3. Создание JSON-файлов
Для отображения предмета в игре необходимо создать два JSON-файла: один для модели предмета (отображение текстурки), а второй для его перевода (язык предмета). Иначе это будет фиолетово черная текстура с названием айди предмета.
3.1. Создание корректных пакетов.
Важность структуры ресурсов:
Строгое соблюдение структуры папок и их названий критически важно. Даже незначительная ошибка в названии (регистр, опечатка) приведёт к некорректной работе мода.  
Пошаговая структура:
• Папка resources.
- Корневая директория ресурсов мода (src/main/resources).
• Папка assets.
- Содержит все ресурсы мода: текстуры, модели, локализацию, звуки и т.д.
Внутри assets создаётся папка с ID вашего мода (напр. rinova).
• Внутри папки с ID мода (rinova):
- textures
Хранит PNG-текстуры элементов игры.
Для предметов создайте подпапку item.
- models
Содержит JSON-файлы, определяющие 3D-модели и их привязку к текстурам.
Для предметов создайте подпапку item
- lang
Включает JSON-файлы локализации, где задаются названия предметов на разных языках.
Итоговый вид папок:
3.2. Текстура предмета
Далее переносим текстуру нашего предмета. Оно должно быть размером 16x16 пикселей (либо любой другой размер, но главное соотношение 1:1) и сохранено в формате PNG в пакет textures/item. Название текстуры должно быть - айди_предмета.png:
Текстуры можно создавать в любой удобной для вас программе (Photoshop и т.д.). Я создаю в Aseprite:
3.3. Создание модели и применение текстуры предмету.
Для начала займемся созданием json модели текстуры (папка models). Далее ПКМ по папке item, наводимся на New -> File и прописываем айди_предмета.json. К примеру у меня это будет pinkylite_crystal.json:
Открываем файл и пишем следующую запись:
В этом JSON-файле мы определяем модель предмета для нашего мода. Мы указываем, что наш предмет должен основываться на стандартной 2D-модели item/generated, которая отвечает за отображение иконок в инвентаре и на руке. Затем, в разделе textures, мы назначаем основную текстуру для этого предмета через ключ layer0. Ссылка rinova:item/pinkylite_crystal указывает на файл текстуры, который расположен в папке assets/rinova/textures/item/. 
3.4. Создание перевода предмету
В папке lang создаём два файла:
• en_us.json - Базовый язык - английский, без него не будет переводов на другие языки)
• ru_ru.json - Русский язык, автоматически предмет переводится, когда ставим в майнкрафте из списка языков "Русский язык"
В этом файле будет находиться название предмета для отображения в игре. Местоположение файлов:
Как создавать перевод предметам:
item - предмет
rinova - айди мода
pinkylite_crystal - айди предмета.
Через двоеточие в ковычках указываем название. Не ошибитесь в знаках!
Русский язык точно такая же запись, но уже другой язык.
4. Добавление предмета в ванильную креативную вкладку
Чтобы добавить созданный предмет во вкладку ингредиентов Minecraft (или любую другую стандартную вкладку), необходимо выполнить следующие шаги:
4.1. Создание метода addCreative
Для добавления предмета в креативную вкладку используется событие BuildCreativeModeTabContentsEvent. Это событие позволяет модифицировать содержимое вкладок, предоставляемых самой игрой.
4.2. Проверка вкладки
Внутри метода addCreative необходимо:
• Получить ключ текущей вкладки с помощью метода event.getTabKey().
• Сравнить полученный ключ с нужной вкладкой, например, CreativeModeTabs.INGREDIENTS.
4.3. Добавление предмета
Если проверка на соответствие вкладки прошла успешно, добавьте предмет в эту вкладку с помощью метода event.accept().
Примечание: Вместо CreativeModeTabs.INGREDIENTS можно указать любую другую вкладку. Для этого после написания CreativeModeTabs. нажмите точку (.), и среда разработки подскажет доступные варианты вкладок.  
Полная запись выглядит следующим образом:
Необходима так же запись modEventBus.addListener(this::addCreative) там же, где мы регистрировали предметы, чтобы мод заметил изменение.
5. Тестирование
Теперь запускаем игру, для этого справа есть панель и находим runClient:
После заходим в мир, находим нашу вкладку и вуаля, предмет готов
В следующем посте будет написана инструкция как создать свою вкладку креатива!
Весь написанный код:
https://github.com/ringoway/Rinova/pull/2/commits/2f1a9d44f7fbd6f8b5e3b8166928bea9b894a271
Следующая лекция:
Forge Моддинг 1.20.1 — Лекция 4: Собственная творческая вкладка
Subscription levels4

🌱Junior Dev

$3.7 per month
Начало пути в моддинге

Включено:
✅ Базовые лекции по моддингу
✅ Шаблоны и примеры кода (Github)
✅ Приватный Telegram-чат "Сообщество мододелов"
✅ Роль "🌱Junior Dev" в Discord
+ chat

🛠️Middle Dev

$5.4 per month
Практикующий моддер

Включено:
✅ Всё из уровня «Junior Dev»
✅ Продвинутые лекции по моддингу
✅ Роль "🛠️Middle Dev" в Discord
+ chat

🎓Senior Dev

$7.7 per month
Опытный разработчик

Включено:
✅ Всё из уровня «Middle Dev»
✅ Большая благодарность!
✅ В будущем будут расширенные лекции 
✅ Роль "🎓Senior Dev" в Discord
+ chat

🎓Architect Dev

$13.4 per month
Опытный разработчик

Включено:
✅ Всё из уровня «Senior Dev»
✅ Огромная благодарность!
✅ В будущем будут расширенные лекции 
✅ Роль "🎓Architect Dev" в Discord
+ chat
Go up