Warning
Note: This is only relevant when using RRV 7.1.4 or below, or if you need to synchronize server data by hand.
RRV 8.0.0 and above synchronize recipes through the standard recipe synchronization APIs provided by Fabric and NeoForge.
Since recipes only exist on the server since 1.21.2, the client does not know which recipes exist. In order for RRV to be able to show recipes, we have to synchronize them between the server and client ourselves. For consistency, RRV required a serverside representation of all recipes regardless whether it's a mod or vanilla recipe.
Creating a serverside representation of your mod recipes is quite easy, simply create a class that implements ReliableServerRecipe and override the methods:
Example
public class ExampleServerRecipe implements ReliableServerRecipe {// SlotContent is used here as an abstraction over ever-changing Ingredients and ItemStacks.private SlotContent input, output;//Create a server recipe type (the id does not have to match your client side recipe type id)public static final ReliableServerRecipeType<ExampleServerRecipe> TYPE = ReliableServerRecipeType.register(Identifier.fromNamespaceAndPath("example-mod", "your_recipe_id"),() -> new ExampleServerRecipe(null, null));public ExampleServerRecipe(Ingredient input, ItemStack result) {this.input = SlotContent.of(left);this.output = SlotContent.of(result);}@Overridepublic void writeToTag(CompoundTag tag) { // called on the server to encode recipestag.put("input", TagUtil.writeSlotContent(this.input));tag.put("output", TagUtil.writeSlotContent(this.output));}@Overridepublic void loadFromTag(CompoundTag tag) { // called on the client to decode recipesthis.input = TagUtil.readSlotContent(tag.getCompound("input").orElseGet(CompoundTag::new));this.output = TagUtil.readSlotContent(tag.getCompound("output").orElseGet(CompoundTag::new));}@Overridepublic ModRecipeType<? extends ReliableServerRecipe> getRecipeType() {return TYPE;}// Getter for the input, used in the client recipe wrapper.public SlotContent getInput() {return this.input;}// Getter for the output, used in the client recipe wraper.public SlotContent getOutput() {return this.output;}}
Info
The API includes a TagUtil class that provides a lot of helper functions for encoding and decoding different objects, primarily writeSlotContent and readSlotContent.
With all your recipe classes created, you can move on to creating the plugins.