Zeta

Zeta

20M Downloads

Regarding RecipeCrawlHandler NPEs with Create: Dreams and Desires

quat1024 opened this issue ยท 0 comments

commented

It's already fixed, but I'm making this a GH issue so I can pin it to the issue tracker for reference.

I don't want to read all that, tell me how to fix it

Update to Zeta 30.

If you are using an old version of Quark (older than 4.0-461), you will need to update Quark too (due to unrelated changes in Zeta).

The short answer

  • Started getting reports that "Create: Dreams and Desires" was causing our RecipeCrawlHandler to crash.
  • I attempted a fix in Zeta 28. It didn't work because I misread the stacktrace, d'oh - I thought CD&D was returning null from this method getCraftingRemainingItem, but it's actually throwing an exception inside getCraftingRemainingItem.
    • My mistake for not checking that the fix worked correctly. Sorry.
  • I corrected the fix in Zeta 30.

The long answer

  • Vanilla adds a method called Item getCraftingRemainingItem().

    • This is intended for mechanics like "honey bottle turns into a regular bottle when you craft using it".
    • If you do not have a crafting remaining item - the vast majority of items - you are expected to return null from Item getCraftingRemainingItem().
  • Forge adds a method called ItemStack getCraftingRemainingItem(ItemStack).

    • Yes it has the same name.
    • This separate method allows mods to return a different crafting remaining item based on properties of the ItemStack (such as the NBT tag). This is more flexible than the vanilla system.
    • If you do not have a crafting remaining item - the vast majority of items - you are expected to return ItemStack.EMPTY from ItemStack getCraftingRemainingItem(ItemStack).
  • Create: Dreams & Desires adds some tools. Each tool includes the following line of code inside its ItemStack getCraftingRemainingItem(ItemStack) implementation:

    return new ItemStack(this.getCraftingRemainingItem());

    This calls the vanilla Item getCraftingRemainingItem function, which returns null, and passes it to the ItemStack constructor. This is incorrect and will crash when called.

  • However, vanilla never calls getCraftingRemainingItem except when you successfully craft something. I'm not familiar with CD&D, but it seems odd to craft something with a tool as a crafting ingredient? So I don't think this is a problem in practice.

  • But, Zeta is interested in iterating through all of the game's crafting recipes to implement mechanics in Quark like "the Magnet attracts any block crafted using Iron".

    • For various reasons we want to avoid items like the honey bottle which turn into something else when crafted.
    • So we need to call ItemStack getCraftingRemainingItem(ItemStack) in order to see if the item is one of these complex items.
    • This triggers the incorrect code in CD&D and everything blows up.

Timeline

  • On Jun 22, 2024 I believe we got our first reports about crashes with CD&D. This crash report about CD&D was tossed into an issue report about an unrelated crash.

  • The latest version of CD&D for 1.20.1 was released on Jun 24, 2024.

  • On Jul 1, 2024 the CD&D developer fixed the problem in their codebase. This version was not released because it was intended to be rolled into a larger content update which, I guess, never happened.

    I'll upload a beta soon of the next update but it's no where near finished

  • On Mar 8, 2025 I added the first getCraftingRemainingItem fix. This checked that items weren't returning null from ItemStack getCraftingRemainingItem(ItemStack). This was released as part of Zeta 28.

    • This is not a correct fix. As described in the previous sections, CD&D was throwing an exception from ItemStack getCraftingRemainingItem(ItemStack), not returning null from it.
    • I was confused because I wrote this referencing the code on GitHub, not the code in the released mod.
  • On Apr 17, 2025 I noticed a report of the same issue with a user running Zeta 29 and did this proper investigation. I added a try-catch around our getCraftingRemainingItem call and ignore items that throw an exception. This was released as part of Zeta 30.