Posted June 20, 20178 yr Hi, I'm trying the new registry using events, but I seem to get a nullpointer exception. The console is not helping at all. Here's my code. Main class. @Mod(modid = Reference.ID, name = Reference.NAME, version = Reference.VERSION, acceptedMinecraftVersions = "[" + Reference.MC_VERSION + "]") public class AutoMiner { @Instance public static AutoMiner INSTANCE = new AutoMiner(); @SidedProxy(clientSide = Reference.CLIENT_PROXY, serverSide = Reference.COMMON_PROXY) public static CommonProxy PROXY = new CommonProxy(); @EventHandler public static void preInit(FMLPreInitializationEvent event) { MinecraftForge.EVENT_BUS.register(new AMRegistryHandler()); new AMItems(); new AMBlocks(); new AMEntities(); new AMRecipes(); PROXY.setTitle("Minecraft - " + Reference.MC_VERSION + " AutoMiner - " + Reference.VERSION); } @EventHandler public static void init(FMLInitializationEvent event) { } @EventHandler public static void postInit(FMLPostInitializationEvent event) { } } Handler. public class AMRegistryHandler { @SubscribeEvent public static void registerBlocks(RegistryEvent.Register<Block> event) { event.getRegistry().registerAll(AMBlocks.BLOCKS); } @SubscribeEvent public static void registerItems(RegistryEvent.Register<Item> event) { event.getRegistry().registerAll(AMItems.ITEMS); for (int i = 0; i < AMBlocks.BLOCKS.length; i++) { Block block = AMBlocks.BLOCKS[i]; event.getRegistry().register(new ItemBlock(block).setRegistryName(block.getRegistryName()) .setUnlocalizedName(block.getUnlocalizedName())); } } @SubscribeEvent public static void registerModels(ModelRegistryEvent event) { for (int i = 0; i < AMBlocks.BLOCKS.length; i++) { Block block = AMBlocks.BLOCKS[i]; ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(block), 0, new ModelResourceLocation(block.getRegistryName(), "inventory")); } for (int i = 0; i < AMItems.ITEMS.length; i++) { Item item = AMItems.ITEMS[i]; ModelLoader.setCustomModelResourceLocation(item, 0, new ModelResourceLocation(item.getRegistryName(), "inventory")); } } } Blocks class. public class AMBlocks { public static final Block STEEL_BLOCK = new Block(Material.IRON).setCreativeTab(AMTabs.AM_TAB).setHardness(8.0F) .setResistance(15.0F); public static final Block AUTO_MINER = new BlockAutoMiner().setCreativeTab(AMTabs.AM_TAB).setHardness(7.0F) .setResistance(20.0F); public static final Block[] BLOCKS = new Block[] { STEEL_BLOCK, AUTO_MINER }; public AMBlocks() { STEEL_BLOCK.setHarvestLevel("pickaxe", 2); AUTO_MINER.setHarvestLevel("pickaxe", 1); AMUtils.setNames(STEEL_BLOCK, "steel_block"); AMUtils.setNames(AUTO_MINER, "auto_miner"); } } Items class. public class AMItems { public static final Item STEEL_INGOT = new Item().setCreativeTab(AMTabs.AM_TAB); public static final Item WRENCH = new Item().setCreativeTab(AMTabs.AM_TAB).setMaxDamage(128).setMaxStackSize(1); public static final Item[] ITEMS = new Item[] { STEEL_INGOT, WRENCH }; public AMItems() { AMUtils.setNames(STEEL_INGOT, "steel_ingot"); AMUtils.setNames(WRENCH, "wrench"); } } Also, the error in the console. java.lang.NullPointerException: Initializing game at net.minecraft.client.util.SearchTree.lambda$func_194042_b$0(SearchTree.java:57) at java.util.ArrayList.forEach(Unknown Source) at net.minecraft.client.util.SearchTree.func_194042_b(SearchTree.java:55) at net.minecraft.client.util.SearchTree.func_194043_a(SearchTree.java:50) at java.util.ArrayList.forEach(Unknown Source) at net.minecraft.client.Minecraft.func_193986_ar(Minecraft.java:640) at net.minecraft.client.Minecraft.init(Minecraft.java:565) at net.minecraft.client.Minecraft.run(Minecraft.java:411) at net.minecraft.client.main.Main.main(Main.java:118) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) at net.minecraft.launchwrapper.Launch.main(Launch.java:28) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97) at GradleStart.main(GradleStart.java:26) Edited June 21, 20178 yr by Kokkie Classes: 94 Lines of code: 12173 Other files: 206 Github repo: https://github.com/KokkieBeer/DeGeweldigeMod
June 20, 20178 yr Registry events are fired before preInit, so you need to annotate the event handler class with @Mod.EventBusSubscriber to automatically register it at mod construction time (or register it manually). In addition to this, you're registering an instance of the event handler but your methods are static; which is incorrect. Static event handler methods require you to register the Class object rather than an instance, as explained in the documentation. You need to set the registry name of an IForgeRegistryEntry like Block or Item before you register it. Having a constructor modify static fields in a class where there there are no instance fields or methods and calling this constructor purely for the side-effects is very strange and probably a bad idea. If you need to do more stuff to the Items in preInit, create a regular static method instead of a constructor. ModelLoader is a client-only class and can't be referenced from common code. ModelRegistryEvent should be handled in a client-only class that's only registered with the event bus on the physical client (pass Side.CLIENT to the @Mod.EventBusSubscriber annotation or manually register it in a method only called on the physical client). Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.
June 21, 20178 yr Author I no longer get any errors, but the items and blocks aren't registered. The events aren't fired... Main. @Mod(modid = Reference.ID, name = Reference.NAME, version = Reference.VERSION, acceptedMinecraftVersions = "[" + Reference.MC_VERSION + "]") public class AutoMiner { @Instance public static AutoMiner INSTANCE = new AutoMiner(); @SidedProxy(clientSide = Reference.CLIENT_PROXY, serverSide = Reference.COMMON_PROXY) public static IProxy PROXY; @EventHandler public static void preInit(FMLPreInitializationEvent event) { PROXY.registerEntities(); PROXY.registerRecipes(); PROXY.setTitle("Minecraft - " + Reference.MC_VERSION + " AutoMiner - " + Reference.VERSION); } @EventHandler public static void init(FMLInitializationEvent event) { } @EventHandler public static void postInit(FMLPostInitializationEvent event) { } } IProxy. public interface IProxy { void setTitle(String title); void registerEntities(); void registerRecipes(); } CommonProxy. public class CommonProxy implements IProxy { @Override public void setTitle(String title) { } @Override public void registerEntities() { GameRegistry.registerTileEntity(TileEntityAutoMiner.class, "AutoMiner"); } @Override public void registerRecipes() { AMUtils.addShapedRecipe("wrench", new ItemStack(AMItems.WRENCH), "S S", "SSS", " S ", 'S', AMItems.STEEL_INGOT); AMUtils.addShapedRecipe("auto_miner", new ItemStack(AMBlocks.AUTO_MINER), "SSS", "SPS", "SSS", 'S', AMItems.STEEL_INGOT, 'P', Items.IRON_PICKAXE); } } ClientProxy. public class ClientProxy implements IProxy { @Override public void setTitle(String title) { Display.setTitle(title); } @Override public void registerEntities() { } @Override public void registerRecipes() { } } Blocks. public class AMBlocks { public static final Block STEEL_BLOCK = new Block(Material.IRON).setCreativeTab(AMTabs.AM_TAB).setHardness(8.0F) .setResistance(15.0F).setRegistryName("steel_block").setUnlocalizedName("steel_block"); public static final Block AUTO_MINER = new BlockAutoMiner().setCreativeTab(AMTabs.AM_TAB).setHardness(7.0F) .setResistance(20.0F).setRegistryName("auto_miner").setUnlocalizedName("auto_miner"); public static final Block[] BLOCKS = new Block[] { STEEL_BLOCK, AUTO_MINER }; } Items. public class AMItems { public static final Item STEEL_INGOT = new Item().setCreativeTab(AMTabs.AM_TAB).setRegistryName("steel_ingot") .setUnlocalizedName("steel_ingot"); public static final Item WRENCH = new Item().setCreativeTab(AMTabs.AM_TAB).setMaxDamage(128).setMaxStackSize(1) .setRegistryName("wrench").setUnlocalizedName("wrench"); public static final Item[] ITEMS = new Item[] { STEEL_INGOT, WRENCH }; } Client Handler. @Mod.EventBusSubscriber(modid = Reference.ID, value = Side.CLIENT) public class AMClientHandler { @SubscribeEvent public void registerModels(ModelRegistryEvent event) { for (int i = 0; i < AMBlocks.BLOCKS.length; i++) { Block block = AMBlocks.BLOCKS[i]; ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(block), 0, new ModelResourceLocation(block.getRegistryName(), "inventory")); } for (int i = 0; i < AMItems.ITEMS.length; i++) { Item item = AMItems.ITEMS[i]; ModelLoader.setCustomModelResourceLocation(item, 0, new ModelResourceLocation(item.getRegistryName(), "inventory")); } } } Common Handler. @Mod.EventBusSubscriber(modid = Reference.ID, value = Side.SERVER) public class AMCommonHandler { @SubscribeEvent public void registerBlocks(RegistryEvent.Register<Block> event) { AMBlocks.STEEL_BLOCK.setHarvestLevel("pickaxe", 2); AMBlocks.AUTO_MINER.setHarvestLevel("pickaxe", 1); event.getRegistry().registerAll(AMBlocks.BLOCKS); } @SubscribeEvent public void registerItems(RegistryEvent.Register<Item> event) { event.getRegistry().registerAll(AMItems.ITEMS); for (int i = 0; i < AMBlocks.BLOCKS.length; i++) { Block block = AMBlocks.BLOCKS[i]; event.getRegistry().register(new ItemBlock(block).setRegistryName(block.getRegistryName()) .setUnlocalizedName(block.getUnlocalizedName())); } } } Classes: 94 Lines of code: 12173 Other files: 206 Github repo: https://github.com/KokkieBeer/DeGeweldigeMod
June 21, 20178 yr Author Everything registers fine (I think) but I, again, get the lambda nullpointer, why does this happen? Classes: 94 Lines of code: 12173 Other files: 206 Github repo: https://github.com/KokkieBeer/DeGeweldigeMod
June 21, 20178 yr Does this happen if you switch the for-loop to for-each loops? eg for(Block block : AMBlocks.BLOCKS){...} You can also try to switch over to lambda's. For arrays, you need to use Arrays.stream(array) to be able to call forEach() Also previously known as eAndPi. "Pi, is there a station coming up where we can board your train of thought?" -Kronnn Published Mods: Underworld Handy links: Vic_'s Forge events Own WIP Tutorials.
June 21, 20178 yr Author It seems to have gone away... But now it's stuck on the while loop in here... if (recipeComponents[i] instanceof String[]) { String[] astring = (String[]) ((String[]) recipeComponents[i++]); for (int s3 = 0; s3 < astring.length; s3++) { String s2 = astring[s3]; ++k; j = s2.length(); s = s + s2; } } else { while (recipeComponents[i] instanceof String) { String s1 = (String) recipeComponents[i++]; ++k; j = s1.length(); s = s + s1; } } Classes: 94 Lines of code: 12173 Other files: 206 Github repo: https://github.com/KokkieBeer/DeGeweldigeMod
June 21, 20178 yr Author When the code reaches the while loop it freezes the game and opens the debug perspective telling me something about the while loop... Edited June 21, 20178 yr by Kokkie Classes: 94 Lines of code: 12173 Other files: 206 Github repo: https://github.com/KokkieBeer/DeGeweldigeMod
June 21, 20178 yr I see 2 possible exit conditions to this loop: 1. recipeComponents is not a string, the loop exits normally. 2. i => recipeComponents.length(the last element of the recipeComponents array is a string), the loop throws an ArrayIndexOutOfBounds exception and the exception is passed along potentially crashing the game. That could be your issue. 1 hour ago, Kokkie said: (String[]) ((String[]) recipeComponents[i++]); Why is there a String[] to String[] cast? Isn't it a tad bit redundant? Edited June 21, 20178 yr by V0idWa1k3r
June 21, 20178 yr Author I fixed the problem there, but it seems like the lambda nullpointer didn't go away, but the code didn't get far enough to reach a lambda... So, please help. I can't find what causes it because the console doesn't give any information... Classes: 94 Lines of code: 12173 Other files: 206 Github repo: https://github.com/KokkieBeer/DeGeweldigeMod
June 21, 20178 yr Set a breakpoint in the lambda with the condition p_194039_2_ == null. When the breakpoint is hit, look at the value of the element parameter to see which Item has a null registry name. Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.
June 21, 20178 yr 3 hours ago, Kokkie said: @Mod.EventBusSubscriber(modid = Reference.ID, value = Side.SERVER) Correct me if I'm wrong but I think that this value param is dictating the physical side for the forge to run the subscribption on(FMLCommonHandler::getSide) and not the logical side(FMLCommonHandler::getEffectiveSide)? Therefore if the SERVER is specified as a side here would FML not subscribe the class to the event bus unless the code is running on an actual server(that is the Minecraft Server is chosen as a run configuration or the user launches a server)? In any case blocks(and items) being in the registry is a common thing. It makes no sense for them to only be present on the server, the client needs to know about them too. Edited June 21, 20178 yr by V0idWa1k3r
June 21, 20178 yr Author 40 minutes ago, Choonster said: Set a breakpoint in the lambda with the condition p_194039_2_ == null. When the breakpoint is hit, look at the value of the element parameter to see which Item has a null registry name. How can I set that condition? Classes: 94 Lines of code: 12173 Other files: 206 Github repo: https://github.com/KokkieBeer/DeGeweldigeMod
June 21, 20178 yr Author Where can I find which item it is? Classes: 94 Lines of code: 12173 Other files: 206 Github repo: https://github.com/KokkieBeer/DeGeweldigeMod
June 21, 20178 yr When the breakpoint is hit inspect the locals in that method. Your culprit is within the parameter of the method if I assume the method usage correctly.
June 21, 20178 yr Author Here? Classes: 94 Lines of code: 12173 Other files: 206 Github repo: https://github.com/KokkieBeer/DeGeweldigeMod
June 21, 20178 yr Well expand the RecipeList(p_194042_1_) and see the recipes that it contains. One of those recipes has no registry name set for it's output(the one that has one of your items/blocks as it's output)
June 21, 20178 yr Author When I remove the recipe for the wrench, it works, but I set the registry name for the wrench... Also, it seems like the items aren't registered properly yet. They don't show up in the tab and I can't give them to me using /give... Classes: 94 Lines of code: 12173 Other files: 206 Github repo: https://github.com/KokkieBeer/DeGeweldigeMod
June 21, 20178 yr Have you removed 4 hours ago, Kokkie said: value = Side.SERVER from your 4 hours ago, Kokkie said: AMCommonHandler 's EventBusSubscriber annotation(that you have now called AMServerHandler)? Just leave the annotation be as EventBusSubscriber(modid = Reference.ID) and check if that helps. As I've said objects being in registry is common for both client and server, it makes no sense for the server only to have them registered, the client needs it too. Edited June 21, 20178 yr by V0idWa1k3r
June 21, 20178 yr Author Also, go here for code. https://github.com/KokkieBeer/Auto-Miner Classes: 94 Lines of code: 12173 Other files: 206 Github repo: https://github.com/KokkieBeer/DeGeweldigeMod
June 21, 20178 yr Author 3 minutes ago, V0idWa1k3r said: value = Side.SERVER Removed it, didn't work. Classes: 94 Lines of code: 12173 Other files: 206 Github repo: https://github.com/KokkieBeer/DeGeweldigeMod
June 21, 20178 yr Your methods in the AMServerHandler(and in your AMClientHandler) are not annotated with SubscribeEvent. Even if you annotate the class with EventBusSubscriber you still need to annotate the methods that you want to be listening for the event specified. Also CraftingManager.register is private in the latest versions of forge, so you must use the appropriate registry event.
June 21, 20178 yr Author 5 minutes ago, V0idWa1k3r said: Your methods in the AMServerHandler(and in your AMClientHandler) are not annotated with SubscribeEvent. Even if you annotate the class with EventBusSubscriber you still need to annotate the methods that you want to be listening for the event specified. Just noticed that :D. 5 minutes ago, V0idWa1k3r said: Also CraftingManager.register is private in the latest versions of forge, so you must use the appropriate registry event. Is the event in newer versions of Forge? (I have 14.21.0.2321) Also, the wrench recipe now works :D. Edited June 21, 20178 yr by Kokkie Classes: 94 Lines of code: 12173 Other files: 206 Github repo: https://github.com/KokkieBeer/DeGeweldigeMod
June 21, 20178 yr IRecipe is a IForgeRegistryEntry as are all it's implementations at least in 14.21.0.2343 so there should be an event for them. Not sure about the version you are using. The recipes and registries have been going through a lot of changes recently and will go through a lot more so I usually try to stay on the latest available version so I have the chance to adapt to the changes gradualy instead of having to rewrite everything once things settle down.
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.