13rac1 / Minecraft-Water-Erosion

Minecraft Mod - Adds natural water erosion to create streams and waterfalls
https://www.curseforge.com/minecraft/mc-mods/water-erosion
GNU General Public License v3.0
4 stars 1 forks source link

Servercore incompatability #31

Open arazadaz opened 1 year ago

arazadaz commented 1 year ago

This mod is incompatible with the servercore performance optimization mod.

Here is the crash report: https://mclo.gs/CdfGrJW

13rac1 commented 1 year ago
The specific error from the log > [14:53:13] [main/ERROR]: Mixin apply for mod servercore failed servercore.common.mixins.json:optimizations.ticking.chunk.random.LiquidBlockMixin from mod servercore -> net.minecraft.class_2404: org.spongepowered.asm.mixin.injection.throwables.InvalidInjectionException @At("INVOKE") on net/minecraft/class_2404::servercore$cancelDuplicateFluidTicks with priority 1000 cannot inject into net/minecraft/class_2404::method_9542(Lnet/minecraft/class_2680;)Z merged by com._13rac1.erosion.fabric.mixin.LiquidBlockMixin with priority 1000 [PREINJECT Applicator Phase -> servercore.common.mixins.json:optimizations.ticking.chunk.random.LiquidBlockMixin from mod servercore -> Prepare Injections -> -> redirect$hjd000$servercore$cancelDuplicateFluidTicks(Lnet/minecraft/class_3610;)Z -> Prepare] org.spongepowered.asm.mixin.injection.throwables.InvalidInjectionException: @At("INVOKE") on net/minecraft/class_2404::servercore$cancelDuplicateFluidTicks with priority 1000 cannot inject into net/minecraft/class_2404::method_9542(Lnet/minecraft/class_2680;)Z merged by com._13rac1.erosion.fabric.mixin.LiquidBlockMixin with priority 1000 [PREINJECT Applicator Phase -> servercore.common.mixins.json:optimizations.ticking.chunk.random.LiquidBlockMixin from mod servercore -> Prepare Injections -> -> redirect$hjd000$servercore$cancelDuplicateFluidTicks(Lnet/minecraft/class_3610;)Z -> Prepare]

This is crash caused by duplicate Mixin Framework @Override/@Redirect of LiquidBlock.isRandomlyTicking() by Servercore and Water Erosion. isRandomlyTicking() must be enabled for Water Erosion to function, but Servercore disables the ticks. [Mixin Injection Point reference]

servercore 1.19.2 : https://github.com/Wesley1808/ServerCore/blob/bbddbc8c/common/src/main/java/me/wesley1808/servercore/mixin/optimizations/ticking/chunk/random/LiquidBlockMixin.java#L14-L27

    /**
     * Liquid blocks already run their fluid random ticks in {@link ServerLevel#tickChunk(LevelChunk, int)}
     * This patch gets rid of the second 'duplicate' random tick.
     */
    @Redirect(
            method = "isRandomlyTicking",
            at = @At(
                    value = "INVOKE",
                    target = "Lnet/minecraft/world/level/material/FluidState;isRandomlyTicking()Z"
            )
    )
    private boolean servercore$cancelDuplicateFluidTicks(FluidState fluidState) {
        return false;
    }

water-erosion: https://github.com/13rac1/Minecraft-Water-Erosion/blob/6de8671fbf463cc5d8b5bec937cad7d5056fc3dc/fabric/src/main/java/com/_13rac1/erosion/fabric/mixin/LiquidBlockMixin.java#L26-L30

🤔 The Servercore code comment states: Liquid blocks already run their fluid random ticks in {@link ServerLevel#tickChunk(LevelChunk, int)} So, I look at the ServerLevel.class and find:

      if (i > 0) {
         LevelChunkSection[] levelChunkSections = levelChunk.getSections();

         for(int n = 0; n < levelChunkSections.length; ++n) {
            LevelChunkSection levelChunkSection = levelChunkSections[n];
            if (levelChunkSection.isRandomlyTicking()) {
               l = levelChunk.getSectionYFromSectionIndex(n);
               int o = SectionPos.sectionToBlockCoord(l);

               for(m = 0; m < i; ++m) {
                  BlockPos blockPos3 = this.getBlockRandomPos(j, o, k, 15);
                  profilerFiller.push("randomTick");
                  BlockState blockState4 = levelChunkSection.getBlockState(blockPos3.getX() - j, blockPos3.getY() - o, blockPos3.getZ() - k);
                  if (blockState4.isRandomlyTicking()) {
                     blockState4.randomTick(this, blockPos3, this.random);
                  }

                  FluidState fluidState = blockState4.getFluidState();
                  if (fluidState.isRandomlyTicking()) {
                     fluidState.randomTick(this, blockPos3, this.random);
                  }

When fluidState.isRandomlyTicking() is false, fluidState.randomTick() is never called. Where is the other call to fluidState.randomTick()? Is there really a "second 'duplicate' random tick"? I must be missing something here. I'm open to suggestions for how to make this compatible with Servercore, but I've reached my time limit for researching this issue.