Хотите создавать крутые моды для Minecraft? Fabric - ваш лучший выбор. Вот что нужно знать об обработке событий:
- События позволяют модам реагировать на действия в игре
- Fabric API предоставляет множество готовых событий
- Можно создавать собственные события
- Правильная обработка событий - ключ к стабильной работе мода
Основные типы событий:
- Игрока (смерть, вход на сервер)
- Блоков (размещение, разрушение)
- Сущностей (спавн, трансформация)
- Мира (тики)
Для работы с событиями:
- Настройте проект Fabric
- Создайте обработчики событий
- Зарегистрируйте их в главном классе мода
Пример обработчика:
AttackBlockCallback.EVENT.register((player, world, hand, pos, direction) -> {
if (world.getBlockState(pos).isToolRequired() && player.getMainHandStack().isEmpty()) {
player.damage(DamageSource.GENERIC, 1.0F);
}
return ActionResult.PASS;
});
Этот код наносит урон игроку при попытке сломать блок голыми руками.
Используйте события Fabric для создания эффективных и совместимых модов!
Перед началом работы
Что вам понадобится
Для работы с событиями в Fabric:
-
Java Development Kit (JDK): Java 21+ для Minecraft 1.20.5+, Java 17+ для 1.18+, Java 8+ для старых версий. Скачайте на Adoptium или jdk.java.net.
-
IDE: IntelliJ IDEA с плагином Minecraft Development - лучший выбор.
-
Fabric Loader и API: Основа для создания модов.
Настройка проекта
1. Установка
Скачайте и установите JDK и IntelliJ IDEA.
2. Создание проекта
Два варианта:
- Копируйте шаблон из fabric-example-mod
- Используйте генератор в IntelliJ IDEA с плагином Minecraft Development
3. Настройка
Измените:
gradle.properties
: свойства модаfabric.mod.json
: зависимости
4. Проверка
Запустите:
./gradlew runClient
Minecraft должен запуститься без проблем.
"События часто заменяют миксины." - Fabric Wiki
Fabric API не обязателен, но очень полезен для совместимости модов.
Как работают события в Fabric?
События в Fabric - это способ для модов реагировать на происходящее в игре. Представьте, что это система оповещений для вашего мода.
Что такое эти события?
По сути, события Fabric - это обратные вызовы. Они позволяют вашему моду "подписаться" на определенные действия в игре.
Каждое событие - это экземпляр класса Event
из Fabric API. Этот класс отвечает за хранение и вызов обратных вызовов.
Какие бывают события?
Fabric API предлагает много разных событий:
Тип | Что это? |
---|---|
Клиентские | Всё, что происходит на стороне клиента |
Серверные | То, что творится на сервере |
Жизненного цикла | Запуск и остановка игры или сервера |
Игрока | Действия игрока (атака, использование предметов) |
Вот несколько конкретных примеров:
AttackBlockCallback
: Срабатывает при ударе по блокуUseItemCallback
: Когда игрок использует предметPlayerBlockBreakEvents
: Группа событий о разрушении блоков
Как это работает на практике?
- Ваш мод регистрирует обратный вызов для нужного события.
- Когда что-то происходит в игре, Fabric API вызывает все зарегистрированные обратные вызовы.
- Код вашего мода реагирует на событие.
Вот пример кода:
AttackBlockCallback.EVENT.register((player, world, hand, pos, direction) -> {
BlockState state = world.getBlockState(pos);
if (!player.isSpectator() && player.getMainHandStack().isEmpty() && state.isToolRequired()) {
player.damage(world.getDamageSources().generic(), 1.0F);
}
return ActionResult.PASS;
});
Этот код наказывает игрока уроном, если он бьет голыми руками по блоку, требующему инструмент.
События Fabric часто проще и надежнее, чем использование миксинов для изменения игры.
Настройка мода
Чтобы работать с событиями Fabric, нужно правильно настроить мод. Вот как это сделать:
Файловая структура
Типичная структура Fabric-мода:
src/
main/
java/ # Код
resources/ # Ресурсы и конфиги
assets/
data/
fabric.mod.json
Главное:
java/
: весь кодresources/
: ресурсы и конфигиfabric.mod.json
: метаданные мода
Настройка fabric.mod.json
Этот файл - сердце мода. Пример:
{
"schemaVersion": 1,
"id": "myeventmod",
"version": "1.0.0",
"name": "Мой обработчик событий",
"description": "Обработка событий в Minecraft",
"authors": ["Я"],
"contact": {
"homepage": "https://example.com/",
"sources": "https://github.com/me/myeventmod"
},
"license": "MIT",
"icon": "assets/myeventmod/icon.png",
"environment": "*",
"entrypoints": {
"main": ["com.example.myeventmod.MyMod"]
},
"depends": {
"fabricloader": ">=0.14.21",
"minecraft": "~1.20.1",
"java": ">=17"
}
}
Ключевые моменты:
id
: уникальный идентификатор (2-64 символа)version
: версия модаentrypoints
: главные классыdepends
: зависимости (версии Fabric, Minecraft, Java)
Что нужно сделать:
- Поменять
id
иname
- Указать версию
- Обновить
entrypoints
- Проверить
depends
Правильная настройка этого файла - залог успешной работы с событиями Fabric.
Добавление обработчиков событий
Чтобы мод реагировал на события в игре, нужны обработчики событий. Вот как их добавить:
Создание обработчика
- Новый класс для обработки событий
- Аннотация
@EventBusSubscriber
к классу - Статические методы для каждого типа события
- Аннотация
@SubscribeEvent
к методам
Пример:
@EventBusSubscriber
public class МойОбработчик {
@SubscribeEvent(priority = EventPriority.NORMAL, receiveCanceled = true)
public static void onEvent(EntityConstructing event) {
// Код обработки
}
}
Подключение к Fabric
Используйте register()
для нужного события:
public class МойМод implements ModInitializer {
@Override
public void onInitialize() {
AttackBlockCallback.EVENT.register((player, world, hand, pos, direction) -> {
BlockState state = world.getBlockState(pos);
if (state.isToolRequired() && !player.isSpectator() && player.getMainHandStack().isEmpty()) {
player.damage(DamageSource.field_5869, 1.0F);
}
return ActionResult.PASS;
});
}
}
Этот код регистрирует обработчик для AttackBlockCallback
. Он проверяет, нужен ли инструмент для блока, и бьет игрока, если тот пытается сломать блок голыми руками.
Событие | Описание | Пример |
---|---|---|
AttackBlockCallback | При атаке блока | Изменение разрушения блоков |
UseBlockCallback | При использовании блока | Новые действия с блоками |
UseItemCallback | При использовании предмета | Предметы с особыми эффектами |
Важно:
EventPriority
управляет порядком обработчиковreceiveCanceled=true
для отмененных событийActionResult.PASS
продолжает обработку другими модами
Грамотное использование обработчиков позволит моду эффективно влиять на игру и взаимодействовать с другими модами.
Распространенные типы событий
Fabric предлагает множество событий для модификации игры. Давайте рассмотрим самые популярные:
События игрока
Эти события реагируют на действия игрока:
Событие | Описание | Применение |
---|---|---|
death | Смерть игрока | Новое сообщение о смерти |
join | Вход на сервер | Приветствие |
kill_entity | Убийство сущности | Награда за определенных мобов |
leave | Выход с сервера | Сохранение данных |
События блоков
Изменяют поведение блоков:
- Before Player Place: До размещения блока
- Entity Fall On: Падение сущности на блок
- Player Destroy: Разрушение блока игроком
Пример обработки разрушения блока:
void afterBlockBreak(World world, PlayerEntity player, BlockPos pos, BlockState state, BlockEntity blockEntity) {
// Код обработки
}
События сущностей
Реагируют на действия мобов и объектов:
- Entity Spawned: Появление сущности
- Entity Transformed: Трансформация сущности
Пример пользовательского события:
public interface SheepShearCallback {
Event<SheepShearCallback> EVENT = EventFactory.createArrayBacked(SheepShearCallback.class,
(listeners) -> (player, sheep) -> {
for (SheepShearCallback listener : listeners) {
ActionResult result = listener.interact(player, sheep);
if(result != ActionResult.PASS) {
return result;
}
}
return ActionResult.PASS;
});
ActionResult interact(PlayerEntity player, SheepEntity sheep);
}
События мира
Реагируют на изменения в игровом мире:
- Random Tick: Случайный тик (рост растений)
- Tick: Регулярный тик
"PlayerTick жрет в 2-6 раз больше CPU, чем нужно." - 4HeadTiger, мод-разработчик
Помните о производительности при использовании событий. PlayerTick может вызываться несколько раз за тик, что увеличивает нагрузку на CPU.
sbb-itb-b1cf51d
Написание обработчиков событий
Обработка событий - ключевая часть разработки модов для Fabric. Давайте разберемся, как создавать и использовать обработчики событий эффективно.
Создание пользовательского обработчика
Чтобы сделать свой обработчик событий в Fabric:
1. Создайте интерфейс обратного вызова:
public interface СтрижкаОвецCallback {
Event<СтрижкаОвецCallback> EVENT = EventFactory.createArrayBacked(СтрижкаОвецCallback.class,
(listeners) -> (player, sheep) -> {
for (СтрижкаОвецCallback listener : listeners) {
ActionResult result = listener.interact(player, sheep);
if(result != ActionResult.PASS) {
return result;
}
}
return ActionResult.PASS;
});
ActionResult interact(PlayerEntity player, SheepEntity sheep);
}
2. Вызовите событие из Mixin:
@Mixin(SheepEntity.class)
public class SheepShearMixin {
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/passive/SheepEntity;dropItems()V"), method = "interactMob", cancellable = true)
private void onShear(final PlayerEntity player, final Hand hand, final CallbackInfoReturnable<Boolean> info) {
ActionResult result = СтрижкаОвецCallback.EVENT.invoker().interact(player, (SheepEntity) (Object) this);
if(result == ActionResult.FAIL) {
info.cancel();
}
}
}
3. Реализуйте и зарегистрируйте обработчик:
СтрижкаОвецCallback.EVENT.register((player, sheep) -> {
sheep.setSheared(true);
ItemStack stack = new ItemStack(Items.DIAMOND);
ItemEntity itemEntity = new ItemEntity(player.world, sheep.x, sheep.y, sheep.z, stack);
player.world.spawnEntity(itemEntity);
return ActionResult.FAIL;
});
Советы по обработке событий
- Используйте
ActionResult
для управления потоком событий. - Не забудьте зарегистрировать Mixin в mixins.json.
- Возвращайте
ActionResult.PASS
, если не хотите прерывать цепочку событий. - Оптимизируйте код для частых событий.
Пример оптимизированного обработчика:
AttackBlockCallback.EVENT.register((player, world, hand, pos, direction) -> {
BlockState state = world.getBlockState(pos);
if (state.isToolRequired() && !player.isSpectator() && player.getMainHandStack().isEmpty()) {
player.damage(DamageSource.field_5869, 1.0F);
}
return ActionResult.PASS;
});
Этот код проверяет условия до выполнения действий, экономя ресурсы.
Продвинутые техники работы с событиями
Создание собственных событий
Иногда стандартных событий Fabric API мало. Вот как создать свое:
1. Создайте интерфейс обратного вызова:
public interface СобытиеСтрижкиОвец {
Event<СобытиеСтрижкиОвец> EVENT = EventFactory.createArrayBacked(СобытиеСтрижкиОвец.class,
(listeners) -> (игрок, овца) -> {
for (СобытиеСтрижкиОвец listener : listeners) {
ActionResult результат = listener.обработать(игрок, овца);
if(результат != ActionResult.PASS) {
return результат;
}
}
return ActionResult.PASS;
});
ActionResult обработать(PlayerEntity игрок, SheepEntity овца);
}
2. Вызовите событие из Mixin:
@Mixin(SheepEntity.class)
public class MixinСтрижкиОвец {
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/passive/SheepEntity;sheared(Lnet/minecraft/sound/SoundCategory;)V"), method = "interactMob", cancellable = true)
private void приСтрижке(PlayerEntity игрок, Hand рука, CallbackInfoReturnable<ActionResult> инфо) {
ActionResult результат = СобытиеСтрижкиОвец.EVENT.invoker().обработать(игрок, (SheepEntity) (Object) this);
if(результат == ActionResult.FAIL) {
инфо.setReturnValue(результат);
}
}
}
3. Зарегистрируйте обработчик:
СобытиеСтрижкиОвец.EVENT.register((игрок, овца) -> {
овца.setSheared(true);
ItemStack алмаз = new ItemStack(Items.DIAMOND);
ItemEntity предмет = new ItemEntity(игрок.getWorld(), овца.getX(), овца.getY(), овца.getZ(), алмаз);
игрок.getWorld().spawnEntity(предмет);
return ActionResult.FAIL;
});
Этот код создает событие стрижки овец, выдающее алмаз вместо шерсти.
Приоритеты и отмена событий
В Fabric API можно управлять порядком обработчиков и отменять события:
ActionResult.FAIL
отменяет событиеActionResult.PASS
позволяет другим обработчикам выполниться- Порядок регистрации влияет на приоритет
Пример:
// Высокий приоритет
СобытиеСтрижкиОвец.EVENT.register((игрок, овца) -> {
System.out.println("Высокий приоритет");
return ActionResult.PASS;
});
// Низкий приоритет
СобытиеСтрижкиОвец.EVENT.register((игрок, овца) -> {
System.out.println("Низкий приоритет");
return ActionResult.FAIL; // Отменяет событие
});
Здесь обработчик с высоким приоритетом выполнится первым, но событие отменится обработчиком с низким приоритетом.
Осторожно с отменой событий - это может конфликтовать с другими модами.
Исправление проблем с обработчиками событий
Работа с событиями в Fabric может быть непростой. Давайте разберем частые проблемы и их решения.
NullPointerException
Эта ошибка появляется, когда вы пытаетесь использовать null-объект:
Error: java.lang.NullPointerException: Cannot invoke 'me.shedaniel.rei.impl.common.entry.type.EntryRegistryList.needsHash()' because 'this.registryList' is null.
Как исправить? Проверяйте объекты на null:
if (this.registryList != null) {
this.registryList.needsHash();
}
Клиент-серверная синхронизация
Некоторые события работают только на клиенте или сервере. Используйте правильные события:
- Для клиента:
ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> {
// Ваш код
});
- Для сервера:
ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
// Ваш код
});
Краш при отключении от сервера
Проверьте версии модов и библиотек. Иногда проблема решается обновлением CreativeCore для Fabric.
Отладка
- Логи: Добавьте логирование в обработчики:
FabricLoader.getInstance().getLogger().info("Событие X: " + параметры);
-
Отчеты о крашах: Изучайте их внимательно - там много полезной информации.
-
Отладчик IDE: Используйте для пошагового выполнения кода.
-
Профилировщик: Для проблем с производительностью попробуйте VisualVM или встроенный профилировщик Minecraft (F3 + L).
Помните, отладка в Minecraft может быть сложной из-за многопоточности и разделения на клиент и сервер. Будьте терпеливы и методичны.
Ускорение обработки событий
Хотите, чтобы ваш мод Fabric летал? Давайте разберемся, как ускорить обработку событий и избежать тормозов.
Быстрее, выше, сильнее
Уменьшите дистанцию прорисовки. 10 чанков - золотая середина между FPS и геймплеем.
Настройки видео - ваш друг:
Настройка | Что делаем |
---|---|
Графика | Быстрая |
Облака | Долой |
Частицы | Минимум |
Тени сущностей | Выключаем |
Предварительная генерация чанков - ваш щит от лагов при быстром перемещении.
Избегайте "тяжелых" мест. Сложные структуры и толпы мобов - враги производительности.
Нет тормозам!
Сеть на максимум:
- Проводное подключение - ваш выбор
- Закройте "прожорливые" приложения
- QoS для игрового трафика
- Обновите прошивку роутера
Фоновые процессы под контроль:
- Никаких неожиданных обновлений
- Остановите загрузки на других устройствах
Умные игровые механики:
- Выключатели для ферм мобов
- Не усложняйте механизмы в одном месте
Примените эти советы, и ваш мод Fabric будет работать как часы!
Подведение итогов
Давайте вспомним главное об обработке событий в Fabric:
- Fabric API использует инъекции, не меняя классы напрямую
- При создании ресурс-паков или дата-паков важна правильная структура папок
- Система событий Fabric позволяет модам реагировать на игровые события
Советы
Не используйте java.awt
или javax.swing
- они могут подвесить Minecraft.
Для пользовательских полей или методов:
- Добавляйте префикс "[modid]$"
- Используйте аннотацию @Unique
При работе с сетью обрабатывайте пакеты в сетевом потоке, а остальное - в основном потоке.
Дополнительные ресурсы
Чтобы узнать больше:
- Изучите официальную документацию Fabric
- Посетите форумы Fabric
- Загляните в GitHub репозиторий Fabric
Используя эти знания, вы сможете создавать эффективные моды для Minecraft на Fabric.