From 97eef980fdfb0153b2b5731eca86cd37766763c9 Mon Sep 17 00:00:00 2001 From: Nischhelm Date: Sun, 3 Aug 2025 09:17:45 +0200 Subject: [PATCH 1/4] foamfix unload entities patch created concurrentmodificationexceptions for me about 10 times per day on a server. it was missing one line that forge probably added after that foamfix patch was made (2017) --- build.gradle | 1 + gradle.properties | 1 + .../fermiummixins/config/FoamFixConfig.java | 31 +++++++++++++++++++ .../fermiummixins/handlers/ConfigHandler.java | 3 ++ .../foamfix/WorldRemovalInjectMixin.java | 21 +++++++++++++ .../mixin/foamfix/vanilla/WorldAccessor.java | 11 +++++++ .../fermiummixins/util/ModLoadedUtil.java | 1 + ...ummixins.early.foamfix.unloadentities.json | 11 +++++++ ...iummixins.late.foamfix.unloadentities.json | 11 +++++++ 9 files changed, 91 insertions(+) create mode 100644 src/main/java/fermiummixins/config/FoamFixConfig.java create mode 100644 src/main/java/fermiummixins/mixin/foamfix/WorldRemovalInjectMixin.java create mode 100644 src/main/java/fermiummixins/mixin/foamfix/vanilla/WorldAccessor.java create mode 100644 src/main/resources/mixins.fermiummixins.early.foamfix.unloadentities.json create mode 100644 src/main/resources/mixins.fermiummixins.late.foamfix.unloadentities.json diff --git a/build.gradle b/build.gradle index 377deb1..0db62e4 100644 --- a/build.gradle +++ b/build.gradle @@ -62,6 +62,7 @@ dependencies { implementation fg.deobf("curse.maven:elenai-${elenai_version}") implementation fg.deobf("curse.maven:fancymenu-${fancymenu_version}") implementation fg.deobf("curse.maven:firstaid-${firstaid_version}") + implementation fg.deobf("curse.maven:foamfix-optimization-mod-${foamfix_version}") implementation fg.deobf("curse.maven:foodexpansion-${foodexpansion_version}") implementation fg.deobf("curse.maven:forgottenitems-${forgottenitems_version}") implementation fg.deobf("curse.maven:infernalmobs-${infernalmobs_version}") diff --git a/gradle.properties b/gradle.properties index d6731e0..e07990f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -60,6 +60,7 @@ dynamicsurroundingshud_version=309318:2820653 elenai_version=373104:3575333 fancymenu_version=367706:4655936 firstaid_version=276837:4414252 +foamfix_version=278494:3973967 foodexpansion_version=235328:2573308 forgottenitems_version=262884:4167346 infernalmobs_version=227875:2771611 diff --git a/src/main/java/fermiummixins/config/FoamFixConfig.java b/src/main/java/fermiummixins/config/FoamFixConfig.java new file mode 100644 index 0000000..2a89edc --- /dev/null +++ b/src/main/java/fermiummixins/config/FoamFixConfig.java @@ -0,0 +1,31 @@ +package fermiummixins.config; + +import fermiumbooter.annotations.MixinConfig; +import fermiummixins.FermiumMixins; +import fermiummixins.util.ModLoadedUtil; +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.common.config.Config; +import net.minecraftforge.fml.common.registry.ForgeRegistries; +import org.apache.logging.log4j.Level; + +import java.util.HashSet; + +@MixinConfig(name = FermiumMixins.MODID) +public class FoamFixConfig { + + @Config.Comment("Patch \"fixWorldEntityCleanup\" of FoamFix rarely creating ConcurrentModificationException crashes due to being older than the forge code it fixes.") + @Config.Name("Patch World Entity Cleanup Fix (FoamFix)") + @Config.RequiresMcRestart + @MixinConfig.MixinToggle( + earlyMixin = "mixins.fermiummixins.early.foamfix.unloadentities.json", + lateMixin = "mixins.fermiummixins.late.foamfix.unloadentities.json", + defaultValue = false) + @MixinConfig.CompatHandling( + modid = ModLoadedUtil.FoamFix_MODID, + desired = true, + reason = "Requires mod to properly function" + ) + public boolean patchUpdateEntitiesPatch = false; +} \ No newline at end of file diff --git a/src/main/java/fermiummixins/handlers/ConfigHandler.java b/src/main/java/fermiummixins/handlers/ConfigHandler.java index 09af0d0..e91387a 100644 --- a/src/main/java/fermiummixins/handlers/ConfigHandler.java +++ b/src/main/java/fermiummixins/handlers/ConfigHandler.java @@ -91,6 +91,9 @@ public class ConfigHandler { @Config.Name("FirstAid Config") public static final FirstAidConfig FIRSTAID_CONFIG = new FirstAidConfig(); + + @Config.Name("FoamFix Config") + public static final FoamFixConfig FOAMFIX_CONFIG = new FoamFixConfig(); @Config.Name("FoodExpansion Config") public static final FoodExpansionConfig FOODEXPANSION_CONFIG = new FoodExpansionConfig(); diff --git a/src/main/java/fermiummixins/mixin/foamfix/WorldRemovalInjectMixin.java b/src/main/java/fermiummixins/mixin/foamfix/WorldRemovalInjectMixin.java new file mode 100644 index 0000000..acc867a --- /dev/null +++ b/src/main/java/fermiummixins/mixin/foamfix/WorldRemovalInjectMixin.java @@ -0,0 +1,21 @@ +package fermiummixins.mixin.foamfix; + +import fermiummixins.mixin.foamfix.vanilla.WorldAccessor; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import pl.asie.foamfix.coremod.injections.WorldRemovalInject; + +@Mixin(WorldRemovalInject.class) +public abstract class WorldRemovalInjectMixin { + + @Inject( + method = "foamfix_removeUnloadedEntities", + at = @At(value = "INVOKE", target = "Lnet/minecraft/profiler/Profiler;endStartSection(Ljava/lang/String;)V") + ) + public void foamfix_removeUnloadedEntities(CallbackInfo ci) { + //The patch by FoamFix was created before Forge added this line in World.updateEntities + ((WorldAccessor) this).setProcessingLoadedTiles(true); //FML Move above remove to prevent CMEs + } +} diff --git a/src/main/java/fermiummixins/mixin/foamfix/vanilla/WorldAccessor.java b/src/main/java/fermiummixins/mixin/foamfix/vanilla/WorldAccessor.java new file mode 100644 index 0000000..5fdefdc --- /dev/null +++ b/src/main/java/fermiummixins/mixin/foamfix/vanilla/WorldAccessor.java @@ -0,0 +1,11 @@ +package fermiummixins.mixin.foamfix.vanilla; + +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(World.class) +public interface WorldAccessor { + @Accessor("processingLoadedTiles") + void setProcessingLoadedTiles(boolean newValue); +} diff --git a/src/main/java/fermiummixins/util/ModLoadedUtil.java b/src/main/java/fermiummixins/util/ModLoadedUtil.java index 9eca9e0..67a4d9e 100644 --- a/src/main/java/fermiummixins/util/ModLoadedUtil.java +++ b/src/main/java/fermiummixins/util/ModLoadedUtil.java @@ -35,6 +35,7 @@ public abstract class ModLoadedUtil { public static final String ElenaiDodge_MODID = "elenaidodge"; public static final String FancyMenu_MODID = "fancymenu"; public static final String FirstAid_MODID = "firstaid"; + public static final String FoamFix_MODID = "foamfix"; public static final String FoodExpansion_MODID = "foodexpansion"; public static final String ForgottenItems_MODID = "forgottenitems"; public static final String InfernalMobs_MODID = "infernalmobs"; diff --git a/src/main/resources/mixins.fermiummixins.early.foamfix.unloadentities.json b/src/main/resources/mixins.fermiummixins.early.foamfix.unloadentities.json new file mode 100644 index 0000000..9d60bbc --- /dev/null +++ b/src/main/resources/mixins.fermiummixins.early.foamfix.unloadentities.json @@ -0,0 +1,11 @@ +{ + "required": true, + "package": "fermiummixins.mixin", + "refmap": "mixins.fermiummixins.refmap.json", + "compatibilityLevel": "JAVA_8", + "target": "@env(DEFAULT)", + "minVersion": "0.8", + "mixins": [ + "foamfix.vanilla.WorldAccessor" + ] +} \ No newline at end of file diff --git a/src/main/resources/mixins.fermiummixins.late.foamfix.unloadentities.json b/src/main/resources/mixins.fermiummixins.late.foamfix.unloadentities.json new file mode 100644 index 0000000..8bd402d --- /dev/null +++ b/src/main/resources/mixins.fermiummixins.late.foamfix.unloadentities.json @@ -0,0 +1,11 @@ +{ + "required": true, + "package": "fermiummixins.mixin", + "refmap": "mixins.fermiummixins.refmap.json", + "compatibilityLevel": "JAVA_8", + "target": "@env(DEFAULT)", + "minVersion": "0.8", + "mixins": [ + "foamfix.WorldRemovalInjectMixin" + ] +} \ No newline at end of file From a26e008f8438c3cf9d2471bfde5d6b8a22080421 Mon Sep 17 00:00:00 2001 From: Nischhelm Date: Sun, 3 Aug 2025 19:55:30 +0200 Subject: [PATCH 2/4] moved to a vanilla mixin checking with @Debug revealed that it didnt apply the mixin at all. i guess with some mixin magic (mixin into worldserver instead of the patch class of foamfix?) it could be done but this should work too will test on my server --- build.gradle | 1 - gradle.properties | 1 - .../fermiummixins/config/FoamFixConfig.java | 31 --------- .../fermiummixins/config/VanillaConfig.java | 6 ++ .../fermiummixins/handlers/ConfigHandler.java | 3 - .../foamfix/WorldRemovalInjectMixin.java | 21 ------ .../{foamfix => }/vanilla/WorldAccessor.java | 8 ++- .../mixin/vanilla/WorldServerMixin.java | 66 +++++++++++++++++++ ...ummixins.early.foamfix.unloadentities.json | 11 ---- ...mmixins.early.vanilla.unloadentities.json} | 3 +- 10 files changed, 81 insertions(+), 70 deletions(-) delete mode 100644 src/main/java/fermiummixins/config/FoamFixConfig.java delete mode 100644 src/main/java/fermiummixins/mixin/foamfix/WorldRemovalInjectMixin.java rename src/main/java/fermiummixins/mixin/{foamfix => }/vanilla/WorldAccessor.java (58%) create mode 100644 src/main/java/fermiummixins/mixin/vanilla/WorldServerMixin.java delete mode 100644 src/main/resources/mixins.fermiummixins.early.foamfix.unloadentities.json rename src/main/resources/{mixins.fermiummixins.late.foamfix.unloadentities.json => mixins.fermiummixins.early.vanilla.unloadentities.json} (77%) diff --git a/build.gradle b/build.gradle index 0db62e4..377deb1 100644 --- a/build.gradle +++ b/build.gradle @@ -62,7 +62,6 @@ dependencies { implementation fg.deobf("curse.maven:elenai-${elenai_version}") implementation fg.deobf("curse.maven:fancymenu-${fancymenu_version}") implementation fg.deobf("curse.maven:firstaid-${firstaid_version}") - implementation fg.deobf("curse.maven:foamfix-optimization-mod-${foamfix_version}") implementation fg.deobf("curse.maven:foodexpansion-${foodexpansion_version}") implementation fg.deobf("curse.maven:forgottenitems-${forgottenitems_version}") implementation fg.deobf("curse.maven:infernalmobs-${infernalmobs_version}") diff --git a/gradle.properties b/gradle.properties index e07990f..d6731e0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -60,7 +60,6 @@ dynamicsurroundingshud_version=309318:2820653 elenai_version=373104:3575333 fancymenu_version=367706:4655936 firstaid_version=276837:4414252 -foamfix_version=278494:3973967 foodexpansion_version=235328:2573308 forgottenitems_version=262884:4167346 infernalmobs_version=227875:2771611 diff --git a/src/main/java/fermiummixins/config/FoamFixConfig.java b/src/main/java/fermiummixins/config/FoamFixConfig.java deleted file mode 100644 index 2a89edc..0000000 --- a/src/main/java/fermiummixins/config/FoamFixConfig.java +++ /dev/null @@ -1,31 +0,0 @@ -package fermiummixins.config; - -import fermiumbooter.annotations.MixinConfig; -import fermiummixins.FermiumMixins; -import fermiummixins.util.ModLoadedUtil; -import net.minecraft.block.Block; -import net.minecraft.init.Blocks; -import net.minecraft.util.ResourceLocation; -import net.minecraftforge.common.config.Config; -import net.minecraftforge.fml.common.registry.ForgeRegistries; -import org.apache.logging.log4j.Level; - -import java.util.HashSet; - -@MixinConfig(name = FermiumMixins.MODID) -public class FoamFixConfig { - - @Config.Comment("Patch \"fixWorldEntityCleanup\" of FoamFix rarely creating ConcurrentModificationException crashes due to being older than the forge code it fixes.") - @Config.Name("Patch World Entity Cleanup Fix (FoamFix)") - @Config.RequiresMcRestart - @MixinConfig.MixinToggle( - earlyMixin = "mixins.fermiummixins.early.foamfix.unloadentities.json", - lateMixin = "mixins.fermiummixins.late.foamfix.unloadentities.json", - defaultValue = false) - @MixinConfig.CompatHandling( - modid = ModLoadedUtil.FoamFix_MODID, - desired = true, - reason = "Requires mod to properly function" - ) - public boolean patchUpdateEntitiesPatch = false; -} \ No newline at end of file diff --git a/src/main/java/fermiummixins/config/VanillaConfig.java b/src/main/java/fermiummixins/config/VanillaConfig.java index 46f91a7..420b0e5 100644 --- a/src/main/java/fermiummixins/config/VanillaConfig.java +++ b/src/main/java/fermiummixins/config/VanillaConfig.java @@ -528,6 +528,12 @@ public class VanillaConfig { @Config.RequiresMcRestart @MixinConfig.MixinToggle(earlyMixin = "mixins.fermiummixins.early.vanilla.blockstorageoptifine.json", defaultValue = false) public boolean blockStorageOptifineLagFix = false; + + @Config.Comment("A modern version of \"fixWorldEntityCleanup\" by FoamFix. Made because the one by FoamFix was rarely creating ConcurrentModificationException crashes due to being older than the forge code it fixed.") + @Config.Name("Unload Entities on empty world (Vanilla)") + @Config.RequiresMcRestart + @MixinConfig.MixinToggle(earlyMixin = "mixins.fermiummixins.early.vanilla.unloadentities.json", defaultValue = false) + public boolean patchUpdateEntitiesPatch = false; private Set tippedArrowBlacklistedPotions = null; private List particleRetainCollisionClasses = null; diff --git a/src/main/java/fermiummixins/handlers/ConfigHandler.java b/src/main/java/fermiummixins/handlers/ConfigHandler.java index e91387a..09af0d0 100644 --- a/src/main/java/fermiummixins/handlers/ConfigHandler.java +++ b/src/main/java/fermiummixins/handlers/ConfigHandler.java @@ -91,9 +91,6 @@ public class ConfigHandler { @Config.Name("FirstAid Config") public static final FirstAidConfig FIRSTAID_CONFIG = new FirstAidConfig(); - - @Config.Name("FoamFix Config") - public static final FoamFixConfig FOAMFIX_CONFIG = new FoamFixConfig(); @Config.Name("FoodExpansion Config") public static final FoodExpansionConfig FOODEXPANSION_CONFIG = new FoodExpansionConfig(); diff --git a/src/main/java/fermiummixins/mixin/foamfix/WorldRemovalInjectMixin.java b/src/main/java/fermiummixins/mixin/foamfix/WorldRemovalInjectMixin.java deleted file mode 100644 index acc867a..0000000 --- a/src/main/java/fermiummixins/mixin/foamfix/WorldRemovalInjectMixin.java +++ /dev/null @@ -1,21 +0,0 @@ -package fermiummixins.mixin.foamfix; - -import fermiummixins.mixin.foamfix.vanilla.WorldAccessor; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import pl.asie.foamfix.coremod.injections.WorldRemovalInject; - -@Mixin(WorldRemovalInject.class) -public abstract class WorldRemovalInjectMixin { - - @Inject( - method = "foamfix_removeUnloadedEntities", - at = @At(value = "INVOKE", target = "Lnet/minecraft/profiler/Profiler;endStartSection(Ljava/lang/String;)V") - ) - public void foamfix_removeUnloadedEntities(CallbackInfo ci) { - //The patch by FoamFix was created before Forge added this line in World.updateEntities - ((WorldAccessor) this).setProcessingLoadedTiles(true); //FML Move above remove to prevent CMEs - } -} diff --git a/src/main/java/fermiummixins/mixin/foamfix/vanilla/WorldAccessor.java b/src/main/java/fermiummixins/mixin/vanilla/WorldAccessor.java similarity index 58% rename from src/main/java/fermiummixins/mixin/foamfix/vanilla/WorldAccessor.java rename to src/main/java/fermiummixins/mixin/vanilla/WorldAccessor.java index 5fdefdc..67a71fd 100644 --- a/src/main/java/fermiummixins/mixin/foamfix/vanilla/WorldAccessor.java +++ b/src/main/java/fermiummixins/mixin/vanilla/WorldAccessor.java @@ -1,11 +1,17 @@ -package fermiummixins.mixin.foamfix.vanilla; +package fermiummixins.mixin.vanilla; +import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; +import java.util.List; + @Mixin(World.class) public interface WorldAccessor { @Accessor("processingLoadedTiles") void setProcessingLoadedTiles(boolean newValue); + + @Accessor("tileEntitiesToBeRemoved") + List getTileEntitiesToBeRemoved(); } diff --git a/src/main/java/fermiummixins/mixin/vanilla/WorldServerMixin.java b/src/main/java/fermiummixins/mixin/vanilla/WorldServerMixin.java new file mode 100644 index 0000000..10a9e71 --- /dev/null +++ b/src/main/java/fermiummixins/mixin/vanilla/WorldServerMixin.java @@ -0,0 +1,66 @@ +package fermiummixins.mixin.vanilla; + +import net.minecraft.entity.Entity; +import net.minecraft.profiler.Profiler; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; +import net.minecraft.world.WorldProvider; +import net.minecraft.world.WorldServer; +import net.minecraft.world.storage.ISaveHandler; +import net.minecraft.world.storage.WorldInfo; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.Collections; +import java.util.IdentityHashMap; +import java.util.List; +import java.util.Set; + +@Mixin(WorldServer.class) +public abstract class WorldServerMixin extends World { + protected WorldServerMixin(ISaveHandler saveHandlerIn, WorldInfo info, WorldProvider providerIn, Profiler profilerIn, boolean client) { + super(saveHandlerIn, info, providerIn, profilerIn, client); + } + + //Copied from FoamFix (patch from 2017), modified to not create rare Concurrent Modification Exceptions + @Inject( + method = "updateEntities", + at = @At(value = "RETURN", ordinal = 0) + ) + public void fermiumMixins_vanillaWorldServer_updateEntities(CallbackInfo ci) { + this.profiler.startSection("entities"); + this.profiler.endStartSection("remove"); + this.loadedEntityList.removeAll(this.unloadedEntityList); + + for (Entity entityToUnload : this.unloadedEntityList) + if (entityToUnload.addedToChunk && this.isChunkLoaded(entityToUnload.chunkCoordX, entityToUnload.chunkCoordZ, true)) + this.getChunk(entityToUnload.chunkCoordX, entityToUnload.chunkCoordZ).removeEntity(entityToUnload); + + this.unloadedEntityList.forEach(this::onEntityRemoved); + + this.unloadedEntityList.clear(); + + this.profiler.endStartSection("blockEntities"); + + ((WorldAccessor) this).setProcessingLoadedTiles(true); //FML Move above remove to prevent CMEs + + List tileEntitiesToBeRemoved = ((WorldAccessor) this).getTileEntitiesToBeRemoved(); + + if (!tileEntitiesToBeRemoved.isEmpty()) { + tileEntitiesToBeRemoved.forEach(TileEntity::onChunkUnload); + + // forge: faster "contains" makes this removal much more efficient + Set remove = Collections.newSetFromMap(new IdentityHashMap<>()); + remove.addAll(tileEntitiesToBeRemoved); + + this.tickableTileEntities.removeAll(remove); + this.loadedTileEntityList.removeAll(remove); + tileEntitiesToBeRemoved.clear(); + } + + this.profiler.endSection(); + this.profiler.endSection(); + } +} diff --git a/src/main/resources/mixins.fermiummixins.early.foamfix.unloadentities.json b/src/main/resources/mixins.fermiummixins.early.foamfix.unloadentities.json deleted file mode 100644 index 9d60bbc..0000000 --- a/src/main/resources/mixins.fermiummixins.early.foamfix.unloadentities.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "required": true, - "package": "fermiummixins.mixin", - "refmap": "mixins.fermiummixins.refmap.json", - "compatibilityLevel": "JAVA_8", - "target": "@env(DEFAULT)", - "minVersion": "0.8", - "mixins": [ - "foamfix.vanilla.WorldAccessor" - ] -} \ No newline at end of file diff --git a/src/main/resources/mixins.fermiummixins.late.foamfix.unloadentities.json b/src/main/resources/mixins.fermiummixins.early.vanilla.unloadentities.json similarity index 77% rename from src/main/resources/mixins.fermiummixins.late.foamfix.unloadentities.json rename to src/main/resources/mixins.fermiummixins.early.vanilla.unloadentities.json index 8bd402d..31767b9 100644 --- a/src/main/resources/mixins.fermiummixins.late.foamfix.unloadentities.json +++ b/src/main/resources/mixins.fermiummixins.early.vanilla.unloadentities.json @@ -6,6 +6,7 @@ "target": "@env(DEFAULT)", "minVersion": "0.8", "mixins": [ - "foamfix.WorldRemovalInjectMixin" + "vanilla.WorldAccessor", + "vanilla.WorldServerMixin" ] } \ No newline at end of file From fba302ee36e14127f3f06853bd128153c3a67435 Mon Sep 17 00:00:00 2001 From: Nischhelm Date: Sun, 3 Aug 2025 20:45:17 +0200 Subject: [PATCH 3/4] quick rename --- ...Mixin.java => WorldServer_UnloadEntitiesInEmptyWorld.java} | 4 ++-- .../mixins.fermiummixins.early.vanilla.unloadentities.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename src/main/java/fermiummixins/mixin/vanilla/{WorldServerMixin.java => WorldServer_UnloadEntitiesInEmptyWorld.java} (91%) diff --git a/src/main/java/fermiummixins/mixin/vanilla/WorldServerMixin.java b/src/main/java/fermiummixins/mixin/vanilla/WorldServer_UnloadEntitiesInEmptyWorld.java similarity index 91% rename from src/main/java/fermiummixins/mixin/vanilla/WorldServerMixin.java rename to src/main/java/fermiummixins/mixin/vanilla/WorldServer_UnloadEntitiesInEmptyWorld.java index 10a9e71..dbfa73f 100644 --- a/src/main/java/fermiummixins/mixin/vanilla/WorldServerMixin.java +++ b/src/main/java/fermiummixins/mixin/vanilla/WorldServer_UnloadEntitiesInEmptyWorld.java @@ -19,8 +19,8 @@ import java.util.Set; @Mixin(WorldServer.class) -public abstract class WorldServerMixin extends World { - protected WorldServerMixin(ISaveHandler saveHandlerIn, WorldInfo info, WorldProvider providerIn, Profiler profilerIn, boolean client) { +public abstract class WorldServer_UnloadEntitiesInEmptyWorld extends World { + protected WorldServer_UnloadEntitiesInEmptyWorld(ISaveHandler saveHandlerIn, WorldInfo info, WorldProvider providerIn, Profiler profilerIn, boolean client) { super(saveHandlerIn, info, providerIn, profilerIn, client); } diff --git a/src/main/resources/mixins.fermiummixins.early.vanilla.unloadentities.json b/src/main/resources/mixins.fermiummixins.early.vanilla.unloadentities.json index 31767b9..da86b3f 100644 --- a/src/main/resources/mixins.fermiummixins.early.vanilla.unloadentities.json +++ b/src/main/resources/mixins.fermiummixins.early.vanilla.unloadentities.json @@ -7,6 +7,6 @@ "minVersion": "0.8", "mixins": [ "vanilla.WorldAccessor", - "vanilla.WorldServerMixin" + "vanilla.WorldServer_UnloadEntitiesInEmptyWorld" ] } \ No newline at end of file From 72657b33699c01d149dacb49d5b57a55abcea16b Mon Sep 17 00:00:00 2001 From: Nischhelm Date: Mon, 18 Aug 2025 15:28:11 +0200 Subject: [PATCH 4/4] updated lazy chunk spawn deny "Actually now that i have a bit better knowledge of the spawning logic, skipping not fully loaded chunks might have been the better move after all. Vanilla varies its mob cap depending on how many of the expected eligiblechunks are actually eligible So with low render it would just reduce mob cap automatically. With my old fix it would still fill up the loaded chunks with the full mobcap, but with the usual speed " --- .../WorldEntitySpawner_LazyChunksMixin.java | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/main/java/fermiummixins/mixin/vanilla/WorldEntitySpawner_LazyChunksMixin.java b/src/main/java/fermiummixins/mixin/vanilla/WorldEntitySpawner_LazyChunksMixin.java index 40d1dbb..846205b 100644 --- a/src/main/java/fermiummixins/mixin/vanilla/WorldEntitySpawner_LazyChunksMixin.java +++ b/src/main/java/fermiummixins/mixin/vanilla/WorldEntitySpawner_LazyChunksMixin.java @@ -1,11 +1,15 @@ package fermiummixins.mixin.vanilla; -import net.minecraft.util.math.MathHelper; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import com.llamalad7.mixinextras.sugar.Local; +import net.minecraft.util.math.ChunkPos; import net.minecraft.world.WorldEntitySpawner; import net.minecraft.world.WorldServer; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; + +import java.util.Set; /** * Fix by Nischhelm @@ -13,16 +17,17 @@ @Mixin(WorldEntitySpawner.class) public abstract class WorldEntitySpawner_LazyChunksMixin { - @Redirect( + @WrapOperation( method = "findChunksForSpawning", - at = @At(value="INVOKE",target = "Lnet/minecraft/world/WorldServer;isAnyPlayerWithinRangeAt(DDDD)Z") + at = @At(value="INVOKE",target = "Ljava/util/Set;add(Ljava/lang/Object;)Z") ) - private boolean fermiummixins_vanillaWorldEntitySpawner_findChunksForSpawning(WorldServer instance, double x, double y, double z, double range) { - int x1 = MathHelper.floor(x); - int z1 = MathHelper.floor(z); - - if(!((IWorldInvoker)instance).invokeIsAreaLoaded(x1 - 32, 0, z1 - 32, x1 + 32, 0, z1 + 32, true)) return true; + private boolean fermiummixins_vanillaWorldEntitySpawner_findChunksForSpawning(Set instance, Object obj, Operation original, @Local(argsOnly = true) WorldServer world) { + ChunkPos cpos = (ChunkPos) obj; + int x1 = cpos.x << 4 + 8; + int z1 = cpos.z << 4 + 8; - return instance.isAnyPlayerWithinRangeAt(x, y, z, range); + if(!((IWorldInvoker)world).invokeIsAreaLoaded(x1 - 32, 0, z1 - 32, x1 + 32, 0, z1 + 32, true)) + return false; + return original.call(instance, obj); } } \ No newline at end of file