Recipes have extremely difficult to debug issues
emilyploszaj opened this issue ยท 4 comments
This took a long time to navigate. These issues occur for clients connecting to non-integrated servers (normal multiplayer, joining LAN, etc).
First off, ResourcefulLib assumes fromNetwork
is a nullable method on recipe serializers. It is not, returning null from a recipe serializer breaks every other recipe in the game with a null pointer exception later down the line with no clear reasoning. This method needs to not catch exceptions, and replace .orElse(null)
with .orElseThrow()
, as well as removing the incorrect @Nullable
annotation. Throwing is of no concern because recipes are already broken whether your return null or throw, so it'd be nice to have a correct reason why in logs.
ref: https://github.com/Team-Resourceful/ResourcefulLib/blob/1.19.3/common/src/main/java/com/teamresourceful/resourcefullib/common/recipe/CodecRecipeSerializer.java#L44
Second and more insidiously, ingredients are serialized incorrectly. Vanilla network syncing is extremely terrible in a lot of ways, and one of these ways is tags and recipes cannot depend on each other or reference each other non-lazily, because on initial connection to a server, recipes are sent before tags, but on resource reload, tags are sent before recipes. This means that ingredients are always serialized by vanilla systems as a list of items, even if they are actually tags, because the client doesn't know what tags exist. However, ResourcefulLib assumes they can be serialized and deserialized to json painlessly, which is not the case. On the client, recipes that use this method and introspect on values will fail, because at the time the tag doesn't exist. This is less fatal, but is certainly bad practice and could have serious hard to debug ramifications. Following the vanilla model of serializing ingredients as a set of stacks is much safer.
ref: https://github.com/Team-Resourceful/ResourcefulLib/blob/1.19.3/common/src/main/java/com/teamresourceful/resourcefullib/common/codecs/recipes/IngredientCodec.java
These issues have caused an issue here AlexNijjar/Extractinator#23 relating to a mod that uses this lib where the recipe serialization methods cause vanilla recipe sync to fail, no recipes to load, and the vanilla recipe book along with any recipe viewers fail to load recipes (and appears to be their fault). There may be more issues here, these are the surface level ones I caught while debugging this for them.
Sorry if this is a lot of information, I spent a lot of time debugging this issue, and I'm deep in the weeds of this territory of vanilla code, so I thought I'd explain it best I could.
An addendum to the second ingredient serialization issue: Ingredients cache their matching stacks, so if a recipe introspects or reads its ingredients during/after the recipe sync but before tag sync, it'll collapse every tag into emptiness, which is certainly undesirable.
The nullable thing is because forge marks it as nullable so I thought it was from vanilla so I can fix that.
As for the ingredients I provide the ability for recipes to have a network and a json codec it is on the developer using the codec recipes to have 2 codecs to allow for different serialization for ingredients, a lot of times its not needed to have 2 separate codecs so I let them pass in 1 or 2. so the second part is on Extractinator.
For the ingredient things again, it should not be an issue as ingredients are lazy loaded so the problem with tags vs recipe times should not be an issue as it hasnt been an issue with for example REI and JEI, the only time it would be an issue is if they are loaded very early which shouldn't really be done as if for example you wanted to display beacon bases that wouldn't work as its a tag.
But that's just my opinion it can be fixed if the dev changes to using a separate codec for network.