A Quilt Standard Libraries module that aims to help to manipulate recipes.
It has three parts, QuiltRecipeSerializer (Which was briefly covered in the Recipe Creation Tutorial), recipe manager manipulation (Addition, Removal and Modification of recipes) and utilities.
An interface that extends RecipeSerializer to add JSON serialization.
Its primary use is the recipe dump, which allows for dumping of JSON representations of recipes as files into the game directory (./debug/quilt/recipe/...) - It supports any recipes whose serializer implements QuiltRecipeSerializer, vanilla recipes are supported by default.
Dumping can be enabled by setting the quilt.recipe.dump system property.
Static recipes are a kind of recipe that is always kept present during the whole game lifecycle. They're only applied after data pack reloads, that is, when starting a world/server or after using the /reload command.
From Recipes.java:
// ...
RecipeManagerHelper.registerStaticRecipe(
VanillaRecipeBuilders.shapedRecipe("IAI") // Shaped recipe with the IAI pattern
.output(new ItemStack(Items.CHAINMAIL_CHESTPLATE)) // That outputs a chestplate
.ingredient('I', Items.IRON_INGOT) // I being an ingot
.ingredient('A', Items.APPLE) // and A an Apple
.build(new Identifier("example", "apple_iron_ingot_fun"), "")
);
// ...
Dynamic recipe providers can be used to register recipes that might have a runtime component - Something that cannot be known at build time - for example, recipes that depend on other mods.
From Recipes.java:
// ...
RecipeManagerHelper.addRecipes(handler -> handler.register(new Identifier("example", "random"), id ->
VanillaRecipeBuilders.shapelessRecipe(new ItemStack(
// We can't know which item it's going to output in advance, therefore, it's impossible
// to create a JSON for this recipe.
Registry.ITEM.getRandom(RandomGenerator.createLegacy()).orElseThrow().value()))
.ingredient(Items.ACACIA_BUTTON)
.build(id, "")));
// ...
Mods might want to modify values or replace recipes entirely while they're being built, this event allows for that.
From Recipes.java:
// ...
RecipeManagerHelper.modifyRecipes(handler -> {
// Modifies the name of the output of the stone smelting recipe
handler.getRecipe(new Identifier("minecraft", "stone"), RecipeType.SMELTING)
.getOutput().setCustomName(Text.literal("Modified!").formatted(Formatting.RED));
// Replaces the enchanting table recipe with different ingredients
handler.replace(VanillaRecipeBuilders.shapedRecipe(" B ", "D#D", "###")
.ingredient('B', Items.WRITABLE_BOOK)
.ingredient('D', Items.GOLD_INGOT)
.ingredient('#', Items.POLISHED_BASALT)
.output(new ItemStack(Items.ENCHANTING_TABLE))
.build(new Identifier("minecraft", "enchanting_table"), "")
);
});
// ...
Mods might want to remove a recipe completely from the game; this event allows for that - Proceed with caution, this might cause incompatibilities.
From Recipes.java:
// ...
RecipeManagerHelper.removeRecipes(handler -> {
handler.remove(new Identifier("minecraft", "acacia_door"));
handler.removeIf(RecipeType.BLASTING, rec -> rec.getOutput().isOf(Items.GOLD_INGOT));
});
// ...