Як створити мод для Minecraft у різний спосіб.

Сьогодні ми починаємо цикл статей для новачків, покликаний допомогти освоїти моддинг Minecraft, а головне зробити це максимально швидко і корисно. В принципі, кожен з нас може знайти уроки і почати створювати моди, адже методом тику можна зробити практично все, що завгодно, нехай і не правильно і красиво. Даний туторіал убереже вас від наступу на граблі та допоможе стартувати максимально швидко та зручно.

Введення в моддінг Minecraft

Варто зазначити, що моди Minecraftпишуться Java. Жодних зручненьких редакторів тут не буде. Від вас потрібно хоча б мінімальне знання Java, або досвід роботи з іншими мовами програмування, знання їх основ. На крайній випадок – велике бажання навчитися всього цього. Якщо ви не тупо копіюватимете приклади, а постараєтеся зрозуміти, як воно працює, то напевно чекає успіх.

Практично кожна людина, яка хоч раз встановлювала моди Minecraft, знайома з модифікацією Forge, адже більшість модів вимагають її наявності у вашій грі. У рамках цієї статті ми створюватимемо моди саме під Forge.

Чому Forge? Уявіть, що вам потрібно відремонтувати телевізор/комп'ютер/айфон/великий адронний колайдер (потрібне підкреслити), але під рукою у вас тільки молоток і цвяхи. Звичайно ж ми підемо і дістанемо запилену скриньку з інструментами, в якій є і пасатижі, і пінцет, та й взагалі все, що душа забажає. У нашому випадку, Forge – це і є та бажана скринька з інструментами.

Приступимо до роботи

Для початку нам потрібно завантажити JDK (Java Development Kit)

Стаття є ексклюзивною для сайту. Копіювання та передрук інформації можливе лише за письмовою згодою автора.


Не треба видаляти META-INF, minecraft.jar, і minecraft_server.jar
1. Створюємо папку (наприклад: MCP Forge) і розпаковуємо туди зміст архіву з MCP.
2. Копіюємо в папку ../MCP Forge/jars/ , з клієнта папку bin і resources, з сервера нам знадобиться тільки minecraft_server.jar.
3. Розпаковуємо архів з Forge-src у папку MCP Forge
4. Відкриваємо папку../MCP Forge/forge/ та запускаємо файл install.cmd. Чекаємо закінчення декомпіляції.
(P.S Якщо хочете що б у вас вже був готовий MCP з Forge, наприклад, якщо ви випадково видалили його або ще щось, то: Коли декомпіляція пройде запустіть гру нехай скачає lib, і потім додайте в архів цей MCP Forge наприклад так (mcp Forge 1.5.1)
5. "Встановлюємо" та запускаємо Eclipse, під час запуску у вас "запитають" папку з проектом, вказуємо шлях: ../MCP Forge/eclipse/
6. Отже, ми відкрили проект, тепер (Зазвичай ліворуч, є Package explorer) дивимося, яку бібліотеку він "їсть" (У вікні Package explorer, "відкриваємо проект Minecraft" і якщо буде рядок "JRE System Library", то все нормально, але якщо рядок "JRE System Library", то натискаємо ПКМ(Правою кнопкою миші), вибираємо пункт Properties, далі відкрилося вікно в ньому пункт Execution environment, вибираємо JavaSE-1.7 і натискаємо Ok.
7. Отже, приготування готове.

Як же все-таки почати писати мод?

Для початку, нам потрібно створити "основу", тобто основну "папку" в якій зберігатиметься наша "основа" і все інше.
1. Заходимо в Eclipse бачимо в Package Explorer папку Minecraft, відкриваємо, і натискаємо ПКМ на папку src, вибираємо New-> Package. Відкрите вікно в рядку Name, ми вказуємо назву папки в якій буде все зберігатися (Для прикладу візьмемо: mods.testmod.src) і натискаємо Ok.
2. Натискаємо ПКМ по нашій папці (mods.testmod.src), далі New -> Class. У рядку Name вказуємо назву нашого файлу (Наприклад: TestModBase) та натискаємо Finish.
3. Змінюйте шлях, але не прибирайте mods, ось так наприклад mods.NewItemMod.src.
4. У нових версіях треба імпортувати "Дуже багато" всього, щоб зробити це швидше в Екліпс натискайте "ctrl + shift + o", і вам швидко він все імпортує, а якщо з'явитися вікно тоді вибирайте потрібний вам імпорт.
5. Якщо ви працюєте не в екліпсі, тоді вам буде набагато важче, так що краще перейти на нього, він вкаже де помилка, і які імпорти треба, і ви не будете ставити дурних питаньу коментарях.

package mods.testmod.src;

import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.Init;
import cpw.mods.fml.common.Mod.Instance;
import cpw.mods.fml.common.Mod.PostInit;
import cpw.mods.fml.common.Mod.PreInit;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.network.NetworkMod;
import cpw.mods.fml.common.network.NetworkRegistry;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.common.registry.LanguageRegistry;
import cpw.mods.fml.common.network.NetworkMod.SidedPacketHandler;
import cpw.mods.fml.common.SidedProxy;
@Mod (modid = "TestMod", name = "Test Mod", version = "0.0.1")
@NetworkMod (clientSideRequired = true, serverSideRequired = false, versionBounds = "1.0.0")

public class TestModBase (

@Instance("TestModID")
public static TestModBase instance;

@Init

{
}

@PreInit
public void preLoad(FMLPreInitializationEvent event)
{
}

@PostInit
public void postLoad(FMLPostInitializationEvent event)
{
}
}


У нашому файлі TestModBase
Після напису:
public class TestModBase (
Вписуємо такий рядок:
public static final Block testBlock = новий TestBlock(2020).setUnlocalizedName("testBlock");
Розбір:
Block "testBlock" - testBlock назва нашого блоку в коді(не в грі)
new TestBlock(2020) - TestBlock назва нашого блоку в коді(не в грі), 2020 ID блоку
setUnlocalizedName("testBlock") - ("testBlock") назва нашого блоку в коді(не в грі)
Після напису:
@Init
public void load(FMLInitializationEvent event)
{

Вписуємо такий рядок:
GameRegistry.registerBlock(testBlock);
LanguageRegistry.addName(testBlock, "Test Block");

Розбір:
(testBlock) - назва нашого блоку в коді (не в грі)
(testBlock, "Test Block") - testBlock назва нашого блоку в коді(не в грі), "Test Block" назва нашого блоку в грі.
Створюємо файл testBlock і вписуємо в нього такий код:
package mods.testmod.src;

import net.minecraft.block.Block;
import net.minecraft.block.material.Material;

public class TestBlock extends Block (

public TestBlock(int par1)
{
super(par1, Material.ground);//Матеріал
this.setCreativeTab(CreativeTabs.tabTools);//Додаємо в креатив
}
//Реєструємо текстуру
@Override

{
}
}


У нашому файлі TestModBase
Після напису:
public class TestModBase (
Вписуємо такий рядок:
public static Item testItem = new TestItem(2021).setUnlocalizedName("testItem");
Розбір:
public static final Item "testItem" - testItem назва нашого предмета в коді (не в грі)
new TestItem(2021) - TestItem назва нашого предмета в коді(не в грі), 2021 ID предмета
setUnlocalizedName("testItem") - ("testItem") назва нашого предмета в коді(не в грі)
Після напису:
@Init
public void load(FMLInitializationEvent event)
{

Вписуємо такий рядок:
LanguageRegistry.addName(testItem, "Test Item");
Розбір:
(testItem, "Test Item") - testItem назва нашого предмета в коді (не в грі), "Test Item" назва нашого предмета в грі.
Створюємо файл testItem і вписуємо в нього такий код:
package mods.testmod.src;

import net.minecraft.item.Item;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.creativetab.CreativeTabs;

public class TestItem extends Item
{
public TestItem(int par1)
{
super(par1);
setCreativeTab(CreativeTabs.tabTools);
}

//Реєстрація текстури для ітему трохи відрізняється від блоку
@Override
public void registerIcons(IconRegister par1IconRegister)
{
}
}


@Override
public void registerIcons(IconRegister par1IconRegister)
{
this.blockIcon = par1IconRegister.registerIcon("testmod:testBlock");
}

("testmod:testBlock"), testmod - це "ім'я папки", в якій буде "папка з текстурою", testBlock - назва нашої текстури. Ось таке розміщення текстури:

\Tutorial Forge 1.5.1\mcp744\src\minecraft\mods\testmod\textures\blocks\testBlock.png


@Override
public void registerIcons(IconRegister par1IconRegister)
{
this.itemIcon = par1IconRegister.registerIcon("testmod:testItem");
}

("testmod:testItem"), testmod - це "ім'я папки", в якій буде "папка з текстурою", testItem - назва нашої текстури. Ось таке розміщення текстури.

Отже, ми маємо папку з наступними файлами всередині:

  • build.gradle
  • gradlew (.bat і.sh)
  • папка gradle

Тепер необхідно виконати команду gradlew eclipse. Якщо у вас Windows, то ви можете клацнути правою кнопкою по порожньому простору всерединіцієї папки із затиснутою клавішею Shift. Тоді, в контекстному меню буде пункт "Відкрити вікно команд". Виберіть цей пункт і відкриється консоль.

У консолі введіть gradlew eclipse .

Відкрийте Eclipse. Немає особливої ​​різниці, де розташовується робочий простір. У верхній частині екрана відкрийте меню "File" і виберіть пункт "Import". У списку виберіть "Gradle > Gradle Project".

Пропустіть вступне вікно Gradle, натиснувши кнопку "Next >", якщо воно з'явиться.

У наступному вікні вкажіть папку з розпакованими файлами. Натисніть "Finish".

Gradle таски

Відкрийте меню "Window" у верхній частині екрана та виберіть "Show View > Other…".

У вікні виберіть "Gradle > Gradle Tasks".

У вас відкриється вікно із Gradle завданнями. Gradle – популярна система автоматичного збирання, яка з вихідників збирає готові програми та робить ще багато інших необхідних, але рутиннихсправ. Ці справи називаються завданнями/завданнями/тасками - tasks. Ми якраз і відчинили вікно тяган.

Виглядає воно приблизно так:

Тестовий запуск

Для тестового запуску у верхній частині екрана відкрийте меню Run і виберіть Run configurations. У вікні зліва відкрийте вкладку "Java Application" і виберіть клієнт або сервер. Потім натисніть кнопку "Run".


Сьогодні я знову відкриваю цикл статей і цього разу. закидати його не буду і навіть відповідатиму на ваші коментарі. Ну що ж, від слів до діла. Поїхали!
Підготовка

Для написання своїх плагінів нам знадобляться:
  • Середовище розробки Java-додатків Eclipse;
  • Api Spigot: https://hub.spigotmc.org/nexus/content/groups/public/org/spigotmc/spigot-api/ .
Також знадобляться базові знання з Java. Якщо таких немає, то ось посилання щодо "підняття скила":
  • Основи Java для початківців
    Сайт розрахований на тих, хто тільки починає вивчати Java
  • Java (Beginner) Programming Tutorials
    Відео-туторіал по Ява, розрахований для новачків (я починав із нього).
  • Довідник з java
    Я б назвав це шпаргалкою по яві
  • Java експерт
    І нехай вас не лякає назва. Тут можна знайти безліч прикладів рішення на ті або
    інші завдання.
Встановлення та налаштування Eclipse
Якщо ви вже знайомі з Eclipse або у вас інша IDE, то пропускайте цей розділ.

Проблем із встановленням екліпсу виникнути не повинно: його потрібно просто розпакувати в будь-яку папку та запустити. Відразу після цього, екліпс попросить вказати, який робочий простір (workspace) зараз відкрити. Це папка, в якій будуть зберігатися всі створені проекти і де її розташовувати – ваше рішення. Якщо вам все рано, то залишайте все як є. Якщо раптом захочете змінити робоче місце, то не переживайте: при кожному наступному запуску, екліпс знову запитає вас про робочий простір. Таких просторів можна наробити скільки завгодно і кожен може бути налаштований по-різному, під певні цілі. Наприклад у мене є 2 робочі простори: для написання звичайних java-додатків і для написання плагінів під "відро". Якщо раптом вам набридне це повідомлення, там є галочка «Use this as the default and do not ask again», що дозволяє задати workspace за замовчуванням.

Як тільки ви визначитеся з вибором місця і завантажиться Eclipse, ми побачимо запрошувальну вкладку ... яку відразу ж закриваємо. Вона нам ні до чого.

Тепер ми бачимо робочий простір самого екліпса. З усього цього нам знадобиться тільки наступні панелі:

  • Package Explorer
    Тут будуть відображатися ваші проекти, пакети (про них пізніше) та всілякі файли наших майбутніх плагінів.
  • Problems
    Цією панелькою ми рідко користуватимемося (якщо взагалі до неї справа дійде), але сказати про неї варто. Тут будуть показуватися помилки, допущені в коді, а також попереджувальні повідомлення про можливі помилки або неточності.
  • Outline
    Тут буде відображатись навігація безпосередньо за кодом відкритого java вихідника.
Останні 2 описані панелі взагалі можна згорнути, т.к. користуватися ними будемо рідко.

Робоче місце майже готове. Залишилося лише поставити ще 2 галочки в налаштуваннях.

Переходимо в меню Window -> Preferences, далі по дереву General -> Editor -> Text Editors і виставляємо галочку "Show line numbers", щоб увімкнути відображення нумерації рядків. Тепер переходимо в General -> Workspace і в групі Text file encoding виставляємо кодування UTF-8, самим встановивши кодування за замовчуванням.

З установкою та налаштуванням покінчено. Тепер поясню, як створювати новий проектдля плагіна. Це можна зробити одним з трьох способів:

Перед нами з'явиться вікно New Java Project. У Project name вказуємо назву нашого проекту

Натискаємо Next.
У вікні, переходимо на вкладку Libraries, натискаємо кнопку Add External JARs і вибираємо завантажений Bukkit API

Тиснемо Finish.

Ліворуч, у Package Explorer, з'явився наш проект із папкою src, у якій зберігатимуться наші вихідні коди. Тепер створимо новий клас. Робиться це так само, як і з Java Project.

У вікні New Java Class нам знадобляться лише такі графи:

  • Package
    вказується пакет, у якому зберігається наш клас. Формат імені має бути приблизно такий: ru.dmitriymx.bukkit.tutorial.
    Якщо двома словами і пальцями, то пакети в ява – це простір імен(namespace) чи «віртуальні папки», у яких поміщаються класи. Докладніше про це можна прочитати тут: , , .
  • Name
    вказуємо назву класу (у мене це DmxFirstPlugin)
Всі інші пункти залишаємо як є і тиснемо Finish.

Ось тепер переходимо безпосередньо до коду.
Пишемо простий плагін
Як тільки ми створили новий клас, на наш погляд постає вже готовий порожній шаблон

Поки що це лише порожній клас, який абсолютно марний у побуті. Будемо це виправляти. Змінюємо ось це

на це

Екліпс підкреслить нам JavaPlugin, вказуючи на помилку коду. Якщо підвести мишу до такого підкресленого коду, відкриється віконце з описом помилки та способи її вирішення. У даному випадкунам потрібно імпортувати клас з Bukkit API, для чого вибираємо пункт "Import 'JavaPlugin'(org.bukkit.plugin.java)"

Відразу ж помічаємо, як над усім нашим кодом вписався рядок

Небагато теоретичного матеріалу. У плагінів є 3 основних методи: onEnable(), onDisable() та onLoad(). Перші два відповідають за включення та відключення плагіна, а останній спрацьовує, коли плагін безпосередньо підвантажується в пам'ять сервера. З цього випливає, що onLoad виконується найпершим, але сама плагін починає працювати тільки після виклику onEnable з боку сервера. Після вимкнення або перезавантаження сервера викликається метод onDisable.

З "точками входу-виходу" розібралися. Давайте тепер напишемо щось більш-менш працездатне. Наведемо загальний код класу до наступного виду:

кому не видно друга частина:
про що ми зараз написали – готовий плагін. Все що він робить – це пише в чат про прихід та відхід гравця на сервер. Розбиратися в його роботі будемо по порядку (а як інакше?).
Спочатку зверну увагу на рядок оголошення класу. Як бачимо, до нашого класу додалося розширення Listener. Не заглиблюючись у нетрі яви, скажу простіше: вказуючи дане розширення, ми тим самим розширюємо сферу застосування класу не тільки як плагіна (JavaPlugin), але і як обробника подій (Listener). А ось якраз у методі onEnable() ми реєструємо наш клас на сервері як обробник подій (this – це вказівка ​​«на себе», якщо хтось забув).

Далі слідують 2 наших обробника подій onJoin() і onQuit(). Перший відповідає подія входу гравця на сервер, а другий – за догляд. За допомогою методу event.getPlayer().sendMessage(), ми можемо надіслати повідомлення тому гравцю, який викликав цю подію (у нашому випадку гравцю, який зайшов). Статичний клас ChatColor зберігає константи кольорів для фарбування. Думаю, як ним користуватися вже видно з прикладу. Так само, обидва наші обробки сповіщають інших гравців на сервері про події, що відбулися, але роблять це по-різному. В onJoin() за допомогою методу event.setJoinMessage() ми змінюємо звичне повідомлення "Player joined the game" на будь-яке інше. А в onQuit() ми надійшли інакше (для прикладу): прибрали висновок повідомлення про вихід і повідомляємо про це через метод getServer().broadcastMessage(), який просто посилає всім гравцям на сервері вказане повідомлення.+

Справа залишилася за малим: написання важливого файла plugin.yml і упаковка всього цього в jar-файл.

Plugin.yml – це файл опису плагіна. У ньому задається назва плагіна, головний клас, опис та які команди зареєструвати за плагінами (про це пізніше) і т.д. У нашому випадку файлик повинен виглядати так:

Ой, забфл сказати, де цей файл повинен бути. Тиснемо правою кнопкою миші в PackageExplorer по папці src і через меню New вибираємо File. У полі File name пишемо plugin.yml і тиснемо Finish. У текстовому редакторі, що відкрився, пишемо те, що я вказував вище. Все зберігаємо та переходимо до останньої фази: упаковки.

Правий тик по папці src -> Export. У дереві папок відкриваємо Java і вибираємо JAR file і тиснемо Next. З голочок залишаємо тільки "Export generated class files and resources" і "Compress the contents of the JAR file". У полі JAR file вказуємо, куди зберігатимемо отриманий плагін. Після натискання Finish, плагін можна класти в папку plugins, запускати сервер і перевіряти його роботу.

Бачите? Це дуже просто. З практикою ви наберете більше досвіду і зможете робити більш круті плагіни, навіть такі легендарні як WorldEdit і WorldGuard.
Джерело