Butterfly Creative Mode Tab

One detail I’ve been struggling with while developing Bok’s Banging Butterflies is where to put the items in the Creative Inventory. While playing other mods for inspiration, I saw many create a dedicated Creative Tab just for their content. A tidy, mod-branded spot that makes everything easier to find.

It’s such a simple idea, but it was the perfect solution since I no longer have to think about where to put my items. And with everything in one place it makes the Creative Inventory more user-friendly, and helps show off all the features in the mod.

Registering the Tab


As with all things in Minecraft, Creative Mode Tabs need to be registered. So it’s time to add another registry to Bok’s Banging Butterflies! This registry follows the same structure as all the others, only it registers CreativeModeTab using the CREATIVE_MODE_TAB registry:

/**
 * This class registers new creative tabs for the Butterflies Mod
 */
public class CreativeTabRegistry {

    // An instance of a deferred registry we use to register items.
    private final DeferredRegister<CreativeModeTab> deferredRegister;

    // The Butterfly Creative Tab
    private RegistryObject<CreativeModeTab> butterflyCreativeTab;


    /**
     * Constructs and registers the creative tab registry.
     * @param modEventBus The event bus to register with. Must not be null.
     */
    public CreativeTabRegistry(@NotNull IEventBus modEventBus) {
        this.deferredRegister = DeferredRegister.create(Registries.CREATIVE_MODE_TAB, ButterfliesMod.MOD_ID);
        this.deferredRegister.register(modEventBus);
    }
}

In the registry’s initialise() method, the new creative tab is registered using a CreativeModeTab builder class. A translation string is used for its title, and the Lepidopterist’s Book is used as an icon for the tab:

    /**
     * Registers the creative tab. Must only be called once.
     * @param itemRegistry Registry containing mod items. Must not be null.
     * @throws IllegalStateException if called more than once
     */
    public void initialise(@NotNull ItemRegistry itemRegistry) {
        if (butterflyCreativeTab != null) {
            throw new IllegalStateException("Creative tabs have already been initialised");
        }

        this.butterflyCreativeTab = deferredRegister.register("butterfly_creative_tab",
                () -> CreativeModeTab.builder()
                        .title(Component.translatable("itemGroup.butterfly_tab"))
                        .icon(itemRegistry.getButterflyBook().get()::getDefaultInstance)
                        .build()
        );
    }

Finally, an accessor is provided so that it can be used by other classes:

    /**
     * @return The butterfly creative tab. Never null after initialise().
     * @throws IllegalStateException if called before initialise().
     */
    @NotNull
    public RegistryObject<CreativeModeTab> getButterflyCreativeTab() {
        if (butterflyCreativeTab == null) {
            throw new IllegalStateException("Creative tab has not been initialised. Call initialise() first.");
        }

        return butterflyCreativeTab;
    }

The class is instantiated and initialised in the mod’s constructor, alongside the other registries used by the mod. Now all the items in the mod can be moved to this new tab.

Building the Contents


To move all the items, the response to BuildCreativeModeTabContentsEvent in the ModEventListener is updated. Now, rather than having a switch statement handling multiple tabs, only one tab needs to be checked for. Once the new butterfly tab is detected, all the items in the mod can be added to it.

    /**
     * Registers items with the relevant creative tab
     * @param event The event information
     */
    public void onBuildCreativeModeTabContents(@NotNull BuildCreativeModeTabContentsEvent event) {

        if (!Objects.equals(event.getTabKey(), creativeTabRegistry.getButterflyCreativeTab().getKey())) {
            return;
        }

        // Nets
        event.accept(itemRegistry.getEmptyButterflyNet());
        itemRegistry.getButterflyNets().forEach(event::accept);
        event.accept(itemRegistry.getBurntButterflyNet());

        // Eggs
        itemRegistry.getButterflyEggs().forEach(event::accept);

        // Caterpillars
        itemRegistry.getCaterpillars().forEach(event::accept);

        // Bottles
        itemRegistry.getBottledButterflies().forEach(event::accept);
        itemRegistry.getBottledCaterpillars().forEach(event::accept);

        // Scrolls
        itemRegistry.getButterflyScrolls().forEach(event::accept);

        // Books
        event.accept(itemRegistry.getButterflyBook());
        event.accept(itemRegistry.getZhuangziBook());

        // Blocks
        event.accept(itemRegistry.getButterflyFeeder());
        event.accept(itemRegistry.getButterflyMicroscope());

        // Infested Apple
        event.accept(itemRegistry.getInfestedApple());

        // Silk
        event.accept(itemRegistry.getSilk());

        // Origami
        itemRegistry.getButterflyOrigami().forEach(event::accept);

        // Sherd
        event.accept(itemRegistry.getButterflyPotterySherd());

        // Banner Pattern
        event.accept(itemRegistry.getButterflyBannerPattern());

        // Spawn Eggs
        itemRegistry.getButterflySpawnEggs().forEach(event::accept);
        itemRegistry.getCaterpillarSpawnEggs().forEach(event::accept);
        event.accept(itemRegistry.getButterflyGolemSpawnEgg());
    }

I took care to add these items in an order that would look nice and logical when viewed in game. This helps the tab feel intuitive for players. It’s a small detail, but it really makes the tab feel natural for new players and experienced bug hunters alike.

After all was done, the new tab appears in the creative inventory, and it’s much easier to find items from Bok’s Banging Butterflies:

Backporting


The Creative Mode Tab registry is only available starting with Minecraft 1.20. For 1.19.2 and 1.18.2, I had to use the old property-based assignment. By setting Item.Properties().tab(butterflyTab), each item is manually linked to my custom tab, ensuring consistency in the mod across versions.

To support this, the new tab is created in the initialise() method of the ItemRegistry class. I then create a couple of helper Properties that I can use to register all my items:

        // Create the tab for the creative menu.
        ButterflyTab butterflyTab = new ButterflyTab(CreativeModeTab.TABS.length, "butterfly_tab", this);

        // Item properties
        Item.Properties baseProperties =  new Item.Properties().tab(butterflyTab);
        Item.Properties stacksToOne = baseProperties.stacksTo(1);

Since the tab for each item is set using item properties in these versions, I use some default properties to pass into each item as it is registered. This ensures they are all added to the new creative mode tab, maintaining parity for all versions of the mod.

Wrapping Up


Features like this can vastly improve a mod, both in feeling better integrated into the game, and making them feel more complete. Technically this change doesn’t add anything to survival, but it gives the mod that touch of polish it needs to feel professional.

How do you organize items in your own mods? Have you found clever tricks for creative inventory management, or maybe faced annoying limitations in older Minecraft versions? Drop your thoughts or suggestions in the comments below. Or alternatively, open an issue on GitHub if you’d like to see a feature in Bok’s Banging Butterflies!

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.