Jump to content

[1.15.2] [Solved] Starting Advice (Registering, ObjectHolder, BlockItems, Tutorials)


GenElectrovise

Recommended Posts

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/

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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/

Link to comment
Share on other sites

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/

Link to comment
Share on other sites

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/

Link to comment
Share on other sites

  • GenElectrovise changed the title to [1.15.2] [Solved] Starting Advice (Registering, ObjectHolder, BlockItems, Tutorials)

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.