MultiLoader 1.21+ · Part 9

Custom Food Items (MultiLoader 1.21+)

BEGINNER MULTILOADER 1.21-1.21.1 14 min read · Jul 6, 2026
MultiLoader 1.21+ · 28 parts
1 Getting Started with MultiLoader 1.21+ 2 Setting Up RegistrationUtils 3 Creating Items (MultiLoader 1.21+) 4 Creating Blocks (MultiLoader 1.21+) 5 Data Generation: Block & Item Models (MultiLoader 1.21+) 6 Data Generation: Block Loot Tables (MultiLoader 1.21+) 7 Data Generation: Crafting Recipes (MultiLoader 1.21+) 8 Data Generation: Block & Item Tags (MultiLoader 1.21+) 9 Custom Food Items (MultiLoader 1.21+) 10 Custom Tools (MultiLoader 1.21+) 11 Custom Armour (MultiLoader 1.21+) 12 Block Entities (MultiLoader 1.21+) 13 Config Files (MultiLoader 1.21+) 14 Custom Sounds (MultiLoader 1.21+) 15 Events and Listeners (MultiLoader 1.21+) 16 Networking and Custom Packets (MultiLoader 1.21+) 17 Data Generation: Advancements (MultiLoader 1.21+) 18 Data Generation: Language Files (MultiLoader 1.21+) 19 Custom Entities (MultiLoader 1.21+) 20 Ore Generation (MultiLoader 1.21+) 21 Introduction to Mixins (MultiLoader 1.21+) 22 Custom Particles (MultiLoader 1.21+) 23 Menus & Screens (MultiLoader 1.21+) 24 Key Bindings (MultiLoader 1.21+) 25 Custom Potion Effects (MultiLoader 1.21+) 26 Custom Enchantments (MultiLoader 1.21+) 27 Custom Commands (MultiLoader 1.21+) 28 Custom Biomes (MultiLoader 1.21+)

Food items are one of the most common additions to any mod. In Minecraft, any item can be made edible by attaching a FoodProperties instance to its properties. This tutorial walks through defining nutrition, saturation, and optional status effects, all from the common module, then wires up the model and creative tab entries through datagen. In this tutorial, we'll be creating a Tomato.

NOTE
Complete the Creating Items tutorial before continuing. We add a new entry to the existing ItemRegistry.

Food Properties

Food behaviour is defined through a FoodProperties object built with its inner Builder. Declare a public static final constant in ItemRegistry so the same properties object can be reused:

java
public static final FoodProperties TOMATO_PROPERTIES = new FoodProperties.Builder()
.nutrition(4)
.saturationModifier(0.3f)
.build();

The two required values are:

  • nutrition(int): the number of hunger shanks restored (each shank is 2 points, so 4 restores two full shanks).
  • saturationModifier(float): the saturation multiplier. Actual saturation gained is nutrition × saturationModifier × 2, so 4 × 0.3 × 2 = 2.4 saturation points.

Two optional modifiers worth knowing about are:

  • .alwaysEdible(): allows eating even when the hunger bar is full, like golden apples.
  • .fast(): shortens the eating animation to match dried kelp.

Registering the Item

Register the food item by passing TOMATO_PROPERTIES to Item.Properties.food():

java
public static final RegistryObject<Item, Item> TOMATO = ITEMS.register("tomato",
() -> new Item(getItemProperties().food(TOMATO_PROPERTIES)));

No subclass is needed for a basic food item. The food() call on the properties object is all that is required to make a plain Item edible.

Status Effects on Eating

To apply a status effect when the food is eaten, add one or more .effect() calls to the builder. Each call takes a MobEffectInstance and a probability between 0.0 (never) and 1.0 (always):

java
public static final FoodProperties TOMATO_PROPERTIES = new FoodProperties.Builder()
.nutrition(4)
.saturationModifier(0.3f)
.effect(new MobEffectInstance(MobEffects.MOVEMENT_SPEED, 200, 0), 1.0f)
.effect(new MobEffectInstance(MobEffects.POISON, 60, 0), 0.1f)
.build();

The MobEffectInstance constructor takes the effect, duration in ticks, and amplifier (0 for level I, 1 for level II, and so on). The example above always grants Speed I for 10 seconds and has a 10% chance of inflicting Poison I for 3 seconds.

Creative Tab and Language File

Open CreativeTabRegistry and add the new food item to the display items list of your existing tab:

java
.displayItems((params, output) -> {
output.accept(ItemRegistry.IRON_STICK.get());
output.accept(ItemRegistry.TOMATO.get());
})

Add a display name in your en_us.json language file:

json
{
"item.examplemod.iron_stick": "Iron Stick",
"item.examplemod.tomato": "Tomato",
...
}

Datagen

Food items use the flat 2D inventory model, so they are handled by the same basicItem call used for other items. Open ExampleItemModelProvider and add:

java
@Override
protected void registerModels() {
basicItem(ItemRegistry.IRON_STICK.get());
basicItem(ItemRegistry.TOMATO.get());
}

Create a 16×16 PNG texture at src/main/resources/assets/examplemod/textures/item/tomato.png and run NeoForge Data to generate the model JSON.

Testing In-Game

Launch the client and find the food item in your creative tab. Switch to survival mode (or use /gamemode survival) and lower your hunger bar with /effect give @s minecraft:hunger 10 4, then eat the item. Verify that the hunger and saturation bars increase correctly and that the Speed effect appears in the active effects overlay.

TIP
You can inspect saturation (which is invisible by default) by pressing F3 in-game and looking for saturation in the debug screen overlay, or by using a mod such as AppleSkin.

You can find the source for this tutorial here:

View Source on GitHub
NEXT IN SERIES

Custom Tools (MultiLoader 1.21+)

Implement a custom Tier enum with the 1.21 incorrect-blocks tag system, register sword, pickaxe and axe items, generate handheld item models via datagen, and verify tool tier requirements in-game.

Continue →