Item Checklist

After blocks, items are probably the most likely thing to be added to the game. There are a few steps involved in adding an item, and it’s often easy to forget a step. So this handy checklist should ensure you don’t miss anything.

Checklist


  1. Create the item
  2. Register the item
  3. Add the item to the creative menu
  4. Create the item model
  5. Create the item texture(s)
  6. Add localisation
  7. Add a Recipe

Create the Item


Many items have custom uses and behaviours, and you will need to implement these by extending the Item class, or one of its subclasses. Sometimes your items don’t need any custom behaviour, meaning you can skip this step and use a class that already exists instead.

An example of a simple item class might look like the following. This class creates hover text to identify the species of the caterpillar, as well as allows the player to place a caterpillar entity on leaf blocks.

/**
 * A class to represent a caterpillar in the player's inventory.
 */
public class CaterpillarItem extends Item {

    //  The name this item is registered under.
    public static String getRegistryId(int butterflyIndex) {
        return "caterpillar_" + ButterflySpeciesList.SPECIES[butterflyIndex];
    }

    private final ResourceLocation species;

    /**
     * Construction
     * @param species The species of the caterpillar
     */
    public CaterpillarItem(String species) {
        super(new Item.Properties());

        this.species = new ResourceLocation(ButterfliesMod.MOD_ID, species);
    }

    /**
     * Adds some tooltips.
     * @param stack The item stack.
     * @param level The current level.
     * @param components The current text components.
     * @param tooltipFlag Is this a tooltip?
     */
    @Override
    public void appendHoverText(@NotNull ItemStack stack,
                                @Nullable Level level,
                                @NotNull List<Component> components,
                                @NotNull TooltipFlag tooltipFlag) {

        MutableComponent newComponent = Component.translatable("tooltip.butterflies.place_caterpillar");
        Style style = newComponent.getStyle().withColor(TextColor.fromLegacyFormat(ChatFormatting.GRAY))
                .withItalic(true);
        newComponent.setStyle(style);
        components.add(newComponent);

        super.appendHoverText(stack, level, components, tooltipFlag);
    }

    /**
     * Overridden so we can use a single localisation string for all instances.
     * @param itemStack The stack to get the name for.
     * @return The description ID, which is a reference to the localisation
     *         string.
     */
    @NotNull
    @Override
    public Component getName(@NotNull ItemStack itemStack) {
        return Component.translatable("entity." + species.toString().replace(":", "."));
    }

    /**
     * Places the butterfly scroll on a block.
     * @param context Contains information about the block the user clicked on.
     * @return The result of the interaction.
     */
    @Override
    @NotNull
    public InteractionResult useOn(@NotNull UseOnContext context) {
        Player player = context.getPlayer();
        if (player != null) {

            BlockPos clickedPos = context.getClickedPos();

            BlockState blockState = context.getLevel().getBlockState(clickedPos);
            if (!(ButterflyData.getEntry(this.species).isValidLandingBlock(blockState))) {
                return InteractionResult.FAIL;
            } else {
                if (!context.getLevel().isClientSide()) {
                    Direction clickedFace = context.getClickedFace();
                    Caterpillar.spawn((ServerLevel) context.getLevel(), this.species, clickedPos.relative(clickedFace), clickedFace.getOpposite(), false);
                } else {
                    player.playSound(SoundEvents.SLIME_SQUISH_SMALL, 1F, 1F);
                }

                context.getItemInHand().shrink(1);

                return InteractionResult.CONSUME;
            }
        }

        return super.useOn(context);
    }
}

Register the Item


Items need to be registered in an item registry, as with many other objects in Minecraft. A simple example of an item registry might look like the following.

/**
 * This class registers items with Forge's Item Registry
 */
public class ItemRegistry {

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

    // Registry Items
    private RegistryObject<Item> silk;

    /**
     * Construction
     * @param modEventBus The event bus to register with.
     */
    public ItemRegistry(IEventBus modEventBus) {
        this.deferredRegister = DeferredRegister.create(ForgeRegistries.ITEMS, ButterfliesMod.MOD_ID);
        this.deferredRegister.register(modEventBus);
    }

    /**
     * Register the items.
     * @param blockRegistry The block registry.
     * @param entityTypeRegistry The entity type registry.
     */
    public void initialise() {
        this.silk = deferredRegister.register("silk", () -> new Item(new Item.Properties()));
    }

    /**
     * Accessor for silk.
     * @return The registry object.
     */
    public RegistryObject<Item> getSilk() {
        return this.silk;
    }
}

Add the Item to the Creative Menu


If you want your item to appear in the creative menu, you will need to register it in response to a BuildCreativeModeTabContentsEvent. A simple implementation of this might look like this.

/**
 * Listens for mod based events.
 */
public class ModEventListener {

    // Reference to the item registry.
    private final ItemRegistry itemRegistry;

    /**
     * Construction
     * @param modEventBus The event bus to register with.
     */
    public ModEventListener(IEventBus modEventBus,
                            ItemRegistry itemRegistry) {
        modEventBus.register(this);
        modEventBus.addListener(this::onBuildCreativeModeTabContents);

        this.itemRegistry = itemRegistry;
    }

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

        if (event.getTabKey() == CreativeModeTabs.INGREDIENTS) {
            event.accept(itemRegistry.getSilk());
        }
}

Create the Item Model


Every item needs a model, under /resources/assets/<MOD_ID>/models/item/. These models define what textures they use, and the simplest can just use a Minecraft item model as a base. A simple example of an item model referencing a texture follows.

{
  "parent": "minecraft:item/generated",
  "textures": {
    "layer0": "butterflies:item/silk"
  }
}

Create the Item Texture


Textures for items go under /resources/assets/<MOD_ID>/textures/item/. They are usually 16×16 PNG files, but they can really be any size you want. You can use any image that helps you generate pixel art to create your textures.

Add Localisation


You’ll need a localisation string for your new item. You’ll find localisation files under /resources/assets/<MOD_ID>/lang/. This will be in the form item.<MOD_ID>.<ITEM_ID>. As an example, the silk’s localisation string is:

  "item.butterflies.silk": "Silk",

Add a Recipe


If you want your item to be craftable, you need to add a recipe. This is just a JSON file stored under \resources\data\<MOD_ID>\recipes\ that describes the recipe to be included. You can have more than one recipe for an item, or have zero if you don’t want players to be able to craft the item.

A typical shaped recipe might look something like this:

{
  "type": "minecraft:crafting_shaped",
  "pattern": [
    " s ",
    "sps",
    " s "
  ],
  "key": {
    "s": {
      "item": "butterflies:silk"
    },
    "p": {
      "item": "minecraft:paper"
    }
  },
  "result": {
    "item": "butterflies:banner_pattern_butterfly"
  }
}

Add a Recipe Advancement

To ensure that your recipe can be discovered by players, you should also add in a recipe advancement. These are stored under \resources\data\<MOD_ID\advancements\recipes\ and they tell Minecraft when to unlock an item in the recipe book. Usually you set it to unlock based on one of the ingredients for your item.

The following recipe advancement unlocks the butterfly banner pattern if a player finds silk.

{
  "parent": "minecraft:recipes/root",
  "rewards": {
    "recipes": [
      "butterflies:banner_pattern_butterfly"
    ]
  },
  "criteria": {
    "has_silk": {
      "trigger": "minecraft:inventory_changed",
      "conditions": {
        "items": [
          {
            "items": [
              "butterflies:silk"
            ]
          }
        ]
      }
    },
    "has_the_recipe": {
      "trigger": "minecraft:recipe_unlocked",
      "conditions": {
        "recipe": "butterflies:banner_pattern_butterfly"
      }
    }
  },
  "requirements": [
    [
      "has_silk",
      "has_the_recipe"
    ]
  ]
}