[24May2025 16:05:53.200] [modloading-worker-0/ERROR] [net.neoforged.fml.javafmlmod.FMLModContainer/LOADING]: Failed to create mod instance. ModID: cobblesnapshot, class net.mattias.cobblesnapshot.CobbleSnapshot
java.lang.IllegalArgumentException: Method public static void net.mattias.cobblesnapshot.event.CameraUseEvents.onEntityRightClick(net.neoforged.neoforge.event.entity.player.PlayerInteractEvent$EntityInteractSpecific) has @SubscribeEvent annotation, but takes an argument that is not valid for this busclass net.neoforged.neoforge.event.entity.player.PlayerInteractEvent$EntityInteractSpecific
	at MC-BOOTSTRAP/net.neoforged.bus/net.neoforged.bus.EventBus.registerListener(EventBus.java:164) ~[bus-8.0.2.jar%23141!/:?]
	at MC-BOOTSTRAP/net.neoforged.bus/net.neoforged.bus.EventBus.register(EventBus.java:91) ~[bus-8.0.2.jar%23141!/:?]
	at TRANSFORMER/cobblesnapshot@1.21.1/net.mattias.cobblesnapshot.CobbleSnapshot.<init>(CobbleSnapshot.java:37) ~[%23185!/:?]
	at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62) ~[?:?]
	at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502) ~[?:?]
	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486) ~[?:?]
	at MC-BOOTSTRAP/fml_loader@4.0.31/net.neoforged.fml.javafmlmod.FMLModContainer.constructMod(FMLModContainer.java:115) ~[loader-4.0.31.jar%23139!/:4.0]
	at MC-BOOTSTRAP/fml_loader@4.0.31/net.neoforged.fml.ModLoader.lambda$constructMods$3(ModLoader.java:153) ~[loader-4.0.31.jar%23139!/:4.0]
	at MC-BOOTSTRAP/fml_loader@4.0.31/net.neoforged.fml.ModLoader.lambda$dispatchParallelTask$7(ModLoader.java:231) ~[loader-4.0.31.jar%23139!/:4.0]
	at java.base/java.util.concurrent.CompletableFuture.uniHandle(CompletableFuture.java:934) [?:?]
	at java.base/java.util.concurrent.CompletableFuture$UniHandle.tryFire(CompletableFuture.java:911) [?:?]
	at java.base/java.util.concurrent.CompletableFuture$Completion.exec(CompletableFuture.java:483) [?:?]
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387) [?:?]
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1312) [?:?]
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1843) [?:?]
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1808) [?:?]
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:188) [?:?]
Caused by: java.lang.IllegalArgumentException: This bus only accepts subclasses of interface net.neoforged.fml.event.IModBusEvent, which class net.neoforged.neoforge.event.entity.player.PlayerInteractEvent$EntityInteractSpecific is not.
	at MC-BOOTSTRAP/net.neoforged.bus/net.neoforged.bus.api.BusBuilder.lambda$markerType$0(BusBuilder.java:25) ~[bus-8.0.2.jar%23141!/:?]
	at MC-BOOTSTRAP/net.neoforged.bus/net.neoforged.bus.EventBus.registerListener(EventBus.java:162) ~[bus-8.0.2.jar%23141!/:?]
	... 16 more

I crash on runClient

package net.mattias.cobblesnapshot.event;

import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import com.cobblemon.mod.common.pokemon.Pokemon;
import net.mattias.cobblesnapshot.item.ModItems;
import net.minecraft.ChatFormatting;
import net.minecraft.core.component.DataComponents;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.component.CustomData;
import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class CameraUseEvents {

    @net.neoforged.bus.api.SubscribeEvent
    public static void onEntityRightClick(PlayerInteractEvent.EntityInteractSpecific event) {
        // We only want to do this on the server to prevent consuming items twice.
        if (event.getLevel().isClientSide()) return;

        if (!(event.getTarget() instanceof PokemonEntity target)) return;
        Player player = event.getEntity();
        ItemStack camera = player.getItemInHand(event.getHand());

        if (!camera.is(ModItems.CAMERA.get())) return;

        // Check for film in inventory
        int filmSlot = findFirstSlotWithItem(player, ModItems.FILM.get());
        if (filmSlot == -1) {
            player.sendSystemMessage(Component.literal("You need film to take a snapshot!").withStyle(ChatFormatting.RED));
            return;
        }

        // Get Pokémon data
        Pokemon pokemon = target.getPokemon();

        // Consume 1 film ONLY AFTER we know the operation is successful
        player.getInventory().removeItem(filmSlot, 1);

        // --- Create the Snapshot Item ---
        ItemStack snapshot = new ItemStack(ModItems.IMAGE_FILM.get());

        // Set custom name
        snapshot.set(DataComponents.CUSTOM_NAME, Component.literal("📸 Snapshot of " + pokemon.getDisplayName().getString()));

        // --- Store Metadata in CUSTOM_DATA ---
        CompoundTag tag = new CompoundTag();
        tag.putString("TakenBy", player.getName().getString());
        tag.putString("TakenOn", LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE));

        // Store Pokémon information for the image
        tag.putString("PokemonSpecies", pokemon.getSpecies().getName());
        tag.putString("PokemonForm", pokemon.getForm().getName());
        tag.putBoolean("IsShiny", pokemon.getShiny());

        // Store the Pokémon's display name for reference
        tag.putString("PokemonName", pokemon.getDisplayName().getString());

        // Apply the data to the item stack
        snapshot.set(DataComponents.CUSTOM_DATA, CustomData.of(tag));

        // Give item to player
        if (!player.addItem(snapshot)) {
            player.drop(snapshot, false);
        }

        player.sendSystemMessage(Component.literal("📸 You took a snapshot of " + pokemon.getDisplayName() + "!"));
        event.setCanceled(true);
        event.setCancellationResult(InteractionResult.SUCCESS);
    }

    private static int findFirstSlotWithItem(Player player, Item item) {
        for (int i = 0; i < player.getInventory().getContainerSize(); i++) {
            ItemStack stack = player.getInventory().getItem(i);
            if (stack.is(item)) return i;
        }
        return -1;
    }
}
package net.mattias.cobblesnapshot.item.custom;

import net.minecraft.core.component.DataComponents;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.item.component.CustomData;
import net.minecraft.ChatFormatting;

import java.util.List;

public class ImageFilmItem extends Item {
    public ImageFilmItem(Properties properties) {
        super(properties);
    }

    @Override
    public void appendHoverText(ItemStack stack, TooltipContext context, List<Component> tooltip, TooltipFlag flag) {
        super.appendHoverText(stack, context, tooltip, flag);

        CustomData customData = stack.get(DataComponents.CUSTOM_DATA);
        if (customData != null) {
            CompoundTag tag = customData.copyTag();

            // Add a separator line
            tooltip.add(Component.literal("─────────────────").withStyle(ChatFormatting.GRAY));

            if (tag.contains("PokemonName")) {
                tooltip.add(Component.literal("📸 " + tag.getString("PokemonName")).withStyle(ChatFormatting.YELLOW));
            }

            if (tag.contains("PokemonSpecies")) {
                String species = tag.getString("PokemonSpecies");
                String form = tag.contains("PokemonForm") ? tag.getString("PokemonForm") : "normal";
                boolean isShiny = tag.getBoolean("IsShiny");

                Component speciesComponent = Component.literal("Species: " + species)
                        .withStyle(ChatFormatting.AQUA);
                tooltip.add(speciesComponent);

                if (!form.equals("normal")) {
                    tooltip.add(Component.literal("Form: " + form).withStyle(ChatFormatting.LIGHT_PURPLE));
                }

                if (isShiny) {
                    tooltip.add(Component.literal("✨ Shiny!").withStyle(ChatFormatting.GOLD));
                }
            }

            if (tag.contains("TakenBy")) {
                tooltip.add(Component.literal("Photographer: " + tag.getString("TakenBy")).withStyle(ChatFormatting.GREEN));
            }

            if (tag.contains("TakenOn")) {
                tooltip.add(Component.literal("Date: " + tag.getString("TakenOn")).withStyle(ChatFormatting.GRAY));
            }
        }
    }

    @Override
    public boolean isFoil(ItemStack stack) {
        // Make the item have an enchanted glint to make it look special
        return true;
    }
}
package net.mattias.cobblesnapshot;

import net.mattias.cobblesnapshot.event.CameraUseEvents;
import net.mattias.cobblesnapshot.item.ModItems;
import org.slf4j.Logger;

import com.mojang.logging.LogUtils;

import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.ModContainer;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.fml.common.Mod;
import net.neoforged.fml.config.ModConfig;
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.event.server.ServerStartingEvent;

// The value here should match an entry in the META-INF/neoforge.mods.toml file
@Mod(CobbleSnapshot.MOD_ID)
public class CobbleSnapshot
{
    // Define mod id in a common place for everything to reference
    public static final String MOD_ID = "cobblesnapshot";
    // Directly reference a slf4j logger
    private static final Logger LOGGER = LogUtils.getLogger();

    public CobbleSnapshot(IEventBus modEventBus, ModContainer modContainer) {


        NeoForge.EVENT_BUS.register(this);


        ModItems.register(modEventBus);
        modEventBus.register(CameraUseEvents.class);
        modContainer.registerConfig(ModConfig.Type.COMMON, Config.SPEC);
    }

    private void commonSetup(final FMLCommonSetupEvent event) {

    }



    // You can use SubscribeEvent and let the Event Bus discover methods to call
    @SubscribeEvent
    public void onServerStarting(ServerStartingEvent event) {

    }

    // You can use EventBusSubscriber to automatically register all static methods in the class annotated with @SubscribeEvent
    @EventBusSubscriber(modid = MOD_ID, bus = EventBusSubscriber.Bus.MOD, value = Dist.CLIENT)
    public static class ClientModEvents {
        @SubscribeEvent
        public static void onClientSetup(FMLClientSetupEvent event) {

        }
    }
}
package net.mattias.cobblesnapshot.item;

import net.mattias.cobblesnapshot.CobbleSnapshot;
import net.mattias.cobblesnapshot.item.custom.ImageFilmItem; // <-- Import your custom item
import net.minecraft.world.item.Item;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.neoforge.registries.DeferredItem;
import net.neoforged.neoforge.registries.DeferredRegister;

public class ModItems {
    public static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(CobbleSnapshot.MOD_ID);

    public static final DeferredItem<Item> CAMERA = ITEMS.register("camera", () ->
            new Item(new Item.Properties().stacksTo(1)));

    public static final DeferredItem<Item> FILM = ITEMS.register("film", () ->
            new Item(new Item.Properties()));

    public static final DeferredItem<Item> IMAGE_FILM = ITEMS.register("image_film", () ->
            new ImageFilmItem(new Item.Properties().stacksTo(1)));

    public static void register(IEventBus eventBus) {
        ITEMS.register(eventBus);
    }
}