Jump to content

How Items Are Registered.


Alex S.

Recommended Posts

So I'm new at modding using Forge, so I'm following a tutorial on how to make a custom item. I typed some code like this (where tutorialItem is my custom item):

@SubscribeEvent
     public static void registerItems(RegistryEvent.Register<Item> event)

     event.getRegistry().registerAll(tutorialItem)

Can somebody tell me what this explicitly does? From my guess, it registers an array of Item objects, then uses the registry key generated to assign a registry key to tutorialItem. But how? I looked at the code further up the tree (RegistryEvent and Register) and they look like Latin to me.

Link to comment
Share on other sites

26 minutes ago, Alex S. said:

So I'm new at modding using Forge, so I'm following a tutorial on how to make a custom item. I typed some code like this (where tutorialItem is my custom item):

@SubscribeEvent
     public static void registerItems(RegistryEvent.Register<Item> event)

     event.getRegistry().registerAll(tutorialItem)

Can somebody tell me what this explicitly does? From my guess, it registers an array of Item objects, then uses the registry key generated to assign a registry key to tutorialItem. But how? I looked at the code further up the tree (RegistryEvent and Register) and they look like Latin to me. 

Every Item has a registry name that is stored in its instance, since Items, Blocks, etc are singletons there is only one instance. The registry name is then mapped to the instance think Map<RegistryName, Item>.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

The most important thing to understand is that in Minecraft, both Item and Block classes are used as "singletons". This means there is only one instance created for each (e.g. new ItemAxe()) in the entire game. But of course while playing the game it seems like there are lots of items and lots of blocks, so how does that happen? Well, items and blocks do it differently...

 

Items always exist in an ItemStack instance (which adds quantity, damage, other NBT data to make the stack unique). So there is only one ItemAxe instance but there could be lots of ItemStack(ItemAxe) instances. Even for a single item there is an item stack with quantity 1. So each Item class (which is what gets registered) has only one instance, and all item stacks related to that item point to that one instance.

 

Blocks use a different way of propagating in the world. The presence of a block in the world is stored very compactly in the chunk/world data. There is not a new Block instance created for each block placed, instead the chunk just gets a reference that says "in this BlockPos there is this type of block". Additionally, the same block can have somewhat different behavior/looks though so each block is allowed 4 bits (16 values) of "metadata". The metadata represents a Property of the block at that location -- for example, the direction a furnace is facing would be stored in the metadata.

 

Back to the registries: My point then is that there is only one instance of each Item class and each Block class in the entire game. The registries contain these. This is important because it means that you can do a full comparison using Java == and otherwise it keeps the memory and disk space more compact.

 

Tip: You don't have to use the registries to access the instances. There are constants that represent them for vanilla, and you should do the same. For example, Blocks.VINE or Items.SWORD.

 

Note that Entity classes do not work that way -- a new instance is created every time. So the entity registry works a bit differently and is more like a factory. This is okay because there are a lot less entities in the world than blocks (a single chunk can have 65,536 blocks!).

Edited by jabelar
  • Like 1

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

Oh this is too good! Jabelar, I'm using your tutorials as a supplement to the other tutorial I'm following.

From what I understand you're saying, "RegistryEvent.Register<Item> event" is giving a name to the Item instance that's registered, and from there "getRegistry.registerAll(tutorialItem)" is adding/registering tutorialItem with the instance?

Link to comment
Share on other sites

20 minutes ago, Alex S. said:

Oh this is too good! Jabelar, I'm using your tutorials as a supplement to the other tutorial I'm following.

From what I understand you're saying, "RegistryEvent.Register<Item> event" is giving a name to the Item instance that's registered, and from there "getRegistry.registerAll(tutorialItem)" is adding/registering tutorialItem with the instance?

Yeah that is the general idea, although if you use the recommended @ObjectHolder annotation for populating the instances to the constants the order is a bit different.

 

The recommended way is to:

1) create a constant field (like I have a class called ModItems to contain these) that is initialized to null but annotated with @ObjectHolder.

2) handle the related registry event where you instantiate (using Java new operator) each item.

3) register each item.

4) The @ObjectHolders will automatically be updated after the event is finished firing.

 

Here is my ModItems class showing that sort of thing: https://github.com/jabelar/ExampleMod-1.12/blob/master/src/main/java/com/blogspot/jabelarminecraft/examplemod/init/ModItems.java

 

Note that I don't use the registerAll() method. Instead I just register each one by one.

Edited by jabelar

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

First, let me say I appreciate your help on this topic. Your tutorials are very useful.

OK, so I should use .register instead of registerAll. But what exactly is RegistryEvent.Register<Item> event? The class RegistryEvent has an inner class Register, but I don't see an array in that class anywhere.

Link to comment
Share on other sites

20 minutes ago, Alex S. said:

But what exactly is RegistryEvent.Register<Item> event? The class RegistryEvent has an inner class Register, but I don't see an array in that class anywhere.

Its not an array. It's a generic.

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

38 minutes ago, Alex S. said:

Ah, so it's to specify that only items that extend IForgeRegistryEntry can be used in the class. First time I've been exposed to these.

Generics are amazing.

For example, one of my mods has this method:

private <T extends Comparable<T>, V extends T,U extends Comparable<U>, W extends U>
void addArbitraryOre(String orename, int numFlowers, int clusterSize, int threshold, OreFlowerDictator dictator, IBlockState flower, IBlockState desertFlower, @Nullable IProperty<T> flowerProp, @Nullable V flowerValue, @Nullable IProperty<U> desertProp, @Nullable W desertValue) {
    //...
}

T & V and U & W are what they are because I need to interact with an IBlockState object and its property without referencing a specific property (as I am using four related, but incompatible, enum variants). In theory I could get rid of U & W (and declare two <T> parameters), but there's no reason to.

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

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.