Spectrum

Spectrum

2M Downloads

[BUG] Using ItemPredicate in another mod statically loads SpectrumBlocks too early, causing crashes

Fourmisain opened this issue ยท 3 comments

commented

Describe the bug
This is a weird one, here's how we found it:
When Cozy Cabincore (Github) is installed together with Spectrum, any entity walking on Citrine blocks causes a crash because the block's SoundBlockGroup is null.

What's weirder is that Cozy Cabincore codewise doesn't even do anything special and only has 3 unrelated mixins (2 of which are accessors/invokers).

Looking further into it, it turns out that with Cozy Cabincore, SpectrumBlocks is statically initialized before SpectrumBlockSoundGroups.init() is called, hence SpectrumBlocks.CITRINE_BLOCK is registered but the SpectrumBlockSoundGroups.CITRINE_BLOCK is null at that point.

Here's how this happens
Cozy Cabincore calls the ItemPredicate constructor. Through Spectrum's ItemPredicateMixin, SpectrumItems is statically loaded, which in turn statically loads SpectrumBlocks - all before SpectrumBlockSoundGroups.init(), though that might depend on mod load order.

This can be seen by printing the stack trace at the beginning of SpectrumBlocks, e.g.

    static {
        logInfo("SpectrumBlocks static init, SpectrumBlockSoundGroups.CITRINE_BLOCK = " + SpectrumBlockSoundGroups.CITRINE_BLOCK);

        // print current stack trace
        for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
            System.out.println(ste);
        }
    }

The log shows

Mixing ItemPredicateMixin from spectrum.mixins.json into net.minecraft.class_2073
[STDOUT]: java.base/java.lang.Thread.getStackTrace(Thread.java:1610)
[STDOUT]: de.dafuqs.spectrum.registries.SpectrumBlocks.<clinit>(SpectrumBlocks.java:122)
[STDOUT]: de.dafuqs.spectrum.registries.SpectrumItems.<clinit>(SpectrumItems.java:72)
[STDOUT]: net.minecraft.class_2073.localvar$zof000$addSpectrumShears(class_2073.java:524)
[STDOUT]: net.minecraft.class_2073.<init>(class_2073.java)
[STDOUT]: net.minecraft.class_2073$class_2074.method_8976(class_2073.java:274)
[STDOUT]: net.minecraft.class_223.method_944(class_223.java:39)
[STDOUT]: net.minecraft.class_186$class_187.<init>(class_186.java:48)
[STDOUT]: net.minecraft.class_186.method_826(class_186.java:65)
[STDOUT]: net.minecraft.class_5341$class_210.method_893(class_5341.java:20)
[STDOUT]: net.linkle.cozy.init.ModLootTable.<clinit>(ModLootTable.java:22)
[STDOUT]: net.linkle.cozy.CozyCabinCore.onInitialize(CozyCabinCore.java:33)
(...)
[Spectrum] SpectrumBlocks static init, SpectrumBlockSoundGroups.CITRINE_BLOCK = null
[Spectrum] Registering BlockSound Groups...
(...)
[Spectrum] Registering Blocks...

To Reproduce
Install Cozy Cabincore, load any world and try to place or walk on a Citrine block.

Mod version
Spectrum 1.4.1 (and Cozy Cabincore 1.1)

Crash Report
Placing a Citrine block down:

[Render thread/ERROR]: Unreported exception thrown!
java.lang.NullPointerException: Cannot invoke "net.minecraft.class_2498.method_10598()" because the return value of "net.minecraft.class_2680.method_26231()" is null
	at Not Enough Crashes deobfuscated stack trace.(1.18.2+build.3) ~[?:?]
	at net.minecraft.item.BlockItem.getPlaceSound(BlockItem:105) ~[?:?]
	at net.minecraft.item.BlockItem.place(BlockItem:96) ~[?:?]
	at net.minecraft.item.BlockItem.useOnBlock(BlockItem:50) ~[?:?]

class_2498 = BlockSoundGroup

Potential fix
This issue should be fixable by doing all the SpectrumBlockSoundGroups initialization statically instead of relying on init() being called.

commented

While I could not reproduce it (mod load order sounds like the most logical issue here) I made the BlockSoundGroups initialize statically. Should solve that problem either way.

commented

I haven't had issues with a player walking on citrine
with spectrum 1.4.1 and cozy cabincore 1.0

commented

Huh, interesting. Thank you for the very in-depth report. I will see what I can do