Что же, у нас существует среда разработки и возможность запускать кубач без необходимости его покупки. Замечательно, не так ли? Значит, пора приступать к работе над собственным шедевром. Я уже делал один достаточно простой мод(вот ссылка на него кстати, кому нужно), однако для туториала я пожалуй запилю новый. В планах добавить дополнительное измерение и генерацию структур. Заодно и с гитхабом попробую разобраться.
Первым делом, в левой части окна разверните папку Minecraft и из папки src/main/java удалите com.example.examplemod к чертям, оно нам не надо. Это мод-пример, так что по его названию можно посмотреть, как же именуются моды в коде, условно — com.разраб.название. Так что теперь мы тыкаем ПКМ по src/main/java, New=>Package(далее по тексту — пакет). В поле Name нужно пихнуть конструкцию типа com.coder.myfirstmod(в зависимости от вашего ник и названия), после чего нажать Finish.
Главный класс
Ну хорошо, теперь можем творить. Первым делом нужно запилить основной файлик мода. В свежесозданном пакете жмем ПКМ, New=>Class, в названии вводим очевидно название класса. Я не буду очень уникальным и просто назову его Main, незачем усложнять.
Объявим, что это мод имеет название и версию. Пишем строку над «public class …»:
@Mod (modid = "mracerdim", name="Racer's Dimension", version = "0.1")
Я объявил ID мода, его навание и версию. Оно нужно нам и кубачу для работы. Теперь подправим возникшую ошибку, допишем после строчки с указанием пакете(package com.coder.myfirstmod) следующее:
import cpw.mods.fml.common.Mod;
После этого уже в теле класса, в фигурных скобках, докидываем:
@EventHandler
public void preLoad(FMLPreInitializationEvent event)
{
}
Вылезут две ошибки, но они решаются импортом недостающих библиотек(клик по ошибке — выбрать импорт, обычно оно в самом первом варианте решения). Сохраняемся, смотрим.

Что ж. Давайте сразу начнем работать нормально, чтобы ничего не лежало в одной папке огромной кучей. Для начала я перепишу строку объявления мода:
@Mod(modid = Main.MODID, name = Main.MODNAME, version = Main.VERSION)
А теперь в теле главного класса я пропишу следующие строки:
public static final String MODID = "MRacerDim";
public static final String MODNAME = "Racer's Dimension";
public static final String VERSION = "0.1";
Да, выглядит бесполезным, я в курсе. Но мне удобнее так.
Блоки
И правда, какая модификация может обойтись без своих камешков и земли? Надо делать.
Создаем в src/main/java новый пакет и назовем его com.coder.myfirstmod.blocks. В этом пакете для блоков нужно так же создать новый класс, например ModBlocks или просто Blocks. получится примерно следующее:

Разделение категорий блоки-предметы-мобы-такдалее нужно, чтобы основной файл не был монструозных размеров. Возможно, он будет даже быстрее загружаться при обилии кода.
В теле класса блоков прописываем строчку:
public static Block RedPlating;
Ошибка есть, но она решается импортом из net.minecraft.block.Block. RedPlating — такое условное название для моего будущего блока.
Создаем еще одну переменную для инициализации блоков:
public static final void init() {
GameRegistry.registerBlock(RedPlating = new RedPlating("RedPlating", Material.iron), "RedPlating");
}
Мы регистрируем наш блок. Не забудьте импортировать GameRegistry и Material.
В скобках объявлено его unlocalizedName и material. Эти переменные нужны на описание нашего блока.
Материал показывает, как примерно будет вести себя блок. Условно, материал «стекло» — будет разбиваться со звуком стекла, «камень» — со звуком камня, «ковер» меняет звуки ходьбы и так далее. Вторую ошибку можно исправить созданием класса нашего блока.
В теле класса пишем что-то следующее:
protected RedPlating(String unlocalizedName, Material material) {
super(material);
// Ссылаемся на материал блока в нашем основном файле.
this.setBlockName("unlocalizedName");
// Ссылаемся на название блока в нашем основном файле.
this.setBlockTextureName(Main.ModID + ":" + unlocalizedName);
// Ссылка на текстуру блока. Такое построение ссылки делает ее универсальной, и она будет работать вообще в любом случае, лишь бы ModID и unlocalizedName присутствовали.
this.setCreativeTab(CreativeTabs.tabBlock);
// Добавляет наш блок во вкладку блоков в креативе. Не беспокойтесь, мы сделаем свою чуть позже.
this.setHardness(2.0F);
// Ниже прочность, быстрее будет ломаться блок. Пошаманьте сами с этой характеристикой.
this.setResistance(10.0F);
// Взрывоустойчивость блока.
this.setLightLevel(0.0F);
// Свечение блока. 0 - не светится, 150 - максимальная яркость.
this.setHarvestLevel("pickaxe", 1);
// Каким инструментом и какого уровня можно сломать блок. 0 - деревянный, 1 - каменный, и так далее.
this.setStepSound(soundTypeMetal);
// С каким звуком мы будем по блоку ходить. Вбив просто soundType, нам предложат на выбор некоторые примеры.
}
Необязательными тут являются звуки ходьбы и свечение блока. Остальное — необходимое.
Теперь нужно создать текстурку блока. Главное чтоб квадратная была, но лучше не больше 32х32 пикселей. Название должно совпадать с названием блока, и разширение png. В моем случае текстурка будет иметь название RedPlating.png, и вот так выглядеть:

Нам остается добавить текстурку в проект. Слева в папке src/main/resources создаем новый пакет assets.MODID.textures.blocks, после чего перекиньте туда текстурку.
Вроде готово? Нет, ведь если мы запустим тест, то не найдем наш блок. Его нужно подгрузить в основном классе мода. В preLoad {} допишем строку:
Blocks.init();
Это должно подхватить наш пакет с блоками. Запускаемся и видим:


Теперь-то уж точно готово. Если вы хотите добавить еще блоков, это делается аналогично, главное объявить их в классе блоков не забудьте, дважды — как переменную и в GameRegisrty.

Хорошо, но нам нужно дать НОРМАЛЬНЫЕ имена блокам.
Локализация
В scr/mair/resources создаем пакет assets.MODID.lang, и добавим в него файл en_US.lang(для английского) и опционально ru_RU.lang(Для русского, если требуется).
Пишем в файлик название той кракозябры что видим, далее =, после него нормальное название на том языке, на котором это должно отображаться. Получится что-то типа того для английкого:
tile.RedPlating.name=Red Plating
И что-то такое для русского:
tile.RedPlating.name=Красные пластины
Сохраняемся, смотрим. Да, все работает. Мы великолепны. Не забываем добавлять в файлик все новые штуки. Каждую штуку с новой строки, да.
Компиляция
В build.gradle отредактировать пару строк:
version = "0.1"
group= "com.cingulari.mracerdim" //
archivesBaseName = "Racer Dimension"
После такого редактирования мой мод к примеру будет называться в созданном виде «Racer Dimension-0.1.jar». Осталось лишь скомпиллировать. В корневой папке, куда был распакован Forge, создаем bat-файл с кодом:
gradlew.bat build
После запуска мод скомпилируется и его можно будет найти в папке build/libs. На сегодня все, но нам еще много чего делать еще.

