Fabric Modding: Adding Food Properties to Items

This post was written for Minecraft Java 1.21.8 and Fabric Loader 0.16.14.

In this tutorial, we’re going to enhance one of our existing items — bubble_gum — by giving it a real purpose: making it edible. Right now, it’s just a decorative item that sits in your inventory. We’ll walk through how to give it hunger and saturation values using Minecraft’s FoodComponent system.

This is a great opportunity to revisit how we originally registered our custom item, and then build on top of it to turn it into a functional food item.

A Quick Note on Bubble Gum and Logic

In real life, bubble gum isn’t really something you’re supposed to swallow — so don’t take this tutorial as dietary advice. We’re making it edible in Minecraft because it’s fun, not realistic.

Also, as a reminder: the “strawberry” mod doesn’t take itself too seriously. Its theme is loosely held together by whimsy, food, and whatever else we feel like adding. If you were hoping for a chewing mechanic… well, it probably wouldn’t be very fun to implement anyway.

Quick Review: What Does This Line Actually Do?

Here’s how we originally registered our bubble_gum item in ModItems.java:

public static final Item BUBBLE_GUM = register(
    "bubble_gum",
    Item::new,
    new Item.Settings()
);

Let’s break it down:

  • "bubble_gum" – This is the item’s registry name. It will be registered as strawberry:bubble_gum in-game.
  • Item::new – This is a constructor reference. It tells the register method how to create the item. Right now, it’s just a plain Item, but we can change that later to a food item or something custom.
  • new Item.Settings() – This defines the item’s behavior — stack size, fireproof status, and more. Note: it no longer controls creative tab placement directly. As of modern versions of Minecraft, creative tab assignment is handled separately using ItemGroupEvents.modifyEntriesEvent(...). So far, we haven’t added anything special.

This line successfully registers the item with Minecraft, but it’s just a generic item — we can hold it, but we can’t eat it.

Adding Food Properties with FoodComponent

To make our bubble gum edible, we need to attach a FoodComponent to its item settings. This tells Minecraft how much hunger and saturation the food restores, and whether it can always be eaten.

What is FoodComponent.Builder()?

The FoodComponent.Builder() class uses the Builder pattern — a common object-oriented design pattern in Java that lets you gradually configure an object before constructing it. Instead of passing a dozen parameters into a constructor, you chain together methods to set values and then call .build() to produce the final object.

In this case:

  • You call methods like .nutrition(...), .saturationModifier(...), and .alwaysEdible() to customize how the food behaves.
  • Then you call .build() to return a FoodComponent object with those properties, which you pass into Item.Settings().food(...).

What Does .food(...) Do?

The .food(...) method is part of Item.Settings, and it’s how you tell Minecraft that this item is edible. If you don’t call .food(...), the item behaves like a regular non-edible item (even if it looks like food).

By passing a FoodComponent to .food(...), you’re saying:

“This item should be treated like food and use the properties defined here when the player eats it.”

Without it, even a perfectly built FoodComponent would be ignored — the item simply wouldn’t be recognized as food.

Here’s the full updated code using just FoodComponent:

public static final Item BUBBLE_GUM = register(
    "bubble_gum",
    Item::new,
    new Item.Settings().food(
        new FoodComponent.Builder()
            .nutrition(2)             // Restores 1 hunger bar — like sweet berries or dried kelp
            .saturationModifier(0.2F) // Very low — lower than apples (0.3)
            .alwaysEdible()          // Edible even when full — like golden apples
            .build()
    )
);

What each part does:

  • .nutrition(2) – Restores 1 full hunger icon (2 points).
  • .saturationModifier(0.2F) – Controls how long the player stays full. Lower values mean quicker hunger loss.
  • .alwaysEdible() – Allows the player to eat the gum even when they aren’t hungry.
  • .build() – Constructs the actual FoodComponent object with all the above settings applied.

This gives our bubble gum basic food properties without any special effects. It now plays the eating animation and restores a small amount of hunger — just enough to feel like a sweet little pick-me-up.

Customizing How Food Is Eaten with ConsumableComponent

Now that our bubble gum has basic nutritional properties, let’s improve how it feels to consume. Minecraft assumes most food is something you bite or chew, with crumb particles and a ~1.6 second animation. But that’s not quite the experience we want.

What is ConsumableComponent?

ConsumableComponent is part of Fabric’s component API and gives us control over the experience of consuming the item — including visuals, duration, and advanced effect behavior.

Think of it like an optional argument to the food(...) method in Item.Settings. You can pass in just a FoodComponent, but you can also pass a second argument — a ConsumableComponent — to override things like:

  • Whether the item shows particles when eaten
  • How long eating takes
  • (Later) Whether special effects are triggered during or after use

By using this second argument, we can fine-tune the experience of eating bubble gum.

And yes — in real life, gum is chewed for a long time and never swallowed. But in Minecraft, that would just feel tedious. So we’re going for a fast, clean in-game snack instead.

public static final Item BUBBLE_GUM = register(
    "bubble_gum",
    Item::new,
    new Item.Settings().food(
        new FoodComponent.Builder()
            .nutrition(2)             // Restores 1 hunger bar — like sweet berries or dried kelp
            .saturationModifier(0.2F) // Very low — lower than apples (0.3)
            .alwaysEdible()          // Edible even when full — like golden apples
            .build(),
        ConsumableComponents.food()
            .consumeParticles(false) // Disables crumb particles — feels cleaner and gum-like
            .consumeSeconds(0.5F)    // Much faster than typical food (1.6s default)
            .build()
    )
);

What each part does:

  • .consumeParticles(false) – Prevents the usual food particle effects. Gum doesn’t crumble like bread, so this feels cleaner.
  • .consumeSeconds(0.5F) – Makes the item very quick to consume. For comparison:
    • Most vanilla foods: 1.6 seconds
    • This gum: 0.5 seconds

With just a few lines of configuration, we’ve given our bubble gum a lightweight nutritional profile and customized how it’s eaten. It’s quick, clean, and snacky — perfect for the kind of fun, whimsical item we’re building.

Next, we’ll explore how to give it a little more personality by adding custom effects that trigger when the player eats it — think sugar rush, instant healing, or other quirky boosts.

Adding a Healing Effect with consumeEffect(...)

So far, our bubble gum restores a little hunger and plays the eating animation — but what if we want it to do something more?

That’s where consumeEffect(...) comes in. This lets us apply status effects when the item is eaten — just like how suspicious stew can give you Night Vision or a golden apple can boost your health. In our case, let’s make the gum restore a bit of health on chew.

We’ll use a built-in effect (StatusEffects.INSTANT_HEALTH) and wrap it in an ApplyEffectsConsumeEffect object. This tells Minecraft: “When someone eats this, apply the following effect.”

Here’s the updated item registration:

public static final Item BUBBLE_GUM = register(
    "bubble_gum",
    Item::new,
    new Item.Settings().food(
        // Basic food properties
        new FoodComponent.Builder()
            .nutrition(2)             // Restores 1 hunger icon
            .saturationModifier(0.2F) // Minimal fullness
            .alwaysEdible()           // Can be eaten even when full
            .build(),

        // Consumption behavior
        ConsumableComponents.food()
            .consumeEffect(           // Add a healing effect
                new ApplyEffectsConsumeEffect(
                    new StatusEffectInstance(
                        StatusEffects.INSTANT_HEALTH, // Heals instantly
                        1,                             // Duration (instant effect)
                        0                              // Amplifier (Level I = heals 2 hearts)
                    ),
                    1.0f                              // 100% chance to apply
                )
            )
            .consumeParticles(false)   // No particles when eaten
            .consumeSeconds(0.5F)      // Super quick to chew
            .build()
    )
);

Why Healing?

Bubble gum isn’t exactly a meal — it’s a fun little treat. But in Minecraft, food items take time and effort to make. We wanted this gum to feel worth it.

By giving it a mild instant heal, we’ve turned bubble gum into a fast-acting emergency snack:

  • It’s always edible, even when your hunger bar is full.
  • It plays the eating animation in just half a second.
  • And it heals you instantly — just enough to save your skin if you’re on the run.

It’s silly, it’s sweet, and it’s surprisingly useful — everything a whimsical snack should be.

Creating a Custom Healing Effect

So far, we’ve worked with built-in effects like INSTANT_HEALTH, but they’re not always the right fit. I wanted something gentler than Minecraft’s full-blown healing effect — something that just gives the player a little boost. So I wrote a custom ConsumeEffect.

Here’s the code:

package dev.epicbunny.strawberry;

import net.minecraft.entity.LivingEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.consume.ConsumeEffect;
import net.minecraft.world.World;

public class HealEffect implements ConsumeEffect {
    private final float healAmount;

    public HealEffect(float healAmount) {
        this.healAmount = healAmount;
    }

    @Override
    public Type<? extends ConsumeEffect> getType() {
        return null;
    }

    @Override
    public boolean onConsume(World world, ItemStack stack, LivingEntity user) {
        user.heal(healAmount); // Directly heals the entity by this many half-hearts
        return true; // Returning true tells Minecraft the item was consumed successfully
    }
}

What’s Actually Happening Here?

implements ConsumeEffect
This tells Java that HealEffect follows a specific interface — a sort of contract. It must include all required methods from the ConsumeEffect interface, such as onConsume(...).

@Override annotations
These indicate that we’re overriding methods from the interface. They help Java detect mistakes (like a typo in a method name) and make it clear to other developers where the method came from.

onConsume(World world, ItemStack stack, LivingEntity user)
This method runs when the item is consumed. It receives three parameters:

  • World: the Minecraft world the player is currently in.
  • ItemStack: the item being eaten.
  • LivingEntity: the player (or any other entity capable of eating).

Inside this method, we call user.heal(healAmount), which directly restores health. In our case, 0.5F heals just one half-heart.

The method returns true to indicate that the effect was successfully applied.

Now, let’s see how this class gets used!

public static final Item BUBBLE_GUM = register(
    "bubble_gum",
    Item::new,
    new Item.Settings()
        .food(
            new FoodComponent.Builder()
                .nutrition(2) // Restores 1 hunger bar
                .saturationModifier(0.2F) // Slight saturation
                .alwaysEdible() // Can be eaten even when full
                .build(),
            ConsumableComponents.food()
                .consumeEffect(new HealEffect(0.5F)) // Heals half a heart
                .consumeParticles(false) // No crumbs or particles
                .consumeSeconds(0.5F) // Quick chew time
                .build()
        )
);

This new effect is subtle, snack-like, and unique to our mod. It also opens the door to all sorts of creative effects — from custom buffs and debuffs to status quirks, teleportation, transformations, and more.

We might dive into more ambitious custom effects in a future tutorial, but this is a great first taste.

When it comes to implementing custom behavior in a Minecraft mod, there’s no single “correct” way to do it. Your approach may vary based on how your mod is organized, how much abstraction you prefer, and what your goals are. The simple healing effect we created here is just one possible method — not necessarily the best or most powerful, but definitely a clean and effective one. For most food items, this setup will be more than enough.

In the next post, we’ll be shifting gears to talk about custom weapons and how to add special effects to them. That one’s still in development — I’m writing the code as we speak — but it should be ready soon, so stay tuned!

No Comments on Fabric Modding: Adding Food Properties to Items

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.