Хотите создавать крутые моды для 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.
 
   
  