Skip to main content
Version: 1.20.x

Recipes

Recipes are a way to transform some number of objects into other objects within a Minecraft world. Although the vanilla system deals purely with item transformations, the system as a whole can be expanded to use any object the programmer creates.

Data-Driven Recipes​

Most recipe implementations within vanilla are data driven via JSON. This means that a mod is not necessary to create a new recipe, only a Data pack. A full list on how to create and put these recipes within the mod's resources folder can be found on the Minecraft Wiki.

A recipe can be obtained within the Recipe Book as a reward for completing an advancement. Recipe advancements always have minecraft:recipes/root as their parent, to not to appear on the advancement screen. The default criteria to gain the recipe advancement is a check if the user has unlocked the recipe from using it once or receiving it through a command like /recipe:

// Within some recipe advancement json
"has_the_recipe": { // Criteria label
// Succeeds if examplemod:example_recipe is used
"trigger": "minecraft:recipe_unlocked",
"conditions": {
"recipe": "examplemod:example_recipe"
}
}
//...
"requirements": [
[
"has_the_recipe"
// ... Other criteria labels to be ORed against to unlock recipe
]
]

Data-driven recipes and their unlocking advancement can be generated via RecipeProvider.

Recipe Manager​

Recipes are loaded and stored via the RecipeManager. Any operations relating to getting available recipe(s) are handled by this manager. There are two important methods to know of:

MethodDescription
getRecipeForGets the first recipe that matches the current input.
getRecipesForGets all recipes that match the current input.

Each method takes in a RecipeType, which denotes what method is being applied to use the recipe (crafting, smelting, etc.), a Container which holds the configuration of the inputs, and the current level which is passed to Recipe#matches along with the container.

tip

Forge provides the RecipeWrapper utility class which extends Container for wrapping around IItemHandlers and passing them to methods which requires a Container parameter.

// Within some method with IItemHandlerModifiable handler
recipeManger.getRecipeFor(RecipeType.CRAFTING, new RecipeWrapper(handler), level);

Additional Features​

Forge provides some additional behavior to the recipe schema and its implementations for greater control of the system.

Recipe ItemStack Result​

Except for minecraft:stonecutting recipes, all vanilla recipe serializers expand the result tag to take in a full ItemStack as a JsonObject instead of just the item name and amount in some cases.

// In some recipe JSON
"result": {
// The name of the registry item to give as a result
"item": "examplemod:example_item",
// The number of items to return
"count": 4,
// The tag data of the stack, can also be a string
"nbt": {
// Add tag data here
}
}
note

The nbt tag can alternatively be a string containing a stringified NBT (or SNBT) for data which cannot be properly represented as a JSON object (such as IntArrayTags).

Conditional Recipes​

Recipes and their unlocking advancement can be loaded conditionally and defaulted depending on what information is present (mod loaded, item exists, etc.).

Larger Crafting Grids​

By default, vanilla declares a maximum width and height for a crafting grid to be a 3x3 square. This can be expanded by calling ShapedRecipe#setCraftingSize with the new width and height in FMLCommonSetupEvent.

caution

ShapedRecipe#setCraftingSize is NOT thread-safe. As such, it should be enqueued to the synchronous work queue via FMLCommonSetupEvent#enqueueWork.

Larger crafting grids in recipes can be data generated.

Ingredient Types​

A few additional ingredient types are added to allow recipes to have inputs which check tag data or combine multiple ingredients into a single input checker.