I am using NeoForge to make a Minecraft mod, following this tutorial
I noticed that when I add ModItems.register(modEventBus);
my game crashes with the following error:
Minecraft Error
Main class:
package net.ohusq.emeraldutils;
import net.minecraft.world.item.CreativeModeTabs;
import net.ohusq.emeraldutils.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.BuildCreativeModeTabContentsEvent;
import net.neoforged.neoforge.event.server.ServerStartingEvent;
// The value here should match an entry in the META-INF/neoforge.mods.toml file
@Mod(EmeraldUtils.MOD_ID)
public class EmeraldUtils
{
public static final String MOD_ID = "emeraldutils";
private static final Logger LOGGER = LogUtils.getLogger();
// The constructor for the mod class is the first code that is run when your mod is loaded.
// FML will recognize some parameter types like IEventBus or ModContainer and pass them in automatically.
public EmeraldUtils(IEventBus modEventBus, ModContainer modContainer)
{
// Register the commonSetup method for modloading
modEventBus.addListener(this::commonSetup);
// Register ourselves for server and other game events we are interested in.
// Note that this is necessary if and only if we want *this* class (ExampleMod) to respond directly to events.
// Do not add this line if there are no @SubscribeEvent-annotated functions in this class, like onServerStarting() below.
NeoForge.EVENT_BUS.register(this);
ModItems.register(modEventBus); // ERROR HERE
// Register the item to a creative tab
modEventBus.addListener(this::addCreative);
// Register our mod's ModConfigSpec so that FML can create and load the config file for us
modContainer.registerConfig(ModConfig.Type.COMMON, Config.SPEC);
}
private void commonSetup(final FMLCommonSetupEvent event) {
}
// Add the example block item to the building blocks tab
private void addCreative(BuildCreativeModeTabContentsEvent event) {
if(event.getTabKey() == CreativeModeTabs.INGREDIENTS) {
event.accept(ModItems.BISMUTH);
}
}
// 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)
{
}
}
}
Which issue could cause this to happen? My repository: https://github.com/ohusq/NeoForge-Tutorial
I have tried removing some lines to see which part made it error.
I believe you're just calling .register
rather than .registerItem
here in your ModItems.java
:
public static final DeferredItem<Item> BISMUTH = ITEMS.register("bismuth",
// ^^^^^^^^^
// this should be .registerItem
() -> new Item(new Item.Properties()));
If you swap that out, I believe it should work.
This is also discussed in the documentation, which also helps explain why you got the error that you got.
When discussing Item.Properties
, they say:
setId - Sets the resource key of the item.
- This must be set on every item; otherwise, an exception will be thrown.
Then, when discussing registerItem
, they say:
Internally, this will simply call
ITEMS.register("example_item", registryName -> new Item(new Item.Properties().setId(ResourceKey.create(Registries.ITEM, registryName))))
The error that you're getting is that it can't find the ID for the item, because setId
hasn't been called. Calling registerItem
instead of register
fixes it, because as they show, internally registerItem
calls setId
for you (it's just a little helper method). But, in theory, you could also the issue by calling setId
on Item.properties()
yourself (although I don't think that's too useful unless you're actually wanting to customise more of the properties too).
In general, I think the offical documentation is actually pretty good, at least for most of the common stuff you'll run into when starting out; I'd highly recommend reading through it when you run into problems, and seeing if your general approach and understanding matches what they describe.