Як розробляти моди для Minecraft за допомогою Temporal API?
Ця стаття призначена для тих, хто вже розробляв моди для Minecraft або лише планує спробувати себе в цьому напрямі. Йтиметься про спрощення розробки на NeoForge за допомогою бібліотеки Temporal API.
Що таке NeoForge?
Перш ніж переходити до Temporal API, варто коротко пояснити, що таке NeoForge.
NeoForge — це сучасний open-source API та модлоадер для Minecraft: Java Edition, створений як форк Minecraft Forge.
Простими словами, NeoForge — це один із найпопулярніших модлоадерів (прошарок між модами та грою) поряд із Fabric, Quilt та Forge.
NeoForge з’явився відносно нещодавно та розробляється частиною команди, яка раніше працювала над Forge. Наразі він активно підтримується й оновлюється, а більшість нових модів створюється саме на ньому. Тому для нових проєктів я рекомендую обирати саме NeoForge.
Одна з головних проблем NeoForge
Під час розробки модів на NeoForge виникає значна кількість шаблонного (boilerplate) коду. Це ускладнює підтримку проєкту та відволікає від створення унікального функціоналу.
Як приклад — створення звичайного предмета та додавання простої моделі у Minecraft 1.21.1 (без урахування налаштування проєкту, лише Java-частина):
@Mod(ExampleMod.MOD_ID)
public class ExampleMod { // 1
public static final String MOD_ID = "example";
public ExampleMod(IEventBus modEventBus, ModContainer modContainer) {
ExampleItems.ITEMS.register(modEventBus); // 5
NeoForge.EVENT_BUS.register(this); // 10
}
@SubscribeEvent
public static void gatherData(GatherDataEvent event) { // 8
DataGenerator generator = event.getGenerator();
PackOutput output = generator.getPackOutput();
ExistingFileHelper existingFileHelper = event.getExistingFileHelper();
generator.addProvider(
event.includeClient(),
new ExampleItemModelProvider(output, existingFileHelper) // 9
);
}
}
public class ExampleItems { // 2
public static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(MODID); // 3
public static final DeferredItem<Item> EXAMPLE_ITEM = ITEMS.registerSimpleItem("example_item", new Item.Properties()); // 4
}
public class ExampleItemModelProvider extends ItemModelProvider { // 6
public ExampleItemModelProvider(PackOutput output, ExistingFileHelper existingFileHelper) {
super(output, "examplemod", existingFileHelper);
}
@Override
protected void registerModels() {
basicItem(ExampleItems.EXAMPLE_ITEM.get()); // 7
}
}
Що відбувається в цьому коді:
- Створюється головний клас моду. Його конструктор фактично виконує роль
main. - Створюється клас для зберігання предметів.
- Створюється
DeferredRegister— контейнер, який дозволяє NeoForge коректно зареєструвати предмети в грі. - Реєструється звичайний предмет.
- Контейнер предметів підключається до NeoForge.
- Створюється клас для генерації моделей.
- Описується базова модель.
- Підписка на
GatherDataEventдля генерації даних. - Підключається клас генератора моделей.
- Реєструються всі події в
ExampleMod.
У невеликих прикладах це виглядає зрозуміло. Але зі зростанням кількості контенту код швидко розширюється, і його підтримка стає складнішою.
Temporal API
Що таке Temporal API?
Temporal API — це фреймворк, який автоматизує більшість рутинних задач під час розробки модів.
Він базується на рефлексії та анотаціях. Концептуально його можна порівняти з Spring Framework, але у світі моддингу.
Як Temporal API вирішує цю проблему
Перепишемо той самий приклад із використанням Temporal API:
@Mod(ExampleMod.MOD_ID)
public class ExampleMod { // 1
public static final String MOD_ID = "example";
public ExampleMod(IEventBus modEventBus, ModContainer modContainer) {
TemporalEngine.run(ExampleMod.class, modEventBus, modContainer); // 2
}
}
public final class ExampleItems { // 3
private static final ItemFactory ITEM_FACTORY = InjectionPool.getFromInstance(ItemFactory.class); // 4
@GenerateBasicItemModel // 6
public static final DeferredItem<?> EXAMPLE_ITEM = ITEM_FACTORY.create("example_item"); // 5
}
Код став значно коротшим, але функціональність залишилася тією самою:
- Створюється клас моду.
- Ініціалізується Temporal API через
TemporalEngine.run(...)— це точка входу фреймворку. - Створюється клас із предметами.
- Отримується
ItemFactory— обгортка надDeferredRegister.Items(всередині використовуєтьсяTemporalRegister.Items). - Створюється простий предмет.
- Модель генерується через анотацію
@GenerateBasicItemModel.
І це лише один приклад. Temporal API також містить набір утиліт і власну систему анотацій, яку можна розширювати за потреби.
Недоліки Temporal API
Основний недолік — підтримка версій.
Остання версія Temporal API орієнтована на Minecraft 1.21.1. Перенесення функціональності на нові та старіші версії потребує додаткових ресурсів і контриб’юторів.
Де почитати більше
Temporal API — це open-source проєкт:
Висновок
Наприкінці кілька запитань до спільноти:
- Чи доводилося вам розробляти моди для Minecraft?
- Якщо так, який модлоадер і версію гри ви використовували?
- Якщо ні, чи хотіли б спробувати?
- Чи варто написати окрему статтю з детальним розбором того, як працює Temporal API «під капотом»?
Дякую за увагу.
2 коментарі
Додати коментар Підписатись на коментаріВідписатись від коментарів