AppliedEnergistics / Applied-Energistics-2

A Minecraft Mod about Matter, Energy and using them to conquer the world..
https://appliedenergistics.github.io/
Other
1.38k stars 622 forks source link

Crafting jobs don't resume after loading a saved world #8006

Open Mithi83 opened 1 week ago

Mithi83 commented 1 week ago

Describe the bug

A crafting job that is still running when leaving the world will not resume when loading that world again.

How to reproduce the bug

Expected behavior

Crafting resumes after loading the world.

Additional details

No response

Which minecraft version are you using?

1.21

On which mod loaders does it happen?

NeoForge

Crash log

Selfcompiled main branch

Mithi83 commented 1 week ago

A bit of debug-printing in a minimal setup (1 CPU, 1 Pattern Provider, 1 Molecular Assembler) revealed the following: The CraftingCpuLogic tries to call executeCrafting() and gets different results depending on whether we are in a working scenario before the save&quit or in a non-working scenario after a rejoin. In a working scenario the for loop over craftingService.getProviders(details) finds the provider, after a rejoin the for loop does not print anything, leading me to the conclusion that craftingService.getProviders(details) returns an empty container. I'll investigate further at a later point.

Mithi83 commented 1 week ago

I added a second crafting storage to the setup and it gets even stranger. In the broken state after rejoining a world with a crafting job in progress that will now hang forever, starting another crafting job of the same pattern works without any problems.

With the debugger I could narrow down the point where it fails to this:

This can be traced back all the way to CraftingCpuLogic.executeCrafting() where we get details = task.getKey(). This basically means that it is another instance of AECraftingPattern that was loaded when rejoining the world, even though after a superficial look it seems to have the same values inside. The key point is that the hash is different and it therefore cannot find a provider for that non-existing AECraftingPattern.

Next step would be to trace it back to the place where the tasks are loaded from the file, but that will probably be a debugging session for another day.

Mithi83 commented 1 week ago

Some new observations: hashCode is not constant. Restarting the game multiple times (not just saving/rejoining, but rather quitting the java process entirely) yields different hashCode values for the task that was running across a rejoin as well as the available pattern in the pattern provider between restarts. Just reloading yields different hashCode values for the task saved in the NBT of the crafting cpu, however the hashCode provided by the pattern in the pattern provider is constant.

There are two different code paths involved in getting these hashCodes. One is CraftingCpuLogic.readFromNBT which uses AEItemKey.fromTag(), the other is PatternProviderLogic.updatePatterns which ultimately uses AEItemKey.of(). The former is not constant across rejoins, the latter is constant.