IllegalStateException: Accessing LegacyRandomSource from multiple threads
Ninjawolf0007 opened this issue ยท 5 comments
Issue type:
- ๐ Bug
Short description:
Game crashes due to blood_splash particle colliding with blood_stain block.
Exact Error:
The game crashed whilst accessing legacyrandomsource from multiple threads
Error: java.lang.IllegalStateException: Accessing LegacyRandomSource from multiple threads
Same as #954 and #949 in the ATM8 modpack.
Steps to reproduce the problem:
- Load the game, play for a while
- Mobs receive damage by falling or in a mob farm
- Game crashes due to collision of blood particle and blood stain
Expected behaviour:
The game should not be crashing randomly due to blood stain block and blood splash particle interaction.
Versions:
- This mod: EvilCraft 1.2.12
- Minecraft: 1.19.
- Forge: 43.1.55
- ATM8 Modpack: 1.0.7
Log file:
EvilCraft isn't using LegacyRandomSource
anywhere anymore since #954 as it isn't thread-safe.
However, Minecraft itself is using LegacyRandomSource
for spawning particles. So if another mod is using LegacyRandomSource
incorrectly, and Minecraft spawn a particle, a delayed crash will occur. So the other mod that is using LegacyRandomSource
incorrectly is at fault here.
Other particle-generating mods will likely result in a similar crash due to this, even though they are not at fault.
I recommend reporting to your modpack author, and asking them to add/remove mods until they find the offending mod, and reporting it to them. There's not much I can do on my end unfortunately.
Alright, I've looked into this again. Not sure where my head was at before, but I've reverted my previous changes, applied the suggested changes, and released a new version.
Thanks again @XFactHD for your input!
Since this issue is still happening in the latest version of AllTheMods 8 (1.0.9), further research into this was done and it was found that EvilCraft is indeed at fault here despite the previous fix. The previously deployed fix doesn't achieve anything regarding this issue as the crash doesn't happen directly in any of the code touched by the fix since that code did use the correct RandomSource
from the Level
given by the caller. The actual crash always happens in Minecraft code when the LevelRenderer
tries to apply some particle amount randomisation because it tries to use the client level's random from the server thread where your code unintentionally calls it from.
The underlying issue causing this crash is that the spawning of the blood splash particles (https://github.com/CyclopsMC/EvilCraft/blob/master-1.19/src/main/java/org/cyclops/evilcraft/block/BlockBloodStain.java#L120-L125) does not check for the logical client side, it only checks for the physical client side, both explicitely via the helper call (checks FMLEnvironment.dist == Dist.CLIENT
, which is purely the physical side) and implicitely via the @OnlyIn(Dist.CLIENT)
annotation. This leads to the particle spawning code being called from the server thread in singleplayer as is visible in both the stacktrace linked by the OP and this log snippet where the logging of the LegacyRandomSource
was extended via Mixins for debugging purposes. The proper fix for this is to replace the helper call with a call to Level#isClientSide()
in the method linked above, which would prevent the code from reaching across logical sides and crashing in the LevelRenderer
's random shenanigans.
It's also worth noting that the previous fix is potentially unsafe since it deploys a global and completely unguarded SingleThreadedRandomSource
, which may produce weird results when accessed from multiple threads, which is the reason why the LegacyRandomSource
crashes in these concurrent access scenarios.
An evil mod for Minecraft. Contribute to CyclopsMC/EvilCraft development by creating an account on GitHub.
Thanks for the findings @XFactHD! Will have a look at this soon.