1.0 Refactoring Block and Item Registration to DeferredRegister

Up to this point we have been adding blocks and items in our ModEventSubscriber class, and using an @ObjectHolder to give us a reference to our items. However this method could get messy pretty quickly, and does not really give us much separation in our code. We should switch to using a DeferredRegister

First, open your ModItems class in your init package. Next we want create a new public static final deferred register for items

public static final DeferredRegister<Item> ITEMS = new DeferredRegister<>(ForgeRegistries.ITEMS, ExampleMod.MODID);

Next we want to remove the @ObjectHolder annotation, as we won’t be needing it anymore. Remember to remove the import statement for it from the top of your file (your IDE may do this for you automatically)

Now obviously our EXAMPLE_ITEM won’t be working anymore, so we can rewrite that line to actually register the item like this

public static final RegistryObject<Item> EXAMPLE_ITEM = ITEMS.register("example_item", () -> new Item(new Item.Properties().group(ModItemGroups.MOD_ITEM_GROUP)));

Here we are creating a lambda to create our item when the Registry is ready for it, and now we have a reference to the RegistryObject<Item> for our item, which (once the item is actually created and registered) will give us a reference to the object that we can use elsewhere.

Right now the mod does not work, we are registering our example item twice, and we are trying to use it in ModItemGroups but the type changed. So first lets remove original line registering our Item in ModEventSubscriber the onRegisterItems function should look like this when you are done

@SubscribeEvent
public static void onRegisterItems(RegistryEvent.Register<Item> event) {
    event.getRegistry().registerAll(
    );
}

Right now it is not doing anything, but we will need it later so we don’t want to remove the function.

Next we need to fix ModItemGroups fortunately this is as simple as adding a .get to the end of ModItems.EXAMPLE_ITEM your line creating your ItemGroup should like like this now.

public static final ItemGroup MOD_ITEM_GROUP = new ModItemGroup(ExampleMod.MODID, () -> new ItemStack(ModItems.EXAMPLE_ITEM.get()));

The last thing we need to do is actually register our Deferred Registers in our mod’s main file. so in the constructor you will need to get a reference to the mod event bus, and then pass it into our item’s registry the code should look like this

public ExampleMod() {
        final IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();

        ModItems.ITEMS.register(modEventBus);
    }

At this point if you run the game everything should be working exactly the same as before. If your item no longer exists make sure that the deferred Register was given a reference to the modEvent Bus, and that the Items are being created properly in the ModItems class.

You can see the my exact source at this step here github.com/cody-code-wy/1.15.2-Example-Mod/commit/3e16f1

Next we need to do the same for our block, to start off create a new class in your init package called ModBlocks create a DeferredRegister of type Block

Next we want to register the block just like we did with the item copying information from our ModEventSubscriber and your ModBlocks class should look like this

public class ModBlocks {
    public static final DeferredRegister<Block> BLOCKS = new DeferredRegister<>(ForgeRegistries.BLOCKS, ExampleMod.MODID);
    public static final RegistryObject<Block> EXAMPLE_ORE = BLOCKS.register("example_ore", () -> new Block(Block.Properties.create(Material.ROCK).hardnessAndResistance(3f, 3f)));
}

Next we want to completely remove our onRegisterBlocks function from ModEventSubscriber we won’t be needing it anymore. Make sure you remember to remove the annotation as well or it will probably break something.

Finally we need to register our block’s deferred registry in our main class, which should look like

public ExampleMod() {
    final IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();

    ModItems.ITEMS.register(modEventBus);
    ModBlocks.BLOCKS.register(modEventBus);
}

And if everything has gone well you should still be able to place blocks with /setblock.

You can see my exact source at this point at github.com/cody-code-wy/1.15.2-Example-Mod/commit/52c481

Leave Comment

Your email address will not be published. Required fields are marked *