Posted January 27, 20205 yr Hi all, I've just begun updating my 1.12.2 mod to 1.15.2 (big task!) and I have a couple of questions to ask so I can start off the right way and don't run into issues regarding the basic setup of the mod later on: 1) What is the "Forge Approved" method for registering Items and Blocks? Similarly to 1.12.2, Items and Blocks etc are registered using @Mod.EventBusSubscriber(modid = Main.MODID, bus = Mod.EventBusSubscriber.Bus.MOD) ...and then subscribing a method to events and passing in the correct Registry Event as a parameter. @SubscribeEvent public static void registerBlocks(RegistryEvent.Register<Block> event) { Main.LOGGER.info("Doing registration of Blocks for MODID : " + Main.MODID); event.getRegistry().registerAll(AMETHYST_BLOCK); } public static final Block AMETHYST_BLOCK = new Block(Properties.create(Material.GLASS).harvestTool(ToolType.PICKAXE) .sound(SoundType.GLASS).lightValue(8).hardnessAndResistance(3F, 3F).slipperiness(0.1F)) .setRegistryName(Main.MODID, "amethyst_block"); This is slightly different in syntax to 1.12.2 but a very similar idea. ===== 2) Where does @ObjectHolder come into all of this? What is its purpose? ===== 3) How do BlockItems work? I assume there's a reason for their existence, but what is it? Here's what I'm currently using but I don't know if any of this is correct / the done-thing? @SubscribeEvent public static void registerBlockItems(RegistryEvent.Register<Item> event) { event.getRegistry().registerAll( new BlockItem(EvileBlocks.AMETHYST_BLOCK, new Item.Properties().maxStackSize(64).group(ItemGroup.BUILDING_BLOCKS)) .setRegistryName(EvileBlocks.AMETHYST_BLOCK.getRegistryName()) ); } ===== 4) Any good tutorials? So far I've been using a mix of mcforge.readthedocs.io and the MC source code. Unfortunately, readthedocs doesn't give some of the basic practical information needed (eg What resources does a Block need? I believe it needs a model, blockstate and a loot table?) ; and MC source, while great for examples, doesn't explain anything (although with time and effort you can often work out what's happening). In 1.12.2 I used HarryTalks until @Draco18s kindly explained why I shouldn't in this post (Don't worry I'm cured now ) ===== Anyway that's certainly enough questions for one post -- someone let me know if each one of these should be in its own topic, but I figured that these are perhaps small enough to be grouped! Thanks! How to ask a good coding question: https://stackoverflow.com/help/how-to-ask Give logs, code, desired effects, and actual effects. Be thorough or we can't help you. Don't post code without putting it in a code block (the <> button on the post - select "C-type Language"): syntax highlighting makes everything easier, and it keeps the post tidy. My own mod, Magiks Most Evile: GitHub (https://github.com/GenElectrovise/MagiksMostEvile) Wiki (https://magiksmostevile.fandom.com/wiki/Magiks_Most_Evile_Wiki) Edit your own signature at https://www.minecraftforge.net/forum/settings/signature/
January 27, 20205 yr 3 minutes ago, GenElectrovise said: What is the "Forge Approved" method for registering Items and Blocks? The registry event is fine, but the deferred system is the current and new thing. I am blanking on what it's actually called, but it basically combines registration and @ObjectHolder functionality. 5 minutes ago, GenElectrovise said: Where does @ObjectHolder come into all of this? What is its purpose? https://mcforge.readthedocs.io/en/1.15.x/concepts/registries/#injecting-registry-values-into-fields @ObjectHolder lets you assign values to fields so that you can have a reference to any registry object (blocks, items, enchantments, etc) without having to create a hard dependency as well as cleanly handle overrides (i.e. you have one mod that supplies a block, then another mod comes along and supplies a replacement for that block to add its own functionality, your object holder field will reference the correct block--this is true for vanilla objects, your objects, and other mod's objects). 7 minutes ago, GenElectrovise said: How do BlockItems work? Blocks do not (and cannot) exist in your inventory. What is in your inventory is an ItemStack and ItemStacks only hold Items. Blocks are not items. The way to "get around" this limitation is the BlockItem. It is the item form of a block. Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable. If you think this is the case, JUST REPORT ME. Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice. Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked. DO NOT PM ME WITH PROBLEMS. No help will be given.
January 27, 20205 yr Author Hi all! Thanks for the responses! I now see the point of BlockItems! 16 minutes ago, diesieben07 said: Use DeferredRegister (read it's Javadoc for more info). You can also use the events, just as before, if you so choose. However you must not create your registry entries in a static initializer like you've shown (this is even true in 1.12.2). Ok so here's what I have now with this info: (Trying to register AMETHYST_BLOCK and its BlockItem) Spoiler public class EvileRegistry { private static final DeferredRegister<Item> ITEMS = new DeferredRegister<>(ForgeRegistries.ITEMS, Main.MODID); private static final DeferredRegister<Block> BLOCKS = new DeferredRegister<>(ForgeRegistries.BLOCKS, Main.MODID); //=========BLOCKS====================================================================================================================== public static final RegistryObject<Block> AMETHYST_BLOCK = BLOCKS.register("amethyst_block", () -> new Block(Block.Properties.create(Material.GLASS).harvestTool(ToolType.PICKAXE).sound(SoundType.GLASS) .lightValue(8).hardnessAndResistance(3F, 3F).slipperiness(0.1F)).setRegistryName(Main.MODID, "amethyst_block")); //=========ITEMS======================================================================================================================= public static final RegistryObject<Item> AMETHYST_BLOCK_ITEM = ITEMS.register("amethyst_block", () -> new BlockItem(AMETHYST_BLOCK.get(), new Item.Properties().group(ItemGroup.MISC))); //=========CONSTRUCTOR================================================================================================================= public EvileRegistry() { Main.LOGGER.debug("Constructing EvileRegistry!"); Main.LOGGER.debug("Log Key 182727012020 : FMLJavaModLoadingContext = " + FMLJavaModLoadingContext.get()); BLOCKS.register(FMLJavaModLoadingContext.get().getModEventBus()); ITEMS.register(FMLJavaModLoadingContext.get().getModEventBus()); } } However, I've played around a bit with it and every time I get this error: Spoiler java.lang.RuntimeException: java.lang.reflect.InvocationTargetException at net.minecraftforge.fml.javafmlmod.FMLJavaModLanguageProvider$FMLModTarget.loadMod(FMLJavaModLanguageProvider.java:78) ~[forge-1.15.2-31.0.0_mapped_snapshot_20190719-1.14.3-recomp.jar:31.0] {} at net.minecraftforge.fml.ModLoader.buildModContainerFromTOML(ModLoader.java:234) ~[forge-1.15.2-31.0.0_mapped_snapshot_20190719-1.14.3-recomp.jar:?] {re:classloading} at net.minecraftforge.fml.ModLoader.lambda$buildMods$26(ModLoader.java:214) ~[forge-1.15.2-31.0.0_mapped_snapshot_20190719-1.14.3-recomp.jar:?] {re:classloading} at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) ~[?:1.8.0_241] {} at java.util.HashMap$EntrySpliterator.forEachRemaining(HashMap.java:1699) ~[?:1.8.0_241] {} at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482) ~[?:1.8.0_241] {} at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472) ~[?:1.8.0_241] {} at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) ~[?:1.8.0_241] {} at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[?:1.8.0_241] {} at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) ~[?:1.8.0_241] {} at net.minecraftforge.fml.ModLoader.buildMods(ModLoader.java:216) ~[forge-1.15.2-31.0.0_mapped_snapshot_20190719-1.14.3-recomp.jar:?] {re:classloading} at net.minecraftforge.fml.ModLoader.lambda$gatherAndInitializeMods$18(ModLoader.java:173) ~[forge-1.15.2-31.0.0_mapped_snapshot_20190719-1.14.3-recomp.jar:?] {re:classloading} at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) ~[?:1.8.0_241] {} at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) ~[?:1.8.0_241] {} at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382) ~[?:1.8.0_241] {} at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482) ~[?:1.8.0_241] {} at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472) ~[?:1.8.0_241] {} at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) ~[?:1.8.0_241] {} at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[?:1.8.0_241] {} at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) ~[?:1.8.0_241] {} at net.minecraftforge.fml.ModLoader.gatherAndInitializeMods(ModLoader.java:175) ~[forge-1.15.2-31.0.0_mapped_snapshot_20190719-1.14.3-recomp.jar:?] {re:classloading} at net.minecraftforge.fml.client.ClientModLoader.lambda$begin$2(ClientModLoader.java:97) ~[forge-1.15.2-31.0.0_mapped_snapshot_20190719-1.14.3-recomp.jar:?] {re:classloading,pl:runtimedistcleaner:A} at net.minecraftforge.fml.client.ClientModLoader.lambda$createRunnableWithCatch$5(ClientModLoader.java:113) ~[forge-1.15.2-31.0.0_mapped_snapshot_20190719-1.14.3-recomp.jar:?] {re:classloading,pl:runtimedistcleaner:A} at net.minecraftforge.fml.client.ClientModLoader.begin(ClientModLoader.java:97) ~[forge-1.15.2-31.0.0_mapped_snapshot_20190719-1.14.3-recomp.jar:?] {re:classloading,pl:runtimedistcleaner:A} at net.minecraft.client.Minecraft.<init>(Minecraft.java:394) ~[forge-1.15.2-31.0.0_mapped_snapshot_20190719-1.14.3-recomp.jar:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A} at net.minecraft.client.main.Main.main(Main.java:141) ~[forge-1.15.2-31.0.0_mapped_snapshot_20190719-1.14.3-recomp.jar:?] {re:classloading,pl:runtimedistcleaner:A} at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_241] {} at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_241] {} at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_241] {} at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_241] {} at net.minecraftforge.userdev.FMLUserdevClientLaunchProvider.lambda$launchService$0(FMLUserdevClientLaunchProvider.java:55) ~[forge-1.15.2-31.0.0_mapped_snapshot_20190719-1.14.3-recomp.jar:?] {} at cpw.mods.modlauncher.LaunchServiceHandlerDecorator.launch(LaunchServiceHandlerDecorator.java:37) [modlauncher-5.0.0-milestone.4.jar:?] {} at cpw.mods.modlauncher.LaunchServiceHandler.launch(LaunchServiceHandler.java:54) [modlauncher-5.0.0-milestone.4.jar:?] {} at cpw.mods.modlauncher.LaunchServiceHandler.launch(LaunchServiceHandler.java:72) [modlauncher-5.0.0-milestone.4.jar:?] {} at cpw.mods.modlauncher.Launcher.run(Launcher.java:81) [modlauncher-5.0.0-milestone.4.jar:?] {} at cpw.mods.modlauncher.Launcher.main(Launcher.java:65) [modlauncher-5.0.0-milestone.4.jar:?] {} at net.minecraftforge.userdev.LaunchTesting.main(LaunchTesting.java:101) [forge-1.15.2-31.0.0_mapped_snapshot_20190719-1.14.3-recomp.jar:?] {} Caused by: java.lang.reflect.InvocationTargetException at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:1.8.0_241] {} at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[?:1.8.0_241] {} at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[?:1.8.0_241] {} at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[?:1.8.0_241] {} at net.minecraftforge.fml.javafmlmod.FMLJavaModLanguageProvider$FMLModTarget.loadMod(FMLJavaModLanguageProvider.java:73) ~[forge-1.15.2-31.0.0_mapped_snapshot_20190719-1.14.3-recomp.jar:31.0] {} ... 36 more Caused by: net.minecraftforge.fml.ModLoadingException: Magiks Most Evile has class loading errors null at net.minecraftforge.fml.javafmlmod.FMLModContainer.<init>(FMLModContainer.java:77) ~[forge-1.15.2-31.0.0_mapped_snapshot_20190719-1.14.3-recomp.jar:31.0] {re:classloading} at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:1.8.0_241] {} at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[?:1.8.0_241] {} at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[?:1.8.0_241] {} at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[?:1.8.0_241] {} at net.minecraftforge.fml.javafmlmod.FMLJavaModLanguageProvider$FMLModTarget.loadMod(FMLJavaModLanguageProvider.java:73) ~[forge-1.15.2-31.0.0_mapped_snapshot_20190719-1.14.3-recomp.jar:31.0] {} ... 36 more Caused by: java.lang.ExceptionInInitializerError at java.lang.Class.forName0(Native Method) ~[?:1.8.0_241] {} at java.lang.Class.forName(Class.java:348) ~[?:1.8.0_241] {} at net.minecraftforge.fml.javafmlmod.FMLModContainer.<init>(FMLModContainer.java:71) ~[forge-1.15.2-31.0.0_mapped_snapshot_20190719-1.14.3-recomp.jar:31.0] {re:classloading} at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:1.8.0_241] {} at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[?:1.8.0_241] {} at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[?:1.8.0_241] {} at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[?:1.8.0_241] {} at net.minecraftforge.fml.javafmlmod.FMLJavaModLanguageProvider$FMLModTarget.loadMod(FMLJavaModLanguageProvider.java:73) ~[forge-1.15.2-31.0.0_mapped_snapshot_20190719-1.14.3-recomp.jar:31.0] {} ... 36 more Caused by: java.lang.NullPointerException at genelectrovise.magiksmostevile.common.main.EvileRegistry.<init>(EvileRegistry.java:39) ~[main/:?] {re:classloading} at genelectrovise.magiksmostevile.common.main.Main.<clinit>(Main.java:21) ~[main/:?] {re:classloading} at java.lang.Class.forName0(Native Method) ~[?:1.8.0_241] {} at java.lang.Class.forName(Class.java:348) ~[?:1.8.0_241] {} at net.minecraftforge.fml.javafmlmod.FMLModContainer.<init>(FMLModContainer.java:71) ~[forge-1.15.2-31.0.0_mapped_snapshot_20190719-1.14.3-recomp.jar:31.0] {re:classloading} at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:1.8.0_241] {} at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[?:1.8.0_241] {} at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[?:1.8.0_241] {} at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[?:1.8.0_241] {} at net.minecraftforge.fml.javafmlmod.FMLJavaModLanguageProvider$FMLModTarget.loadMod(FMLJavaModLanguageProvider.java:73) ~[forge-1.15.2-31.0.0_mapped_snapshot_20190719-1.14.3-recomp.jar:31.0] {} ... 36 more Now looking at this I can see that the error occurs in the last "section" because (according to my logging code) the FMLJavaModLoadingContext is null. Here's my Main class. Spoiler @Mod(Main.MODID) @Mod.EventBusSubscriber(modid = Main.MODID, bus = Mod.EventBusSubscriber.Bus.MOD) public class Main { public static final Logger LOGGER = LogManager.getLogger(); public static final String MODID = "magiksmostevile"; public static final String VERSION = "1.0"; public static final String NAME = "MagiksMostEvile"; public static final String ACCEPTED_VERSIONS = "1.15.2"; public static Main instance = new Main(); public static final EvileRegistry EVILE_REGISTRY = new EvileRegistry(); public Main() { LOGGER.info("Welcome to Magiks Most Evile! Hello from the Main class! (If you can see this message, Magiks Most Evile is being loaded by Forge! Woohoo!)"); Main.LOGGER.debug("Log Key 182927012020 : FMLJavaModLoadingContext = " + FMLJavaModLoadingContext.get()); } } Perhaps it's got something to do with a faulty annotation to "declare" my mod? I gotta try getting this onto GitHub before it gets too big How to ask a good coding question: https://stackoverflow.com/help/how-to-ask Give logs, code, desired effects, and actual effects. Be thorough or we can't help you. Don't post code without putting it in a code block (the <> button on the post - select "C-type Language"): syntax highlighting makes everything easier, and it keeps the post tidy. My own mod, Magiks Most Evile: GitHub (https://github.com/GenElectrovise/MagiksMostEvile) Wiki (https://magiksmostevile.fandom.com/wiki/Magiks_Most_Evile_Wiki) Edit your own signature at https://www.minecraftforge.net/forum/settings/signature/
January 27, 20205 yr Author Ahhh thanks! That works! For any future modders looking through this thread, here are my completed classes: Spoiler public class EvileRegistry { private static final DeferredRegister<Item> ITEMS = new DeferredRegister<>(ForgeRegistries.ITEMS, Main.MODID); private static final DeferredRegister<Block> BLOCKS = new DeferredRegister<>(ForgeRegistries.BLOCKS, Main.MODID); //=========BLOCKS====================================================================================================================== public static final RegistryObject<Block> AMETHYST_BLOCK = BLOCKS.register("amethyst_block", () -> new Block(Block.Properties.create(Material.GLASS).harvestTool(ToolType.PICKAXE).sound(SoundType.GLASS) .lightValue(8).hardnessAndResistance(3F, 3F).slipperiness(0.1F))); //=========ITEMS======================================================================================================================= public static final RegistryObject<Item> AMETHYST_BLOCK_ITEM = ITEMS.register("amethyst_block", () -> new BlockItem(AMETHYST_BLOCK.get(), new Item.Properties().group(ItemGroup.MISC))); //=========CONSTRUCTOR================================================================================================================= public EvileRegistry() { BLOCKS.register(FMLJavaModLoadingContext.get().getModEventBus()); ITEMS.register(FMLJavaModLoadingContext.get().getModEventBus()); } } Spoiler @Mod(Main.MODID) @Mod.EventBusSubscriber(modid = Main.MODID, bus = Mod.EventBusSubscriber.Bus.MOD) public class Main { public static final Logger LOGGER = LogManager.getLogger(); public static final String MODID = "magiksmostevile"; public static final String VERSION = "1.0"; public static final String NAME = "MagiksMostEvile"; public static final String ACCEPTED_VERSIONS = "1.15.2"; public Main() { LOGGER.info("Welcome to Magiks Most Evile! Hello from the Main class! (If you can see this message, Magiks Most Evile is being loaded by Forge! Woohoo!)"); new EvileRegistry(); } } How to ask a good coding question: https://stackoverflow.com/help/how-to-ask Give logs, code, desired effects, and actual effects. Be thorough or we can't help you. Don't post code without putting it in a code block (the <> button on the post - select "C-type Language"): syntax highlighting makes everything easier, and it keeps the post tidy. My own mod, Magiks Most Evile: GitHub (https://github.com/GenElectrovise/MagiksMostEvile) Wiki (https://magiksmostevile.fandom.com/wiki/Magiks_Most_Evile_Wiki) Edit your own signature at https://www.minecraftforge.net/forum/settings/signature/
January 27, 20205 yr Author I'll mark this as solved now -- I'll probably be opening many more soon though! -GenElectrovise How to ask a good coding question: https://stackoverflow.com/help/how-to-ask Give logs, code, desired effects, and actual effects. Be thorough or we can't help you. Don't post code without putting it in a code block (the <> button on the post - select "C-type Language"): syntax highlighting makes everything easier, and it keeps the post tidy. My own mod, Magiks Most Evile: GitHub (https://github.com/GenElectrovise/MagiksMostEvile) Wiki (https://magiksmostevile.fandom.com/wiki/Magiks_Most_Evile_Wiki) Edit your own signature at https://www.minecraftforge.net/forum/settings/signature/
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.