Обработка событий Forge в Minecraft

published on 30 August 2024

Обработка событий Forge - ключевой аспект разработки модов для Minecraft. Вот основное:

  • Позволяет модам реагировать на игровые события и менять поведение игры
  • Используются две шины событий:
  • Обработчики регистрируются через @SubscribeEvent или вручную
  • Приоритеты задаются через EventPriority
  • Можно создавать свои события

Важно:

  • Избегайте тяжелых операций в обработчиках
  • Проверяйте возможность отмены через isCancelable()
  • Используйте подходящие подклассы событий
  • Учитывайте совместимость с другими модами

Правильное использование событий позволяет создавать гибкие моды.

Как работают события Forge

Forge

События в Forge позволяют модам реагировать на игровые ситуации. Рассмотрим их устройство:

Типы шин событий

  1. Основная шина Forge (MinecraftForge.EVENT_BUS)
  2. Шина событий мода (FMLJavaModLoadingContext.get().getModEventBus())

Основная шина используется для большинства игровых событий. Шина мода - для событий жизненного цикла мода.

Процесс обработки

  1. Создание объекта события
  2. Отправка на шину
  3. Вызов обработчиков по приоритету
  4. Выполнение действий обработчиками

Пример регистрации:

@Mod.EventBusSubscriber(modid = "mymod")
public class MyEventHandler {
    @SubscribeEvent
    public static void onItemPickup(EntityItemPickupEvent event) {
        // Обработка
    }
}

Регистрация в конструкторе мода:

MinecraftForge.EVENT_BUS.register(...) // Основная шина

FMLJavaModLoadingContext.get().getModEventBus().register(...) // Шина мода

Понимание событий Forge критично для эффективной разработки модов.

Создание и добавление обработчиков событий

Базовая структура обработчика

public class МойОбработчик {
    @SubscribeEvent
    public void onItemPickup(EntityItemPickupEvent event) {
        System.out.println("Предмет подобран!");
    }
}

Способы регистрации

  1. Ручная:
MinecraftForge.EVENT_BUS.register(new МойОбработчик());
  1. Автоматическая:
@Mod.EventBusSubscriber(modid = "mymod")
public class МойСтатическийОбработчик {
    @SubscribeEvent
    public static void onArrowNock(ArrowNockEvent event) {
        System.out.println("Стрела натянута!");
    }
}
Способ Плюсы Минусы
Ручной Гибкость Явный код регистрации
Авто Меньше кода Только статические методы

Выбирайте способ с учетом структуры мода.

Распространенные события Forge

События игроков и сущностей

Событие Описание Пример использования
AttackEntityEvent Атака сущности Изменение урона
EntityItemPickupEvent Подбор предмета Модификация предмета
PlayerInteractEvent Взаимодействие с миром Новые способы взаимодействия

Пример:

@SubscribeEvent
public void onItemPickup(EntityItemPickupEvent event) {
    System.out.println("Подобран: " + event.getItem().getItem().getDisplayName());
}

События мира и блоков

Событие Описание Пример использования
BlockEvent.BreakEvent Разрушение блока Изменение выпадающих предметов
BlockEvent.PlaceEvent Размещение блока Отмена размещения
WorldEvent.Load Загрузка мира Генерация структур

Пример:

@SubscribeEvent
public void onBlockBreak(BlockEvent.BreakEvent event) {
    if (event.getState().getBlock() == Blocks.DIAMOND_ORE) {
        System.out.println("Добыта алмазная руда!");
    }
}

Эти события позволяют создавать уникальный игровой опыт.

sbb-itb-b1cf51d

Продвинутая обработка событий

Установка приоритетов

Приоритеты задаются через EventPriority:

Приоритет Описание
HIGHEST Первый
HIGH После HIGHEST
NORMAL По умолчанию
LOW После NORMAL
LOWEST Последний

Пример:

@SubscribeEvent(priority = EventPriority.HIGH)
public void onBlockBreak(BlockEvent.BreakEvent event) {
    // Код
}

Создание событий

  1. Создайте класс, наследующий Event
  2. Добавьте поля и методы
  3. При необходимости пометьте @Cancelable
  4. Зарегистрируйте на шине

Пример:

public class BloodMoonEvent extends Event {
    private final World world;
    private final int nightCount;

    public BloodMoonEvent(World world, int nightCount) {
        this.world = world;
        this.nightCount = nightCount;
    }

    public World getWorld() {
        return world;
    }

    public int getNightCount() {
        return nightCount;
    }
}

Использование:

MinecraftForge.EVENT_BUS.post(new BloodMoonEvent(world, nightCount));

Обработка:

@SubscribeEvent
public void onBloodMoon(BloodMoonEvent event) {
    World world = event.getWorld();
    // Логика
}

Помните:

  • Проверяйте isCancelable() перед отменой
  • Используйте setResult() для результата
  • Регистрируйте в конструкторе мода

Советы по эффективной обработке событий

Ускорение обработки

  • Избегайте интенсивных операций
  • Используйте случайность для контроля частоты:
if (new Random().nextFloat() <= 0.10f) {
    // Код выпадения предмета
}
  • Разделяйте обработчики на классы
  • Применяйте профилировщик Spark

Работа с другими модами

  • Осторожно отменяйте события
  • Устанавливайте приоритеты аккуратно
  • Настраивайте методы на получение отмененных событий
Совет Описание
Предгенерация чанков Уменьшает задержки
Меньше модов Улучшает производительность
Встроенные методы Повышает читаемость

Правильное использование событий позволит создавать эффективные моды.

Сравнение методов обработки событий

Метод Плюсы Минусы
На основе экземпляров Управление состоянием Нужен экземпляр
Статические Не нужен экземпляр Нет управления состоянием
Авторегистрация Упрощает регистрацию Только статические методы

Выбор зависит от потребностей мода.

Помните:

  • Проверяйте isCancelable()
  • Используйте DeferredWorkQueue для основного потока
  • Осторожно с приоритетами

Иногда встроенные методы лучше обработки событий.

Итоги

  • Система событий Forge позволяет взаимодействовать с 150+ событиями
  • Две шины: основная Forge и специфичная для модов
  • Регистрация через @SubscribeEvent, .register или @Mod.EventBusSubscriber
  • Избегайте интенсивных операций в обработчиках
  • Проверяйте возможность отмены
  • Устанавливайте приоритеты осторожно

Пример:

@SubscribeEvent 
public void onBlockDropItems(BlockEvent.HarvestDropsEvent event) { 
    if (event.getState().getBlock() == Blocks.SPAWNER) { 
        event.getDrops().add(new ItemStack(Items.EXPERIENCE_BOTTLE)); 
    } 
}

Помните о совместимости и избегайте лишней сложности.

Часто задаваемые вопросы

Как зарегистрировать обработчики?

  1. MinecraftForge.EVENT_BUS:
MinecraftForge.EVENT_BUS.register(new МойОбработчик());
  1. FMLJavaModLoadingContext:
FMLJavaModLoadingContext.get().getModEventBus().register(new МойОбработчикМода());
  1. Автоматически:
@Mod.EventBusSubscriber(Dist.CLIENT)
public class МойСтатическийОбработчик {
    @SubscribeEvent
    public static void onRenderWorldLast(RenderWorldLastEvent event) {
        // Код
    }
}

Важно:

  • Методы помечать @SubscribeEvent
  • Статические обработчики регистрировать классом
  • Проверять isCancelable() перед отменой

Выбор метода зависит от типа событий и структуры мода.

Related posts

Read more

Built on Unicorn Platform