PepperCode1 / Continuity

A Fabric mod that allows for efficient connected textures
GNU Lesser General Public License v3.0
261 stars 66 forks source link

Crash when other mod overwrites the vanilla block. #439

Closed KedisPL closed 3 days ago

KedisPL commented 1 week ago

If a some mod overwrites the vanilla block then the game crashes or there is infinite loading screen (This does not happen without Continuity). Probably the solution to this would be to check if the id of the block is already in the map, and if it is then the first result is ignored (vanilla block) and the second is used (overwritten block).

The game crashed whilst rendering overlay
Error: java.lang.IllegalArgumentException: Multiple entries with same key: minecraft:fletching_table#=Block{minecraft:fletching_table} and minecraft:fletching_table#=Block{minecraft:fletching_table}

crash-2024-06-20_16.21.40-client.txt

PepperCode1 commented 4 days ago

Continuity intentionally does not support multiple block states using the same model resource location because it is impossible in vanilla (or even with any API that I am aware of) and mods should have no reason to do that. Continuity uses this assumption to make an optimization. Other issues may arise even if duplicate keys are allowed to override each other. Do you know which of your mods causes this? What code is being used to "overwrite" a vanilla block and why? Similar to #303 and Low-Drag-MC/LDLib-Architectury#9, with additional explanations there.

KedisPL commented 3 days ago

This inject detects if a block is a fletching table and if it is it registers that block with my own FletchingTableBlock class, which is a block entity.

@Inject(method = "register(Ljava/lang/String;Lnet/minecraft/world/level/block/Block;)Lnet/minecraft/world/level/block/Block;", at = @At(value = "RETURN"), cancellable = true)
    private static void registerMixin(String string, Block block, CallbackInfoReturnable<Block> callbackInfoReturnable) {
        if (Objects.equals(string, "fletching_table") && block instanceof net.minecraft.world.level.block.FletchingTableBlock) {
            callbackInfoReturnable.setReturnValue(Registry.register(BuiltInRegistries.BLOCK, "fletching_table", new FletchingTableBlock(BlockBehaviour.Properties.of().mapColor(MapColor.WOOD).instrument(NoteBlockInstrument.BASS).strength(2.5f).sound(SoundType.WOOD).ignitedByLava())));
        }
    }
PepperCode1 commented 3 days ago

The mixin is injecting at RETURN, meaning the original register call runs and now there are two blocks registered with the same resource location. I am guessing that injecting at HEAD instead will cause the original fletching table block to crash the game due to its holder being unbound. I recommend you redirect the constructor of the original fletching table block to instead create your block, or mixin to the fletching table block class to add the necessary behavior, or register your fletching table block as a separate block with a separate resource location and use events to ensure the item places your block instead of the vanilla block.