Minecraft Wiki
Нет описания правки
(разделение, оформление, иллюстрирование)
Строка 1: Строка 1:
{{К разъединению|[[Создание модификаций с помощью Forge/1.7+/Основные уроки|/Основные уроки]], [[Создание модификаций с помощью Forge/1.7+/Дополнительные уроки|/Дополнительные уроки]] <br>а здесь оставить «Подготовку среды» и обзорный список уроков|Большой объём страницы ({{REVISIONSIZE}}).<br>Структура текста допускает разделение.}}
 
 
'''Здесь находятся инструкции по созданию модификаций, работающие для версии 1.7+'''
 
'''Здесь находятся инструкции по созданию модификаций, работающие для версии 1.7+'''
   
Строка 25: Строка 24:
   
 
Выполнение команды займёт какое-то время, после чего должно появиться сообщение рода Build Successful.
 
Выполнение команды займёт какое-то время, после чего должно появиться сообщение рода Build Successful.
  +
  +
[[Файл:Команда setupDecompWorkspace eclipse.png|320px|thumb|center|Пример результата выполнения команды:<br><code>gradlew.bat setupDecompWorkspace eclipse</code>]]
   
 
Если же появляется какая-либо ошибка:
 
Если же появляется какая-либо ошибка:
Строка 34: Строка 35:
   
 
=== Настройка Eclipse ===
 
=== Настройка Eclipse ===
[[Файл:Eclipse после установки.png|250px|thumb|right|Интерфейс Eclipse после правильной установки.]]
 
 
Нужно настроить Eclipse для работы с Minecraft. Первым делом зайдите в него. Он предложит выбрать рабочую директорию (Workspace). Введите туда путь к папке «eclipse» в папке (Путь к папке должен содержать только английские буквы), куда вы распаковали содержимое Forge и поставьте галочку для того чтоб окно больше не появлялось. В примере это «D:\MCModding\eclipse». Если всё прошло успешно, то слева в Eclipse вы увидите раскрывающееся меню Minecraft, а снизу не увидите красных ошибок.
 
Нужно настроить Eclipse для работы с Minecraft. Первым делом зайдите в него. Он предложит выбрать рабочую директорию (Workspace). Введите туда путь к папке «eclipse» в папке (Путь к папке должен содержать только английские буквы), куда вы распаковали содержимое Forge и поставьте галочку для того чтоб окно больше не появлялось. В примере это «D:\MCModding\eclipse». Если всё прошло успешно, то слева в Eclipse вы увидите раскрывающееся меню Minecraft, а снизу не увидите красных ошибок.
  +
[[Файл:Eclipse после установки.png|420px|thumb|center|Интерфейс Eclipse после правильной установки.]]
{{-}}
 
   
 
=== Настройка IntelliJ IDEA ===
 
=== Настройка IntelliJ IDEA ===
После того, как Forge скомпилирован и установлен, Вам необходимо запустить IntelliJ IDEA. В появившемся окне нажимаем 'Import Project' и выбираем в папке «D:\MCModding» файл build.gradle. В появившемся окне вам предложат выбрать способ компиляции (рекомендуется оставить значение Use default gradle wrapper.) В строчке ниже выберите Ваш JAVA_HOME. В пункте «Формат проекта» нужно обязательно выбрать «.ipr (file based)». В противном случае, вам придется подключать все библиотеки и настраивать запуск самостоятельно. После всего этого нажмите OK. Ждите, пока сборка скомпилируется.
+
Если вместо Eclipse Вы решили использовать IntelliJ IDEA, то после того, как Forge скомпилирован и установлен, необходимо запустить IDEA, и в появившемся окне нажать 'Import Project'. После чего выбираем в папке «D:\MCModding» файл build.gradle. В появившемся окне Вам предложат выбрать способ компиляции (рекомендуется оставить значение Use default gradle wrapper.) В строчке ниже выберите Ваш JAVA_HOME. В пункте «Формат проекта» нужно обязательно выбрать «.ipr (file based)». В противном случае, придётся подключать все библиотеки и настраивать запуск самостоятельно. После всего этого нажмите OK. Ждите, пока сборка скомпилируется.
   
 
В случае, если ваша IntelliJ IDEA установлена правильно и она различает формат *.ipr, вы можете просто дважды нажать по файлу <НазваниеПроекта>.ipr в директории вашего MCP. IDEA все сделает за вас.
 
В случае, если ваша IntelliJ IDEA установлена правильно и она различает формат *.ipr, вы можете просто дважды нажать по файлу <НазваниеПроекта>.ipr в директории вашего MCP. IDEA все сделает за вас.
   
Поздравляю! Вы успешно настроили среду для того, чтобы начать писать моды на ней.
+
Поздравляем! Вы успешно настроили среду для того, чтобы начать писать моды на ней.
   
 
== Основные уроки ==
 
== Основные уроки ==
  +
{{Main|Создание модификаций с помощью Forge/1.7+/Основные уроки}}
 
=== Урок 1. Директория Eclipse (Установка среды) ===
+
# [[Создание модификаций с помощью Forge/1.7+/Основные уроки#Урок 1. Директория Eclipse (Установка среды)|Директория Eclipse (Установка среды)]]
  +
# [[Создание модификаций с помощью Forge/1.7+/Основные уроки#Урок 2. Главный класс|Главный класс]]
Теперь вы можете приступать к созданию своего первого мода.
 
  +
# [[Создание модификаций с помощью Forge/1.7+/Основные уроки#Урок 3. Блок|Блок]]
 
  +
# [[Создание модификаций с помощью Forge/1.7+/Основные уроки#Урок 4. Предмет|Предмет]]
Заранее придумайте название своего мода (например, MyBestMod). Перейдём к тому, где должен быть мод в структуре классов Minecraft. Существует некоторый этикет, как оформлять код и всё, что с ним связано. Раскройте проект Minecraft, далее <code>src/main/java</code>. В <code>src/main/java</code> лежит всё, что относится к коду Minecraft. Как вы видите, там есть подпапки (или пакеты) типа net.minecraft.client<ref>В Java директории указываются не слешами, как в Windows, а точками. То есть «net.minecraft.client» — это когда папка «client» лежит в папке «minecraft», которая лежит в папке «net».</ref> и так далее. В Java пакетах принято структурировать пакеты так: <code>domain.product</code> или <code>domain.company.product</code>, то есть первое — домен (com, net, ru), далее название компании (если вы единственный разработчик — ваш ник) и название продукта (мода), или же название компании опускается.<ref>[http://www.oracle.com/technetwork/java/codeconventions-135099.html Документация Oracle]</ref><ref>[[wikipedia:Java package#Package naming conventions|Статья «Java package» на английской Википедии]]</ref> Minecraft, Minecraft Forge и FML имеют первый вариант структурирования пакета. То есть, если ваш никнейм, например, platon, а название вашего мода — My Best Mod, то нажмите на src/main/java {{Кнопка|ПКМ}} и выберите New → package. В поле «Name» наберите «com.platon.mybestmod» с учётом регистра. Это создаст директорию, в которой вы и будете работать с модом. Всё, далее можете приступать непосредственно к его созданию.
 
  +
# [[Создание модификаций с помощью Forge/1.7+/Основные уроки#Урок 5. Крафт|Крафт]]
 
  +
# [[Создание модификаций с помощью Forge/1.7+/Основные уроки#Урок 6. Компиляция|Компиляция]]
=== Урок 2. Главный класс ===
 
  +
# [[Создание модификаций с помощью Forge/1.7+/Основные уроки#Урок 7. Генерация|Генерация]]
Итак, можно приступить к созданию мода. Создадим его основу.
 
  +
# [[Создание модификаций с помощью Forge/1.7+/Основные уроки#Урок 8. Прокси и инстанция|Прокси и инстанция]]
 
  +
# [[Создание модификаций с помощью Forge/1.7+/Основные уроки#Урок 9. Моб|Моб]]
Нажмите {{Кнопка|ПКМ}} на директории мода (com.platon.mybestmod) и выберите New → Class, и в поле Name введите название класса. Это главный класс мода, поэтому пусть это будет указано. Например, одно из возможных названий — «BaseMyBestMod». Обратите внимание, что каждое слово написано с большой буквы (естественно, именно так делать необязательно, но общепринятым считается именно этот вариант). Далее просто нажмите Finish. Всё, у вас теперь есть главный класс мода.
 
 
Приступим к написанию кода. Запишем ВНЕ тела, то есть над строчкой <code>public class... </code><ref>Любое тело в Java обозначается фигурными скобками и обозначает внутренности некоторой подпрограммы. Например, <code>public class BaseMyBestMod {</code>} указывает, что это класс, а в скобках написано, что он делает.</ref> класса следующую строчку:
 
<syntaxhighlight lang="Java">@Mod (modid = "mybestmod", name="My Best Mod", version = "1.0")</syntaxhighlight>
 
 
Вы написали, что ваша модификация называется «My Best Mod» и имеет версию 1.0. Но Eclipse сообщает об ошибке, так как ему неизвестно, что значит @Mod. Нужно импортировать соответствующий класс, для этого после строчки с указанием пакета (<code>package platon.mods.mybestmod;</code>) напишите следующую строчку:
 
<syntaxhighlight lang="Java">import cpw.mods.fml.common.Mod;</syntaxhighlight>
 
После этого сообщение об ошибке должно исчезнуть.
 
 
Далее уже в теле (в фигурных скобках) пишем:
 
 
<syntaxhighlight lang="Java">@EventHandler
 
public void preLoad(FMLPreInitializationEvent event)
 
{
 
 
}</syntaxhighlight>
 
Опять ошибка. Как вы поняли, ему опять не хватает импортированных классов. Почти всегда можно автоматически их импортировать, если Eclipse знает или догадывается, где их искать<ref>В Eclipse встроена функция автоматической организации импортируемых классов ({{Кнопка|Ctrl+Shift+O}}).</ref>.
 
 
Вот и всё. Основа мода готова. Можете запустить Minecraft (Зеленая кнопка сверху → Client) и увидеть в списке модов свой мод. По крайней мере для того, чтобы приступить к созданию первого блока.
 
 
=== Урок 3. Блок ===
 
Приступим к созданию своего первого собственного блока.
 
 
В самом начале тела Класса (После первой фигурной скобки если вы ещё не поняли) пишем:
 
<syntaxhighlight lang="Java">public static Block bestblockever;</syntaxhighlight>
 
 
Public значит, что объект bestblockever (такое кодовое имя мы дали блоку) может быть вызван откуда угодно. Static, что он статичный, а Block значит тип объекта. А вот описание объекта Block надо импортировать, так как в нашем классе этого не указано. Для этого нажмем по ошибке и выберите импорт из net.minecraft.block, а не откуда либо ещё. В случаях с множественными вариантами импорта {{Кнопка|Ctrl-Shift-O}} лучше не нажимать. Всё, ошибка исчезла.
 
 
Теперь укажем, где про блок будет написано более подробно. В теле метода preLoad() напишем строчку:
 
<syntaxhighlight lang="Java">bestblockever = new BlockBestBlockEver();</syntaxhighlight>
 
 
Эта строка говорит, что про объект bestblockever будет написано в классе BlockBestBlockEver. И он выдаёт ошибку. Естественно, ведь никакого класса BlockBestBlockEver не существует. Его легко создать, нажав по ошибке и выбрав Create Class… Далее нажмите Finish.
 
 
Вы перейдете сразу в созданный вами класс. Сразу после названия класса перед фигурной скобкой допишите extends Block. Первую ошибку исправьте, импортировав недостающий класс Block (net.minecraft.block). Вторую ошибку вы видите, потому что созданный класс — наследник класса Block в котором написано что такое блок. И не хватает аргументов которые нужно дать тому классу, чтобы ваш блок был особенным. материал, прочность и т. д. Поэтому просто исправьте ошибку первым способом, он сам её исправит, дописав немного. Строку с двумя слешами, комментарий, можно стереть<ref>В Java если строчка написана после двух слешей, то она воспринимается не как код, а как комментарий. Также можно заключить несколько строк в комментарий, закрыв их в конструкцию <code>/*Закомментированный текст*/</code></ref>.
 
 
В скобках у объекта, где написаны аргументы, которые должны быть посланы снаружи уберите аргумент Material par1Material. Мы пошлем его отсюда, а не снаружи класса. Теперь в следующей строчке в скобках у super() замените «par1Material» на «Material.rock», или после точки сами выберите нужный вам материал.(Не забудьте про импорт) То есть мы посылаем в суперкласс Block что материал блока камень. То есть блок как камень: на звук как камень, ломается с тем же звуком и т. д. Список доступных материалов можно посмотреть через точку после Material.
 
 
Итак, давайте поработаем над характеристиками блока. Это можно сделать из главного класса, указывая их через точку после <code>bestblockever = new BlockBestBlockEver();</code> (до точки с запятой). Но можно и отсюда. Для этого пишите их в теле этого объекта после «this.» «this.» также можно не писать.
 
 
Основные характеристики:
 
 
<syntaxhighlight lang="Java">this.setBlockName("bestblockever");
 
// Без этой строчки у блока не будет внутриигрового (нелокализированного) имени, он просто будет называться «null».
 
 
this.setCreativeTab(CreativeTabs.tabBlock);//
 
// Указывает в какой вкладке будет находиться блок в креативе (доступные также можно посмотреть через точку от CreativeTabs). Не забудьте про импорт.
 
 
this.setHardness(15F);
 
// Устанавливает прочность, то есть как долго блок будет ломаться.
 
 
this.setResistance(10F);
 
// Устанавливает взрывоустойчивость блока.
 
 
this.setHarvestLevel("pickaxe", 3);
 
// Устанавливает, киркой какого уровня можно сломать. Например, алмазная = 3.
 
</syntaxhighlight>
 
 
Также можно установить будет ли блок [[свет]]иться. Чем больше число, тем светлее. Вместо 0 пишете уровень света, создаваемого блоком, умноженное на 10. Таким образом нужно вставить туда значение от 0 до 150 (150 означает уровень света 15, максимальное значение).
 
 
<syntaxhighlight lang="Java">this.setLightLevel(0F);</syntaxhighlight>
 
 
Теперь давайте добавим текстуру блоку. Она может быть любой, но размером 16×16 или 32х32 пикселей. Например можно создать картинку, написать в ней «Б» и уменьшить до 16×16 пикселей и чуть-чуть подредактировать. Можете скачать эту: [[Файл:Пример текстуры(Туториал Forge).png]] Желательно, чтоб название было как у блока, а расширение обязательно .png
 
 
Так, текстура есть, теперь пропишем её в код. Следующее пропишите всё в том же методе блока.
 
<syntaxhighlight lang="Java">this.setBlockTextureName("mybestmod:BlockBestBlockEver");</syntaxhighlight>
 
 
Давайте немного разберемся насчёт «mybestmod:BlockBestBlockEver». Должно быть написано «краткое название мода: название файла», но название без .png. '''ВАЖНО! Для пользователей IntelliJ IDEA''' — ide автоматически склеивает названия папок как ей вздумается, но чтобы работало подключение ресурсов физическая структура папок должна быть строго такой: assets/mymod/textures/blocks — то есть это отдельные папки! Если создавать через New -> Directory и указать «assets.mymod» — она НЕ создаст отдельные подпапки и работать не будет!
 
 
Теперь поместим текстуру в проект. Слева в окне директорий проекта выберите <code>src/main/resources</code> и нажмите правой кнопкой и создайте директорию.(New → package) Назовите так: assets.краткое название мода.textures.blocks (assets.mybestmod.textures.blocks). Теперь мышкой перетяните текстуру из windows в эту директорию. В окне выберите «Copy files».
 
 
Теперь нужно зарегистрировать блок. Перейдите в главный класс и в самом конце метода preLoad допишите
 
<syntaxhighlight lang="Java">GameRegistry.registerBlock(bestblockever, "bestblockever");</syntaxhighlight>
 
 
Это должно зарегистрировать блок в Forge.
 
 
И последнее: мы не указали, как будет называться блок в игре.
 
Локализация описана в [[#Локализация названий в игре|этом]] доп. уроке.
 
 
Ну вот и всё, блок создан. Теперь необходимо проверить его работоспособность. Запускайте Minecraft с вашим модом! Но сначала сохраните оба класса ({{Кнопка|Ctrl-S}}). Для запуска нужно нажать сверху зелёный круг с треугольником (или {{Кнопка|Ctrl-F11}}). После запуска посмотрите, есть ли ваш мод в окне моды (в главном меню), создайте новый мир в режиме креатив и найдите свой блок в креатив-инвентаре во вкладке блоки. Если он там есть, берется, ставится и ломается, то поздравляю: мод, добавляющий блок, создан!
 
 
=== Урок 4. Предмет ===
 
Ну вот мы и создали блок. Но ведь в игре присутствуют не только блоки, но и предметы. Такие как еда, инструменты, в общем всё подряд, что обычно нельзя поставить на землю. Давайте создадим такой предмет. Для примера возьмём кирку.
 
 
Перейдем в главный класс мода. До метода preLoad() сразу после <code>public static Block bestblockever;</code> допишите:
 
<syntaxhighlight lang="Java">public static Item bestpickaxe;</syntaxhighlight>
 
 
Тем самым мы создадим переменную типа Item с кодовым названием кирки.
 
 
В методе preLoad() для удобства отступите одну строку от того что уже написано, и пишите туда следующее: (Я сразу напишу всё, что нужно, многие элементы описания предмета совпадают с описанием блока, особой разницы нет)
 
 
<syntaxhighlight lang="Java">
 
bestpickaxe = new BestPickAxe().setUnlocalizedName("bestpickaxe");
 
GameRegistry.registerItem(bestpickaxe, "bestpickaxe");
 
</syntaxhighlight>
 
 
Итак, мы создали кирку, дали ей нелокализированное имя<ref>С помощью <code>.setUnlocalizedName("bestpickaxe")</code> мы сразу передали методу BestPickAxe информацию, вместо того чтоб в нём писать <code>this.setUnlocalizedName("bestpickaxe")</code> По сути можно все такие аргументы послать через точку.</ref> и зарегистрировали в Forge. Щелкнув по ошибке создадим класс этой кирки. Класс создан, но Eclipse не знает, что мы хотим создать — еду или инструмент, поэтому сделаем этот класс наследником класса, где написано про инструмент или еду или что хотите, главное, что про предмет, а не блок. В строчке <code>public class BestPickAxe{</code> после BestPickAxe допишите <code>extends ItemPickaxe</code> и импортируйте этот самый ItemPickaxe.
 
 
Немного об ItemPickaxe: '''pickaxe''' — это кирка по-английски, и, соответственно, <code>extends ItemPickaxe</code> говорит о том, что мы «продолжаем» или дополняем класс ItemPickaxe, в котором указаны все базовые характеристики и функции, такого Item’а или предмета, как кирка. Таким образом можно продолжать любой класс, в зависимости от того, какой предмет нужен. То есть, если нужна еда, то мы продолжаем класс ItemFood, если броня, то ItemArmor, а если свой особенный предмет, то просто Item. Не забывайте: вы всегда можете посмотреть список возможных продолжений того, что вы пишете.<ref>Когда вы вводите какой-то путь к методу, переменной и т. п. через точку, после ввода точки вы всегда видите возможные продолжения, пользуйтесь этим, чтобы сократить время написания кода, или если не знаете точно, что вам нужно (ориентируйтесь по тому, что посылается в метод и что он возвращает). Если список исчез, всегда, даже когда нет точки, вы можете посмотреть список доступных продолжений, нажав {{Кнопка|Ctrl+Пробел}}</ref>
 
 
Теперь, не обращая внимания на появившуюся ошибку вставьте в тело это:
 
<syntaxhighlight lang="Java">
 
protected BestPickAxe() {
 
super(ToolMaterial.EMERALD);
 
}
 
</syntaxhighlight>
 
 
Тогда ошибка исчезнет. Строка <code>super(ToolMaterial.EMERALD);</code> говорит о том, что пошлёт в супер-класс информацию о том, что кирка обладает свойствами алмазной кирки. Ну и также допишем после этой строчки
 
 
<syntaxhighlight lang="Java">this.setCreativeTab(CreativeTabs.tabTools);</syntaxhighlight>
 
 
тем самым добавив кирку в раздел инструменты в режиме «[[Творчество]]».
 
 
Почти готово. осталось только добавить текстуру, давайте модифицируем текстуру из Minecraft. Зайдите в папку c Minecraft\versions\1.7.2, там откройте jar-файл c помощью архиватора, в архиве перейдите в assets\items и там найдите какую-нибудь текстуру кирки, извлеките на рабочий стол. Файлы текстур НЕЛЬЗЯ редактировать обычным Paint’ом, так как текстура должна быть кое-где прозрачной, если вы не хотите конечно идеально квадратную кирку. В общем отредактируйте текстуру как угодно, главное чтоб была 16×16. Назовите текстуру BestPickAxe.png Теперь создайте в проекте директорию с текстурами предметов. Для этого {{Кнопка|ПКМ}} по src → New → package а в названии напишите <code>assets.mybestmod.textures.items</code> и туда мышью с раб. стола перенесите готовую текстуру и нажмите ОК. Теперь скажем предмету где его текстура. Пропишите следующее всё в том же методе кирки.
 
 
<syntaxhighlight lang="Java">this.setTextureName("mybestmod:BestPickAxe");</syntaxhighlight>
 
 
И можно запускать для проверки.
 
 
Собственно вот мы и создали первый предмет — инструмент — кирку, которая по свойствам, как алмазная. В [[#Свой материал для инструмента|этом]] доп. уроке вы можете посмотреть, как создать инструмент с особыми свойствами.
 
 
=== Урок 5. Крафт ===
 
Если Вы создаёте модификацию исключительно для добавления/удаления рецептов уже существующих вещей, то следует также рассмотреть вариант использования MineTweaker.
 
Собственно, у нас есть блок и предмет. Мы можем их держать в руках, а блок даже ставить. Но а если мы хотим достать их, играя в режиме Выживания? Тогда блок или предмет можно только найти или скрафтить. Добавить крафт очень просто. Предположим, рецепт блока должен быть следующим:
 
 
{{Крафт
 
|A1= Железный слиток |B1= Железный слиток|C1= Железный слиток
 
|A2= Гравий|B2= Обсидиан |C2= Гравий
 
|A3= Железный слиток|B3= Железный слиток|C3= Железный слиток
 
}}
 
 
Тогда я запишу вот это в тело метода preLoad главного класса '''после''' строки регистрации блока в Forge:
 
<syntaxhighlight lang="Java">
 
GameRegistry.addRecipe(new ItemStack(BaseMyBestMod.bestblockever, 1),
 
 
new Object[]{
 
 
"###", "XYX", "###",
 
 
('X'), Blocks.gravel,
 
('#'), Items.iron_ingot,
 
('Y'), Blocks.obsidian
 
 
}
 
 
);
 
</syntaxhighlight>
 
<!-- Не забудьте ничего импортировать. Что? -->
 
 
Давайте разберем, что тут написано: Итак с помощью GameRegistry мы добавляем новый рецепт, new itemStack значит, что создастся новая стопка с предметом bestblockever который объявлен в классе BaseMyBestMod в количестве одной штуки (вместо 1 можно вписать любое число до 64). А далее уже записана сетка крафта. Как мы помним в верстаке мы видим всего 9 клеток, здесь первая строка верстака это «###», вторая строка — это «XYX», ну и последняя — «###». Понятней будет, если посмотреть вот так:
 
"###"
 
"XYX"
 
"###"
 
 
Каждый предмет в крафте обозначается своим личным знаком (любым). Далее это записано как <code>('X'), Blocks.gravel</code> То есть это означает, что X — это гравий, который является блоком. Соответственно знак # — это слиток железа (который является предметом, а не блоком), а Y — это блок обсидиана. Если нужно, чтоб в ячейке крафта ничего не лежало, то вместо знака пишется пробел (Например " # " значит что посередине будет слиток железа, а по бокам ничего).
 
 
Добавить рецепт крафта можно не только вашему блоку или предмету. Можно вписывать вместо <code>BaseMyBestMod.bestblockever</code> или <code>Blocks.obsidian</code> что угодно, главное что бы после точки была указана зарегистрированная переменная типа Block или Item. А до точки — это просто путь к этой переменной.
 
 
Если хотите создать крафт, который можно произвести в инвентаре, вместо «###», «XYX», «###» используйте «AA», «BC» соответственно.
 
 
Бесформенный крафт (то есть крафт, в котором можно располагать ингредиенты как угодно) опишите так:
 
<syntaxhighlight lang="Java">GameRegistry.addShapelessRecipe(new ItemStack(Blocks.grass, 4), new Object[] {Blocks.gravel, Blocks.gravel, Items.arrow});</syntaxhighlight>
 
То есть если вы положите в верстак/инвентарь 2 блока гравия и стрелу, то получите 4 блока Земли, покрытой травой.
 
 
Если у блока/предмета есть несколько видов (например: дубовые, еловые, березовые доски и т. д.), то указав просто например: <code>Blocks.Planks</code> в крафте можно будет использовать любые доски! Что бы это исправить вместо <code>Block.Planks</code> напишем <code>new ItemStack(Blocks.planks, 1, 0)</code>
 
 
Первое число всегда 1. Изменяем только второе число. 0 — это дубовые доски, 1 — еловые доски и т. д. [[Нумерация данных|(см. ID)]]
 
<syntaxhighlight lang="Java">
 
GameRegistry.addRecipe(new ItemStack(MuchBlocks.MyBlockS, 1),
 
new Object[]{ " I ", "IPI", " I ",
 
('I'), Items.iron_ingot, ('P'), new ItemStack(Blocks.planks, 1, 0)}
 
);
 
</syntaxhighlight>
 
 
Так же в игре, как мы знаем, присутствует переплавка одних предметов/блоков в другие. Рецепт такой переплавки создаётся всего одной строкой, которую нужно писать после регистрации блока bestblockever:
 
 
<syntaxhighlight lang="Java">GameRegistry.addSmelting(bestblockever, new ItemStack(Blocks.diamond_block, 2), 1.0F);</syntaxhighlight>
 
 
Но теперь разберём. Итак, первой в скобках указана переменная типа Block (также можно Item), в данном случае это наш блок, затем идет переменная типа ItemStack, которая создаётся сразу же. У этой переменной уточняется, что создастся стак с блоком или предметом, в данном случае алмазным блоком, в количестве 2. Ну и последняя переменная отвечает за количество опыта, получаемого при переплавке.
 
 
Собственно, всё.
 
 
=== Урок 6. Компиляция ===
 
Что же, вы написали мод, он работает, но вы хотите чтобы он работал и просто на Minecraft. Давайте наконец его скомпилируем!
 
 
Компилировать мод очень просто, запустите файл gradlew.bat с командой build. Или другими словами создайте bat-файл (или измените оставшийся) с кодом:
 
gradlew.bat build
 
 
и запустите его. После автоматического закрытия консоли мод скомпилирован и находится в папке build/libs.
 
Если для компиляции мода требуется подключение дополнительных jar библиотек, то необходимо в корневой папке проекта (MCModding) создать папку libs и поместить все необходимые файлы в неё.
 
 
Теперь немного о том, что получилось. У нас есть файл с расширением jar, а в нём наш мод, и собственно, можно кидать его в папку mods и пользоваться, но нужно отметить что в этом jar-архиве есть папка META-INF, которая запрещает что-либо из него удалять (Если что .jar можно открывать любым архиватором). Так же следует обратить внимание на то что компилятор автоматически вставит в архив всё, что вы «напрограммировали» и там будут весь код и все ресурсы от модов над которыми вы работаете. Если для вас это неприемлемо, просто удалите лишние пути из архива (например platon.mods.megamod, если работаете с mybestmod и т. п.). Так же можно со спокойной совестью удалить META-INF и вообще всё разрахивировать и упаковать в zip-архив, он также будет работать.
 
 
Так же немного о build.gradle Вы можете его модифицировать так, чтобы jar-файл автоматически назывался как надо. Откройте его любым текстовым редактором. Вы можете изменить следующие строки, как захотите, например так:
 
version = "1.0"
 
group= "com.platon.mybestmod"
 
archivesBaseName = "My Best Mod"
 
 
Сохраните файл. Таким образом вы получите при компиляции файл My Best Mod-1.0.jar
 
 
=== Урок 7. Генерация ===
 
Теперь мы сделаем так, чтобы теперь какой-либо блок, аналогично рудам, генерировался в обычном мире, в [[Нижний мир|нижнем мире]] или в [[Край|краю]]. Теперь в главном классе (BaseMyBestMod) после регистрации блока в Forge регистрируем новую переменную:
 
 
<syntaxhighlight lang="Java">public static BestBlockGenerator bestblockgenerator = new BestBlockGenerator();</syntaxhighlight>
 
 
и исправляем ошибку, создав нужный класс. Естественно, вместо BestBlockGenerator вы можете использовать любое название. Далее в методе <code>preLoad()</code> в любом месте после регистрации блока, который хотите генерировать, добавьте такой код:
 
<syntaxhighlight lang="Java">GameRegistry.registerWorldGenerator(bestblockgenerator, 0);</syntaxhighlight>
 
 
Тем самым вы зарегистрируете ваш генератор. Число «0» обозначает каким по счёту будет загружаться генератор (0 — первым, 1 — вторым и т. д.).
 
 
Теперь в созданном классе после <code>public class BestBlockGenerator</code> добавьте <code>implements IWorldGenerator</code> и в тело класса добавьте это:
 
 
{{Спойлер|<small><syntaxhighlight lang="Java">
 
@Override
 
public void generate(Random rand, int chunkX, int chunkZ, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider) {
 
 
generateOverworld(rand, chunkX, chunkZ, world);
 
generateNether(rand, chunkX, chunkZ, world);
 
generateEnd(rand, chunkX, chunkZ, world);
 
 
}
 
 
private void generateOverworld(Random rand, int chunkX, int chunkZ, World world) {
 
 
generateOverworld(world, rand, chunkX * 16, chunkZ * 16);
 
 
}
 
 
private void generateNether(Random rand, int chunkX, int chunkZ, World world) {
 
 
generateNether(world, rand, chunkX * 16, chunkZ * 16);
 
 
}
 
 
private void generateEnd(Random rand, int chunkX, int chunkZ, World world) {
 
 
generateEnd(world, rand, chunkX * 16, chunkZ * 16);
 
 
}
 
 
public void generateOverworld(World world, Random rand, int blockXPos, int blockZPos) {
 
 
addOreSpawn(BaseMyBestMod.bestblockever, Blocks.stone, world, rand, blockXPos, blockZPos, 16, 16, 1, 2, 1, 1, 10, 5, 6);
 
 
}
 
 
public void generateNether(World world, Random rand, int blockXPos, int blockZPos) {
 
 
addOreSpawn(BaseMyBestMod.bestblockever, Blocks.netherrack, world, rand, blockXPos, blockZPos, 16, 16, 1, 2, 1, 1, 10, 5, 6);
 
 
}
 
 
public void generateEnd(World world, Random rand, int blockXPos, int blockZPos) {
 
 
addOreSpawn(BaseMyBestMod.bestblockever, Blocks.end_stone, world, rand, blockXPos, blockZPos, 16, 16, 1, 2, 1, 1, 10, 5, 6);
 
 
}
 
 
/**
 
* Добавляет генерацию руды в Minecraft. Просто воспользуйтесь этим методом для регистрации генерируемых руд.
 
 
* @param block Блок, который хотите генерировать
 
* @param block replace Блок, рядом с которым хотите генерировать
 
* @param world Мир (не измерение), в котором этот блок должен генерироваться
 
* @param random Случайное число для получения координат генерации блока
 
* @param blockXPos Число для того, чтобы было пустое место по координатам X для метода генерации (использует кварцевая руда)
 
* @param blockZPos Число для того, чтобы было пустое место по координатам Z для метода генерации (использует кварцевая руда)
 
* @param maxX Число, которое настроит максимальную X координату для генерации руды на оси X на чанк
 
* @param maxZ Число, которое настроит максимальную Z координату для генерации руды на оси Z на чанк
 
* @param minVeinSize Минимальное число блоков руды в одной жиле
 
* @param maxVeinSize Максимальное число блоков руды в одной жиле
 
* @param minVeinsPerChunk Минимальное число жил в чанке
 
* @param maxVeinsPerChunk Максимальное число жил в чанке
 
* @param chancesToSpawn Шанс генерации блоков на чанк в процентах
 
* @param minY Минимальная координата Y на которой руда может сгенерироваться
 
* @param maxY Максимальная координата Y на которой руда может сгенерироваться
 
**/
 
 
public static void addOreSpawn(Block ore, Block replace, World world, Random rand, int blockXPos, int blockZPos, int maxX, int maxZ,
 
int minVeinSize, int maxVeinSize, int minVeinsPerChunk, int maxVeinsPerChunk, int chanceToSpawn, int minY, int maxY) {
 
if (rand.nextInt(101) < (100 - chanceToSpawn)) return;
 
int veins = rand.nextInt(maxVeinsPerChunk - minVeinsPerChunk + 1) + minVeinsPerChunk;
 
for (int i = 0; i < veins; i++) {
 
int posX = blockXPos + rand.nextInt(maxX);
 
int posY = minY + rand.nextInt(maxY - minY);
 
int posZ = blockZPos + rand.nextInt(maxZ);
 
(new WorldGenMinable(ore, minVeinSize + rand.nextInt(maxVeinSize - minVeinSize + 1),
 
replace)).generate(world, rand, posX, posY, posZ);
 
}
 
}
 
</syntaxhighlight></small>}}
 
 
Описание параметров метода addOreSpawn() можно увидеть (чтобы разобраться в них), наведя курсор на его название. Эту информацию мы привязали к методу, благодаря javadoc-комментарию<ref>[[ruwiki:Javadoc|Javadoc-комментарии]] оставляются над методом, классом, переменной и т. д. для того, чтобы описать назначения класса, метода и т. д. Обособляется конструкцией /**Javadoc-комментарий*/</ref>.
 
 
Теперь можно запускать и смотреть результаты.
 
 
<gallery mode="packed">
 
Генерация руды в аду.png
 
Генерация собственносозданной руды.png
 
Генерация руды в крае.png
 
</gallery>
 
 
=== Урок 8. Прокси и инстанция ===
 
Прокси и инстанция (экземпляр) нужны для создания мобов, регистрация собственных рендеров, звуков и др. Для создания инстанции добавьте в главный файл мода следующий код:
 
 
<syntaxhighlight lang="Java">
 
@Instance("mybestmod")
 
public static MyBestMod instance;
 
</syntaxhighlight>
 
 
Также, если вы хотите сократить число импортов, то вместо <code>@Instance</code> сделайте <code>@Mod.Instance</code>, от этого ничего не изменится. '''Инстанция''' — или '''экземпляр''' — это ссылка на ваш мод, которую использует Forge. Если вы не создали её сами, то Forge создаёт её для вас, но в этом случае вы не сможете взаимодействовать с ней, поэтому рекомендовано создать её самому.
 
 
Теперь следует сделать прокси. '''Прокси''' фильтрует контент на то, что должно быть для сервера, а что для клиента. Сервер хранит данные о мире, в то время как клиент рендерит мир. Для создания прокси создайте два класса: ClientProxy для клиента и CommonProxy для сервера. Суперклассом ClientProxy должен быть CommonProxy. Теперь регистрация прокси. Просто добавьте следующий код в главный класс мода:
 
 
<syntaxhighlight lang="Java">
 
@SidedProxy(clientSide = "ваш.пакет.ClientProxy", serverSide = "ваш.пакет.CommonProxy")
 
public static CommonProxy proxy;
 
</syntaxhighlight>
 
 
Прокси и инстанция готовы.
 
 
=== Урок 9. Моб ===
 
Можно приступать к созданию [[моб]]а. В примере будет создание враждебного моба, со скином игрока. Начните с главного файла мода. Для удобства регистрации мобов, в примере будет создан отдельный метод:
 
 
<syntaxhighlight lang="Java">
 
public static void registerEntity(Class entityClass, String name, int primaryColor, int secondaryColor)
 
{
 
int entityID = EntityRegistry.findGlobalUniqueEntityId();
 
long seed = name.hashCode();
 
 
EntityRegistry.registerGlobalEntityID(entityClass, name, entityID);
 
EntityRegistry.registerModEntity(entityClass, name, entityID, instance, 64, 1, true); //эта строка не нужна(зачем она?)
 
EntityList.entityEggs.put(Integer.valueOf(entityID), new EntityList.EntityEggInfo(entityID, primaryColor, secondaryColor));
 
}
 
</syntaxhighlight>
 
 
Цвета для [[Яйца призывания|яиц призывания]] вы можете посмотреть [[ruwiki:Википедия:Таблица цветов|здесь]], только когда выберете цвет, замените «#» на «0x». Переменная <code>primaryColor</code> назначает цвет фона яйца, а переменная <code>secondaryColor</code> за цвет пупырышек.
 
 
Теперь в метод preLoad добавьте следующий код:
 
 
<syntaxhighlight lang="Java">registerEntity(MyBestEntity.class, "myBestEntity", 0x00FFFF, 0x00008B);</syntaxhighlight>
 
 
Разбор:
 
{| class = "wikitable" style="text-aligh:center"
 
!Параметр
 
!Описание
 
|-
 
|MyBestEntity.class
 
|Класс моба.
 
|-
 
|«myBestEntity»
 
|ID моба
 
|-
 
|0x00FFFF
 
|Цвет фона яйца
 
|-
 
|0x00008B
 
|Цвет пупырышек яйца.
 
|}
 
Теперь создайте класс моба и добавьте туда следующий код:
 
 
<syntaxhighlight lang="Java">
 
public class MyBestEntity extends EntityMob
 
{
 
public EntityTest(World par1World)
 
{
 
super(par1World);
 
}
 
}
 
</syntaxhighlight>
 
 
В примере суперклассом класса моба является класс «EntityMob», предназначенный для враждебных мобов. Также существуют классы «EntityCreature», «EntityAnimal», «EntityLiving» и другие.
 
 
Теперь модель, текстура и рендер. В класс CommonProxy добавьте следующий код:
 
 
<syntaxhighlight lang="Java">
 
public void registerRenderers()
 
{
 
// Здесь ничего, так как сервер не рендерит графику или существ!
 
}
 
</syntaxhighlight>
 
 
Далее в класс ClientProxy добавьте следующий код:
 
 
<syntaxhighlight lang="Java">
 
@Override
 
public void registerRenderers()
 
{
 
RenderingRegistry.registerEntityRenderingHandler(MyBestEnity.class, new RenderMyBestEntity(new ModelBiped(), 0.5F));
 
}
 
</syntaxhighlight>
 
 
* Метод <code>registerEntityRenderingHandler</code> говорит Minecraft, как рендерить существо.
 
* <code>MyBestEntity.class</code> — класс моба.
 
* <code>RenderMyBestEntity</code> — класс рендера моба, который использует модель <code>ModelBiped</code>.
 
* <code>ModelBiped</code> — базовая модель игрока.
 
* <code>0.5F</code> — размер тени.
 
 
Теперь надо вызвать созданный метод в главном файле мода. Просто добавьте этот код:
 
 
<syntaxhighlight lang="Java">proxy.registerRenderers();</syntaxhighlight>
 
 
Далее создайте класс RenderВашМоб. В нашем случае это «RenderMyBestEntity». Его суперклассом должен быть класс «RenderBiped». В класс добавьте следующий код:
 
 
<syntaxhighlight lang="Java">
 
private static final ResourceLocation textureLocation = new ResourceLocation("textures/entity/steve.png");
 
 
public RenderTest(ModelBiped model, float shadowSize)
 
{
 
super(model, shadowSize);
 
}
 
 
@Override
 
protected ResourceLocation getEntityTexture(Entity par1Entity)
 
{
 
return textureLocation;
 
}
 
</syntaxhighlight>
 
 
Вместо <code>textures/entity/steve.png</code> поставьте <code>"IDмода:textures/entity/вашМоб.png"</code>, то есть в примере будет <code>"MyBestMod:textures/entity/myBestEntity.png"</code>. После этого в папке <code>assests/idмода/textures</code> создайте папку <code>entity</code> и туда скопируйте текстуру моба.
 
 
Для локализации яйца моба добавьте в файл локализации следующий код:
 
 
<syntaxhighlight lang="Java">entity.myBestEntity.name=My Best Entity</syntaxhighlight>
 
 
Теперь зайдите в игру. Во вкладке «Разное» будет яйцо.
 
 
Моб закончен.
 
   
 
== Дополнительные уроки ==
 
== Дополнительные уроки ==
  +
{{Main|Создание модификаций с помощью Forge/1.7+/Дополнительные уроки}}
 
=== Локализация названий в игре ===
+
# [[Создание модификаций с помощью Forge/1.7+/Дополнительные уроки#Локализация названий в игре|Локализация названий в игре]]
  +
# [[Создание модификаций с помощью Forge/1.7+/Дополнительные уроки#Дроп определённого предмета при разрушении блока|Дроп определённого предмета при разрушении блока]]
Собственно у нас есть некоторые предметы, блоки, а возможно даже кнопки, существа и надписи из нашего мода, называющиеся в инвентаре примерно так: <code>item.block.name</code> Естественно это нас не устраивает, и это можно исправить, даже не внося изменений в код!
 
  +
# [[Создание модификаций с помощью Forge/1.7+/Дополнительные уроки#Разносторонняя текстура блока|Разносторонняя текстура блока]]
 
  +
# [[Создание модификаций с помощью Forge/1.7+/Дополнительные уроки#Собственная вкладка в Творческом режиме|Собственная вкладка в Творческом режиме]]
Итак, приступим. Слева, в <code>src/main/resources</code> создайте пакет <code>assets.mybestmod.lang</code> Понятно, что mybestmod — это краткое имя мода(или modid), указанное в @Mod. Теперь где угодно создайте файл(создайте текстовой, а затем измените расширение) en_US.lang (где будут написаны английские название блоков, предметов и т. д.) и пропишите в нём то, что вы видите вместо названия в инвентаре (в случае нашего первого блока — tile.bestblockever.name), затем равно, и прямо за ним — ваше локализированное название, например: «Best Block EvAR!». То есть должно получиться:
 
  +
# [[Создание модификаций с помощью Forge/1.7+/Дополнительные уроки#Обновление Forge|Обновление Forge]]
<syntaxhighlight lang="Java">tile.bestblockever.name=Best Block EvAR!</syntaxhighlight>
 
  +
# [[Создание модификаций с помощью Forge/1.7+/Дополнительные уроки#Обновление ForgeGradle|Обновление ForgeGradle]]
 
  +
# [[Создание модификаций с помощью Forge/1.7+/Дополнительные уроки#Свой материал для инструмента|Свой материал для инструмента]]
Теперь скопируйте файл, и назовите копию ru_RU.lang (собственно русский перевод). Внутри него измените название на русское, например
 
  +
# [[Создание модификаций с помощью Forge/1.7+/Дополнительные уроки#Создание брони|Создание брони]]
<syntaxhighlight lang="Java">tile.bestblockever.name=Самый лучший блок!! =P</syntaxhighlight>
 
  +
# [[Создание модификаций с помощью Forge/1.7+/Дополнительные уроки#Свой материал для брони|Свой материал для брони]]
Теперь оба этих файла можете перетащить в заранее созданную <code>assets.mybestmod.lang</code> При переносе выберите Copy files.
 
  +
# [[Создание модификаций с помощью Forge/1.7+/Дополнительные уроки#Генерация предметов в контейнерах натуральных структур|Генерация предметов в контейнерах натуральных структур]]
 
  +
# [[Создание модификаций с помощью Forge/1.7+/Дополнительные уроки#Атрибуты для моба|Атрибуты для моба]]
Чтобы локализировать вкладки в режиме творчество добавьте такой код:
 
  +
# [[Создание модификаций с помощью Forge/1.7+/Дополнительные уроки#Интеллект для моба|Интеллект для моба]]
<syntaxhighlight lang="Java">itemGroup.tabTutorial=Локализированое имя</syntaxhighlight>
 
  +
# [[Создание модификаций с помощью Forge/1.7+/Дополнительные уроки#Свой скин при моддинге|Свой скин при моддинге]]
 
<code>tabTutorial</code> — Название вашей вкладки
 
 
Вот и всё! Локализация завершена, теперь в игре будут отображаться выбранные вами названия.
 
 
Подобных названий можно вписывать сколько угодно, главное в столбик.
 
 
Скорее всего в игре русское название будет выглядеть вопросами! Это всё из-за кодировки. Исправить это можно зайдя в eclipse вкладку window\preferences\general и просто нажмите на workspace и внизу найдите text file encoding и поставьте на other и там выберите UTF-8. Всё! теперь у нас нормальный русский язык!
 
 
=== Дроп определённого предмета при разрушении блока ===
 
Всё очень просто. В конец класса созданного вами блока (перед последней фигурной скобкой) вставьте это:
 
<syntaxhighlight lang="Java">
 
@Override
 
public Item getItemDropped(int par1, Random par2Random, int par3)
 
{
 
return Items.diamond;
 
}
 
</syntaxhighlight>
 
 
То есть теперь при разрушении вашего блока из него выпадет алмаз. Вы можете написать, чтоб выпадало что угодно. Просто вместо
 
<code>return Items.diamond;</code> напишите «<code>return Items.getItemFromBlock(Blocks.);</code>» (для блоков) или «<code>return Items.;</code>» (для предметов), а после ввода вами точки выпадет список возможных предметов или блоков.
 
 
Если хотите, чтоб выпадал не один предмет, а несколько, просто вставьте сразу после предыдущих строк
 
<syntaxhighlight lang="Java">
 
@Override
 
public int quantityDropped(Random par1Random)
 
{
 
return 20;
 
}
 
</syntaxhighlight>
 
 
Тогда при разрушении выпадет 20 выбранных вами предметов или блоков.
 
Всё очень легко и просто!
 
 
=== Разносторонняя текстура блока ===
 
Я буду использовать следующие текстуры:
 
[[Файл:Нижняя часть блока.jpg|Нижняя сторона]] [[Файл:Верхняя часть блока.jpg|Верхняя сторона]] [[Файл:Северная часть блока.jpg|Северная часть]] [[Файл:Южная часть блока.jpg|Южная часть]] [[Файл:Западная часть блока.jpg|Западная часть]] [[Файл:Восточная часть блока.jpg|Восточная часть]]
 
 
Для этого, добавьте такой код в тело класса:
 
 
<syntaxhighlight lang="Java">public IIcon[] icons = new IIcon[6];</syntaxhighlight>
 
 
И такой после конструктора класса:
 
 
<syntaxhighlight lang="Java">
 
@Override
 
public void registerBlockIcons(IIconRegister reg) {
 
for (int i = 0; i < 6; i ++) {
 
this.icons[i] = reg.registerIcon(this.textureName + "_" + i);
 
}
 
}
 
</syntaxhighlight>
 
 
Теперь в папку <code>assets/ID мода/resources/textures/blocks/</code> добавьте файлы с таким именем: <code><То, что вы указали в скобках в конструкторе класса, в методе this.setBlockTextureName()>_<код стороны блока></code>
 
 
И ещё такой код:
 
<syntaxhighlight lang="Java">
 
@Override
 
public IIcon getIcon(int side, int meta) {
 
return this.icons[side];
 
}
 
</syntaxhighlight>
 
 
В игре блок будет выглядеть так:
 
 
<gallery mode="packed">
 
Блок с разностороней текстурой в игре.jpg
 
Блок с Разносторонней текстурой (Вид сзади).jpg
 
</gallery>
 
 
Важно то, что текстура северной и восточной (2 и 5) части блока отображается зеркально. Если вы не поняли, то поставьте [[ТНТ|блок ТНТ]] и посмотрите на части, где написано TNT. С одной стороны написано «TNT», а с другой — «ТИТ».
 
 
=== Собственная вкладка в Творческом режиме ===
 
Для этого добавьте такой код в тело класса:
 
 
<syntaxhighlight lang="Java">public static CreativeTabs tabTutorial = new TabTutorial("ModID");</syntaxhighlight>
 
 
«ModID» заменяем на любое число. Рекомендую ID больше 11 (12 ID сразу на следующей странице творческого инвентаря).
 
 
Потом создайте класс TutorialTab. Если всё правильно, то ваш класс будет иметь <code>extends CreativeTabs</code> до первой фигурной скобки. Теперь добавьте этот метод в ново-созданный класс:
 
 
<syntaxhighlight lang="Java">
 
public TabTutorial(String lable) {
 
super(lable);
 
}
 
 
@Override
 
public Item getTabIconItem()
 
{
 
return Item.getItemFromBlock(Blocks.grass);
 
}
 
</syntaxhighlight>
 
 
Теперь заходите в игру. Вы увидите свою вкладку во втором списке вкладок, её «символом» будет блок [[Трава|травы]]. Если вам хочется, чтобы «символом» был предмет, то вместо <code>Blocks.</code> напишите <code>Items.предмет</code> . Если вы хотите, чтобы «символом» был ваш блок или предмет, то напишите <code>BestMod.bestBlockEver</code> . <code>BestMod</code> — главный файл вашего мода. <code>bestBlockEver</code> — ваш блок/предмет.
 
 
Для того что бы добавить что либо из вашего мода в собственную вкладку пишем:
 
<syntaxhighlight lang="Java">this.setCreativeTab(НазваниеГлавногоКласса.НазваниеВашейВкладки);</syntaxhighlight>
 
[[Файл:Собственная вкладка в креативе.png|150px|right]]
 
 
=== Обновление Forge ===
 
Чтобы обновить версию Forge, на который вы создаёте моды, необязательно всё перекачивать.
 
 
Достаточно просто изменить build.gradle Так что если хотите обновить Forge откройте его любым редактором и найдите строчку
 
version = "1.7.2-10.12.0.998"
 
Там будет написана версия Forge, которая у вас сейчас, соответственно вам нужно всего лишь изменить значение на новое. Измените его на версию, до которой хотите обновить Forge (например на 1.7.2-10.12.0.1012) и сохраните файл. Далее запустите gradlew.bat с командой eclipse (то есть запустить bat-файл с кодом <code>gradlew.bat eclipse</code>) и после завершения его работы ваша версия Forge обновлена!
 
 
=== Обновление ForgeGradle ===
 
Forge отделён от ForgeGradle, поэтому если вы попытаетесь обновиться на версию Forge, которая использует более новой ForgeGradle, вы получите ошибки. Вот таблица версия Forge, и какие версии ForgeGradle он использует.
 
{| class="wikitable"
 
! ForgeGradle
 
! Forge
 
|-
 
| - || 959<, 965
 
|-
 
| 1.0 || 960-964
 
|-
 
| 1.1 || 967-1047
 
|-
 
| 1.2 || 1048+
 
|}
 
Удалите папку '''.gradle''', которая находится в папке, куда вы разархивировали Forge.
 
Теперь, откройте файл '''build.gradle''' (который находится там же). Найдите такую строку:
 
 
<syntaxhighlight lang="Java">
 
dependencies {
 
classpath 'net.minecraftforge.gradle:ForgeGradle:1.x-SNAPSHOT'
 
}
 
</syntaxhighlight>
 
 
В '''1.x-SNAPSHOT''', поменяйте '''1.x''' на нужную версию ForgeGradle. Сохраните файл и откройте командную строку. Повторно введите команды, которые вы использовали при установке Forge. ForgeGradle обновит все нужные файлы.
 
 
=== Свой материал для инструмента ===
 
Допустим вы хотите, чтобы ваш инструмент обладал свойствами не железной/алмазной кирок из майнкрафта, а собственными.
 
 
Тогда где-нибудь(вы можете где угодно написать эту строку, главное, чтоб можно было вызвать.), например в главном классе вне каких либо методов (то есть можно перед последней фигурной скобкой) напишите:
 
public static final ToolMaterial NEWMAT = EnumHelper.addToolMaterial("NEWMAT", 2, 564, 5.0F, 4.0F, 50);
 
Не забудьте про импорт. Давайте разберемся: static означает, что переменная NEWMAT типа ToolMaterial доступна из других классов. Затем приравнивается значению, которое и даст вашей кирке определённые свойства. Теперь об аргументах, перечисленных через запятую:
 
# Название материала
 
# На сколько кирка крута от 0 до 3, то есть какие блоки может ломать(1 — эквивалент каменной, 3 — алмазной).
 
# Максимальное количество сломанных блоков (у алмазной — 1561, каменной — 131).
 
# Скорость добычи (у золотой — 12, у алмазной — 8, деревянной — 2).
 
# Урон, наносимый существам (у деревянной/золотой — 0, железной — 2, алмазной — 3).
 
# Зачаровываемость, то есть какой шанс хороших чар (у золотой — 22, алмазной — 10, железной — 14).
 
 
Теперь можно придать какому-нибудь инструменту эти свойства, для этого в инструменте (например в нашей кирке) измените <code>super(ToolMaterial.EMERALD);</code> на <code>super(BaseMyBestMod.NEWMAT);</code> В таком случае вы отправляете в супер-класс инструмента информацию о том, что свойства описаны переменной NEWMAT типа ToolMaterial, которая описана в классе BaseMyBestMod (или любой другой класс, где она написана).
 
 
Вот и всё, свойства инструмента изменены.
 
 
=== Создание брони ===
 
Создание брони немного отличается от создания обычных предметов, точнее имеет свои особенности. Приступим.
 
 
Мы не будем создавать для каждого предмета свой отдельный класс, а создадим один универсальный, который опишет сразу шлем, нагрудник, штаны и ботинки.
 
Начнём с регистрации переменных.
 
<syntaxhighlight lang="Java">
 
public static Item bestarmorhelmet;
 
public static Item bestarmorplate;
 
public static Item bestarmorpants;
 
public static Item bestarmorboots;
 
</syntaxhighlight>
 
 
Шлем, нагрудник, штаны и ботинки соответственно. Теперь описываем эти переменные с помощью универсального класса. Естественно внутри метода preLoad()
 
<syntaxhighlight lang="Java">
 
bestarmorhelmet = new BestArmor(0, 0).setUnlocalizedName("bestarmorhelmet").setTextureName("mybestmod:BestArmorHelmet");
 
bestarmorplate = new BestArmor(0, 1).setUnlocalizedName("bestarmorplate").setTextureName("mybestmod:BestArmorPlate");
 
bestarmorpants = new BestArmor(0, 2).setUnlocalizedName("bestarmorpants").setTextureName("mybestmod:BestArmorPants");
 
bestarmorboots = new BestArmor(0, 3).setUnlocalizedName("bestarmorboots").setTextureName("mybestmod:BestArmorBoots");
 
</syntaxhighlight>
 
 
Здесь, вроде, всё знакомо, мы даём нелокализированное имя каждому из предметов, а также текстуру. Но здесь мы посылаем ещё и две цифры в метод BestArmor. Вторая цифра отвечает за тип брони (0 — шлем, 3 — ботинки), назначение первой неясно, но в данном случае она роли не играет. Далее тоже ничего нового, просто зарегистрируем эти предметы в Forge. Сделать это нужно после описания переменных.
 
<syntaxhighlight lang="Java">
 
GameRegistry.registerItem(bestarmorhelmet, "bestarmorhelmet");
 
GameRegistry.registerItem(bestarmorplate, "bestarmorplate");
 
GameRegistry.registerItem(bestarmorpants, "bestarmorpants");
 
GameRegistry.registerItem(bestarmorboots, "bestarmorboots");
 
</syntaxhighlight>
 
 
С главным классом работа окончена.
 
 
Теперь щелкаем по одной из ошибок и создаём новый класс BestArmor. Теперь «продолжаем» класс ItemArmor, то есть пишем <code>extends ItemArmor</code> после названия класса. Теперь в тело класса вставляем следующее:
 
 
<syntaxhighlight lang="Java">
 
private String texturePath = "mybestmod:textures/model/armor/";
 
 
public BestArmor(int id, int armorType) {
 
super(ArmorMaterial.DIAMOND, id, armorType);
 
this.setCreativeTab(CreativeTabs.tabCombat);
 
this.setMaxStackSize(1);
 
this.setTextureName();
 
}
 
 
public void setTextureName ()
 
{
 
if(armorType == 0||armorType == 1||armorType == 3){
 
this.texturePath += "MyBestArmor_" + 1 + ".png";
 
}
 
else {
 
this.texturePath += "MyBestArmor_" + 2 + ".png";
 
}
 
}
 
 
@Override
 
public String getArmorTexture(ItemStack itemstack, Entity entity, int slot, String type){
 
return this.texturePath;
 
}
 
</syntaxhighlight>
 
 
Что ж, давайте разбираться.
 
 
Первая переменная, просто обозначает начало пути к текстуре брони. Все нужные текстуры можно спокойно извлечь из майнкрафта и отредактировать по желанию. Вот мои отредактированные текстуры:
 
 
[[Файл:MyBestArmor_1.png]] [[Файл:MyBestArmor_2.png]] [[Файл:BestArmorHelmet.png]] [[Файл:BestArmorPlate.png]] [[Файл:BestArmorPants.png]] [[Файл:BestArmorBoots.png]]
 
 
Текстуры предметов помещаются туда же, где и текстура кирки. А вот две текстуры самой брони нужно поместить в другую папку. Поэтому создайте её: нажмите ПКМ по <code>src/main/resources</code> и выберите New — Package и назовите его <code>assets.mybestmod.textures.model.armor</code> и уже туда перетащите две оставшиеся текстуры.
 
 
Давайте дальше разбираться с кодом: следующим идёт метод BestArmor(), в который мы посылаем из главного класса параметры id и armorType. Напомню: от armorType зависит, какая это часть брони. В нём мы посылаем информацию о том, какой материал брони. Я написал, что броня будет аналогична алмазной, но можно создать [[#Свой материал для брони|свой материал для брони]] и вписать его. Далее мы настраиваем вкладку в креативе. Потом мы ограничиваем максимальное количество данного предмета в одной стопке до одного, чтобы броня не «стакалась». В конце концов мы вызываем созданный нами метод setTextureName()
 
 
В этом нашем собственном методе происходит проверка, какая часть брони вызвала этот класс. И, если это был шлем, нагрудник или ботинки, то используется первая текстура, а если поножи, то вторая. Мы прибавляем к изначальному пути брони нужное окончание, чтобы в определённом случае грузилась одна текстура, а в другом — вторая.
 
 
Последний же метод перезаписывает метод супер-класса и указывает Майнкрафту, что должна грузиться текстура по пути texturePath, который предварительно был отредактирован во втором методе.
 
 
Теперь можно запускать игру и убивать мобов в новых блестящих доспехах!
 
 
=== Свой материал для брони ===
 
Почти не отличается от создания собственного материала для инструмента.
 
 
В главном классе в любом месте, но вне каких-либо методов пишем:
 
static ArmorMaterial BESTMAT = EnumHelper.addArmorMaterial("BESTMAT", 100, new int[] {3, 8, 6, 3}, 30);
 
Затем импортируем ArmorMaterial. Теперь разберём:
 
# BESTMAT — название материала.
 
# 100 — прочность (железо — 15, алмазы — 33).
 
# 3 — защита шлема.
 
# 8 — защита нагрудника.
 
# 6 — защита штанов.
 
# 3 — защита ботинок.
 
# 30 — зачаровываемость.
 
 
Вот и все. Теперь можно использовать этот материал для брони, например заменив <code>ArmorMaterial.DIAMOND</code> на <code>BaseMyBestMod.BESTMAT</code>
 
 
=== Генерация предметов в контейнерах натуральных структур ===
 
Итак, вы можете сделать так, чтобы ваш, или любой другой предмет/блок генерировался в сундуках сокровищницы. Для этого в методе preLoad() в главном классе вставьте следующее:
 
<syntaxhighlight lang="Java">
 
ChestGenHooks.addItem(ChestGenHooks.DUNGEON_CHEST,
 
new WeightedRandomChestContent(new ItemStack(BaseMyBestMod.bestblockever), 1, 10, 3));
 
</syntaxhighlight>
 
Разберемся в параметрах:
 
# <code>(ChestGenHooks.DUNGEON_CHEST)</code> — Вместо <code>DUNGEON_CHEST</code> выберете одно из возможных мест генерации в выпадающем списке.
 
# <code>(BaseMyBestMod.bestblockever)</code> — Требуемый блок/предмет. В скобках указывается любая переменная типа Block или Item.
 
# <code>(1)</code> — Минимальное генерируемое количество.
 
# <code>(10)</code> — Максимальное генерируемое количество.
 
# <code>(3)</code> — Шанс генерации.
 
 
=== Атрибуты для моба ===
 
Если вы уже проверили моба, то заметили, что он двигается очень медленно. Чтобы исправить это и изменить атрибуты для моба, добавьте в его класс следующий код: <br>
 
<syntaxhighlight lang="Java">
 
@Override
 
protected void applyEntityAttributes()
 
{
 
super.applyEntityAttributes();
 
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(20.0D);
 
this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(32.0D);
 
this.getEntityAttribute(SharedMonsterAttributes.knockbackResistance).setBaseValue(0.0D);
 
this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.25D);
 
this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(2.0D);
 
}
 
</syntaxhighlight>
 
 
Разъяснение:
 
{| class = "wikitable" style="text-aligh:left"
 
!Параметр
 
!Описание
 
|-
 
|maxHealth
 
|Максимальное здоровье
 
|-
 
|followRange
 
|Дистанция, на которой моб будет преследовать кого-либо
 
|-
 
|knockbackResistance
 
|Сопротивление к отбрасыванию
 
|-
 
|movementSpeed
 
|Скорость движения
 
|-
 
|attackDamage
 
|Сила атаки
 
|}
 
Атрибуты установлены.
 
 
=== Интеллект для моба ===
 
Теперь моб будет просто двигаться, но ничего не делать. Для того, чтобы добавить ему интеллект создайте в класс моба следующий код:
 
 
<syntaxhighlight lang="Java">
 
public boolean isAIEnabled()
 
{
 
return true;
 
}
 
</syntaxhighlight>
 
 
Теперь в конструктор класса добавьте следующий код:
 
<syntaxhighlight lang="Java">
 
this.tasks.addTask(1, new EntityAISwimming(this));
 
this.tasks.addTask(2, new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.2D, false));
 
this.tasks.addTask(3, new EntityAIWander(this, 1.0D));
 
this.tasks.addTask(4, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));
 
this.tasks.addTask(5, new EntityAILookIdle(this));
 
 
this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false));
 
this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true));
 
</syntaxhighlight>
 
 
Первый аргумент метода «addTask» — приоритет назначения интеллекта, второй — сам интеллект. В примере используются следующие интеллекты: «Swimming», «AttackOnCollid», «Wander», «WatchClosest», «LookIdle», «HurtByTarget» и «NearestAttackableTarget». Разъяснение:
 
 
{| class = "wikitable" style="text-aligh:left"
 
!Интеллект
 
!Описание
 
|-
 
|Swimming
 
|Может ли существо плавать?
 
|-
 
|AttackOnCollid
 
|Базовый тип атаки, который используют [[зомби]] и [[паук]]и.
 
|-
 
|Wander
 
|Существо будет ходить вокруг, когда никого не атакует.
 
|-
 
|WatchClosest
 
|Ищет назначенное существо на заданном расстоянии.
 
|-
 
|LookIdle
 
|Существо будет осматриваться, просто стоя.
 
|-
 
|HurtByTarget
 
|Сделает целью какого-либо моба, который его ударил.
 
|-
 
|NearestAttackableTarget
 
|Ищет любое существо, которое подходит по второму параметру.
 
|}
 
 
Интеллект установлен.
 
 
=== Свой скин при моддинге ===
 
'''Внимание!''' Этот способ работает только на лицензионной версии Minecraft.
 
 
Чтобы при создании мода вы видели свой скин, вместо стандартного скина Steve, нужно прописать 2 строчки в аргументы запуска.
 
 
<syntaxhighlight lang="Java">
 
--username=ВашЛогин
 
--password=ВашПароль
 
</syntaxhighlight>
 
После этого, при заходе в игру вы будете видеть свой скин.
 
   
 
== Примечания ==
 
== Примечания ==

Версия от 18:52, 13 июня 2019

Здесь находятся инструкции по созданию модификаций, работающие для версии 1.7+

Подготовка среды и настройка

Сначала подготовим среду для работы с кодом Minecraft.

Forge

Собственно, для создания модов нужен Forge. Скачать его можно здесь с пометкой Mdk или с пометкой Src (для версий 1.8/1.7). Теперь создайте любую папку там, где вам удобно (в примере это «D:\MCModding»), в ней будет находиться Forge и мод. В эту папку распакуйте содержимое архива с Forge. Вы увидите следующее:

Распакованное содержание Forge

Среда разработки

Теперь нам нужно установить Forge, который при установке также произведёт декомпиляцию и деобфускацию кода Minecraft, чтобы сразу можно было начать создание модов. Для этого необходимо установить Java Development Kit (JDK), скачав с официального сайта Oracle.

Затем необходимо выполнить одну из следующих команд (замените eclipse на idea, если вы используете IntelliJ IDEA):

  • gradlew.bat setupDecompWorkspace eclipse или
  • gradlew.bat setupDevWorkspace eclipse

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

Если вы являетесь пользователем операционной системы Linux, нужно прописать следующие строки в терминале:

  • cd <путь>/<папка с Forge> и
  • ./gradlew setupDecompWorkspace eclipse --refresh-dependencies

Чтобы выполнить команду, можно создать в папке .bat-файл с выбранной вами командой (но обычно он там уже есть) и запустить его. Также вместо всего этого можно запустить командную строку в этой папке (например, нажать ⇧ Shift + ПКМ по этой папке и выбрать «Открыть окно команд») и выполнить выбранную команду.

Выполнение команды займёт какое-то время, после чего должно появиться сообщение рода Build Successful.

Команда setupDecompWorkspace eclipse

Пример результата выполнения команды:
gradlew.bat setupDecompWorkspace eclipse

Если же появляется какая-либо ошибка:

  • Проверьте, чтобы у вас в ⊞ Win + PauseBreak->Дополнительные параметры->Переменные среды: в JAVA_HOME указан путь к папке c JDK (по-умолчанию: «C:\Program Files\Java\jdk1.7.0_79») и в Path был указан путь к bin-папке JDK после точки с запятой (по-умолчанию: «…;C:\Program Files\Java\jdk1.7.0_79\bin»).
  • Включите VPN, так как в редких случаях ссылки, необходимые скрипту, могут быть недоступны.
  • Установите Java другой версии, не удаляя предыдущую.
  • Установите другую версию JDK, не забыв, соответственно, поменять пути JAVA_HOME и Path.

Настройка Eclipse

Нужно настроить Eclipse для работы с Minecraft. Первым делом зайдите в него. Он предложит выбрать рабочую директорию (Workspace). Введите туда путь к папке «eclipse» в папке (Путь к папке должен содержать только английские буквы), куда вы распаковали содержимое Forge и поставьте галочку для того чтоб окно больше не появлялось. В примере это «D:\MCModding\eclipse». Если всё прошло успешно, то слева в Eclipse вы увидите раскрывающееся меню Minecraft, а снизу не увидите красных ошибок.

Eclipse после установки

Интерфейс Eclipse после правильной установки.

Настройка IntelliJ IDEA

Если вместо Eclipse Вы решили использовать IntelliJ IDEA, то после того, как Forge скомпилирован и установлен, необходимо запустить IDEA, и в появившемся окне нажать 'Import Project'. После чего выбираем в папке «D:\MCModding» файл build.gradle. В появившемся окне Вам предложат выбрать способ компиляции (рекомендуется оставить значение Use default gradle wrapper.) В строчке ниже выберите Ваш JAVA_HOME. В пункте «Формат проекта» нужно обязательно выбрать «.ipr (file based)». В противном случае, придётся подключать все библиотеки и настраивать запуск самостоятельно. После всего этого нажмите OK. Ждите, пока сборка скомпилируется.

В случае, если ваша IntelliJ IDEA установлена правильно и она различает формат *.ipr, вы можете просто дважды нажать по файлу <НазваниеПроекта>.ipr в директории вашего MCP. IDEA все сделает за вас.

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

Основные уроки

  1. Директория Eclipse (Установка среды)
  2. Главный класс
  3. Блок
  4. Предмет
  5. Крафт
  6. Компиляция
  7. Генерация
  8. Прокси и инстанция
  9. Моб

Дополнительные уроки

  1. Локализация названий в игре
  2. Дроп определённого предмета при разрушении блока
  3. Разносторонняя текстура блока
  4. Собственная вкладка в Творческом режиме
  5. Обновление Forge
  6. Обновление ForgeGradle
  7. Свой материал для инструмента
  8. Создание брони
  9. Свой материал для брони
  10. Генерация предметов в контейнерах натуральных структур
  11. Атрибуты для моба
  12. Интеллект для моба
  13. Свой скин при моддинге

Примечания