Skip to content

Commit 420d70f

Browse files
5.27.19 - commit.1
1 parent cae4663 commit 420d70f

28 files changed

Lines changed: 959 additions & 130 deletions

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ org.gradle.jvmargs=-Xmx2G
33

44
# Mod properties
55
mod_id=modernfix
6-
version=5.27.18-build.1
6+
version=5.27.19-build.1
77

88
# Minecraft/Fabric
99
minecraft_version=26.2
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package org.embeddedt.modernfix.annotation;
2+
3+
public enum FeatureLevel {
4+
GA, BETA;
5+
6+
public boolean isAtLeast(FeatureLevel required) {
7+
return this.ordinal() >= required.ordinal();
8+
}
9+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package org.embeddedt.modernfix.annotation;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
7+
8+
@Retention(RetentionPolicy.CLASS)
9+
@Target({ElementType.TYPE, ElementType.PACKAGE})
10+
public @interface RequiresFeatureLevel {
11+
FeatureLevel value() default FeatureLevel.GA;
12+
}

src/main/java/org/embeddedt/modernfix/annotation/RequiresMod.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
/**
99
* Marks a mixin class as requiring a specific mod to be present (or absent with ! prefix).
1010
*/
11-
@Target(ElementType.TYPE)
11+
@Target({ElementType.TYPE, ElementType.PACKAGE})
1212
@Retention(RetentionPolicy.RUNTIME)
1313
public @interface RequiresMod {
1414
String value();

src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/missing_block_entities/LevelChunkMixin.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,9 @@ private void makeBlockEntityIfNotExists(BlockState state, BlockPos.MutableBlockP
8585
}
8686

8787
BlockEntity blockEntity = this.getBlockEntity(pos.immutable(), LevelChunk.EntityCreationType.IMMEDIATE);
88-
String blockName = state.getBlock().toString();
89-
if (blockEntity != null) {
90-
ModernFix.LOGGER.warn("Created missing block entity for {} at {}", blockName, pos.toShortString());
91-
} else {
92-
ModernFix.LOGGER.error("Block entity is missing for {} at {}, but could not be created", blockName, pos.toShortString());
88+
if (blockEntity != null && ModernFix.LOGGER.isDebugEnabled()) {
89+
String blockName = state.getBlock().toString();
90+
ModernFix.LOGGER.debug("Created missing block entity for {} at {}", blockName, pos.toShortString());
9391
}
9492
}
9593
}
96-

src/main/java/org/embeddedt/modernfix/common/mixin/perf/cache_strongholds/ChunkGeneratorMixin.java

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22

33
import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
44
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
5+
import com.llamalad7.mixinextras.sugar.Share;
6+
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
7+
import net.minecraft.TracingExecutor;
58
import net.minecraft.core.Holder;
6-
import net.minecraft.core.RegistryAccess;
79
import net.minecraft.nbt.*;
810
import net.minecraft.resources.RegistryOps;
11+
import net.minecraft.server.MinecraftServer;
912
import net.minecraft.util.Util;
1013
import net.minecraft.world.level.ChunkPos;
1114
import net.minecraft.world.level.biome.BiomeSource;
@@ -17,6 +20,8 @@
1720
import org.spongepowered.asm.mixin.Final;
1821
import org.spongepowered.asm.mixin.Mixin;
1922
import org.spongepowered.asm.mixin.Shadow;
23+
import org.spongepowered.asm.mixin.injection.At;
24+
import org.spongepowered.asm.mixin.injection.Redirect;
2025

2126
import java.lang.ref.SoftReference;
2227
import java.nio.charset.StandardCharsets;
@@ -29,6 +34,8 @@
2934
import java.util.List;
3035
import java.util.Map;
3136
import java.util.concurrent.CompletableFuture;
37+
import java.util.concurrent.ExecutorService;
38+
import java.util.concurrent.Executors;
3239

3340
@Mixin(ChunkGeneratorStructureState.class)
3441
public class ChunkGeneratorMixin implements IChunkGenerator {
@@ -41,22 +48,23 @@ public class ChunkGeneratorMixin implements IChunkGenerator {
4148
private BiomeSource biomeSource;
4249

4350
private Path mfix$dimensionPath;
44-
private RegistryAccess.Frozen mfix$registryAccess;
51+
private MinecraftServer mfix$server;
4552
private SoftReference<Map<String, List<ChunkPos>>> mfix$cachedPositions = new SoftReference<>(null);
4653

4754
private static final String CACHE_FILENAME = "mfix_stronghold_cache_v2.nbt";
4855

4956
@Override
50-
public void mfix$setStrongholdCachePath(Path cachePath, RegistryAccess.Frozen registryAccess) {
57+
public void mfix$setStrongholdCachePath(Path cachePath, MinecraftServer server) {
5158
this.mfix$dimensionPath = cachePath;
52-
this.mfix$registryAccess = registryAccess;
59+
this.mfix$server = server;
5360
}
5461

5562
@WrapMethod(method = "generateRingPositions")
5663
private CompletableFuture<List<ChunkPos>> modernfix$cacheRingPositions(Holder<StructureSet> structureSet,
5764
ConcentricRingsStructurePlacement placement,
58-
Operation<CompletableFuture<List<ChunkPos>>> original) {
59-
if (this.mfix$registryAccess == null || this.mfix$dimensionPath == null) {
65+
Operation<CompletableFuture<List<ChunkPos>>> original,
66+
@Share("threadPool") LocalRef<TracingExecutor> threadPoolRef) {
67+
if (this.mfix$server == null || this.mfix$dimensionPath == null) {
6068
return original.call(structureSet, placement);
6169
}
6270

@@ -69,14 +77,34 @@ public class ChunkGeneratorMixin implements IChunkGenerator {
6977
return CompletableFuture.completedFuture(List.copyOf(cached));
7078
}
7179

72-
return original.call(structureSet, placement).thenApplyAsync(positions -> {
73-
mfix$writeToCache(cacheKey, positions);
74-
return positions;
75-
}, Util.ioPool());
80+
var server = this.mfix$server;
81+
ExecutorService strongholdPool = Executors.newFixedThreadPool(Math.max(1, Runtime.getRuntime().availableProcessors() - 2));
82+
threadPoolRef.set(new TracingExecutor(strongholdPool));
83+
try {
84+
return original.call(structureSet, placement).thenApplyAsync(positions -> {
85+
if (server.isRunning()) {
86+
mfix$writeToCache(cacheKey, positions);
87+
}
88+
return positions;
89+
}, Util.ioPool());
90+
} finally {
91+
strongholdPool.shutdown();
92+
}
93+
}
94+
95+
/**
96+
* @author embeddedt
97+
* @reason Ring position calculation is often not required for initial chunk generation, but the tasks still occupy
98+
* CPU time on the main worker pool and prevent higher priority work from progressing. To fix this we use a
99+
* dedicated pool.
100+
*/
101+
@Redirect(method = "generateRingPositions", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/Util;backgroundExecutor()Lnet/minecraft/TracingExecutor;"))
102+
private TracingExecutor useDedicatedService(@Share("threadPool") LocalRef<TracingExecutor> threadPoolRef) {
103+
return threadPoolRef.get();
76104
}
77105

78106
private String mfix$makeCacheKey(ConcentricRingsStructurePlacement placement) {
79-
RegistryOps<Tag> ops = RegistryOps.create(NbtOps.INSTANCE, this.mfix$registryAccess);
107+
RegistryOps<Tag> ops = RegistryOps.create(NbtOps.INSTANCE, this.mfix$server.registryAccess());
80108
String placementKey = ConcentricRingsStructurePlacement.CODEC.codec().encodeStart(ops, placement)
81109
.result().map(Tag::toString).orElse(null);
82110
String biomeSourceKey = BiomeSource.CODEC.encodeStart(ops, this.biomeSource)
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package org.embeddedt.modernfix.common.mixin.perf.cache_strongholds;
2+
3+
import net.minecraft.world.level.chunk.ChunkGeneratorStructureState;
4+
import net.minecraft.world.level.levelgen.structure.placement.ConcentricRingsStructurePlacement;
5+
import org.embeddedt.modernfix.annotation.FeatureLevel;
6+
import org.embeddedt.modernfix.annotation.RequiresFeatureLevel;
7+
import org.spongepowered.asm.mixin.Final;
8+
import org.spongepowered.asm.mixin.Mixin;
9+
import org.spongepowered.asm.mixin.Shadow;
10+
import org.spongepowered.asm.mixin.Unique;
11+
import org.spongepowered.asm.mixin.injection.At;
12+
import org.spongepowered.asm.mixin.injection.Inject;
13+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
14+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
15+
16+
@Mixin(ConcentricRingsStructurePlacement.class)
17+
@RequiresFeatureLevel(FeatureLevel.BETA)
18+
public class ConcentricRingsStructurePlacementMixin {
19+
20+
@Shadow @Final private int distance;
21+
@Shadow @Final private int spread;
22+
@Shadow @Final private int count;
23+
24+
@Unique private static final int MFIX_MAX_BIOME_SNAP_SECTIONS_PER_AXIS = 7;
25+
@Unique private static final double MFIX_MAX_ROUNDING_ERROR = Math.sqrt(2.0) * 0.5;
26+
@Unique private static final double MFIX_MAX_BIOME_SNAP_ERROR = MFIX_MAX_BIOME_SNAP_SECTIONS_PER_AXIS * Math.sqrt(2.0);
27+
@Unique private static final double MFIX_MAX_POSITION_ERROR = MFIX_MAX_ROUNDING_ERROR + MFIX_MAX_BIOME_SNAP_ERROR;
28+
29+
@Unique private long mfix$innerRadiusSq;
30+
@Unique private long mfix$outerRadiusSq;
31+
32+
@Inject(
33+
method = "<init>(Lnet/minecraft/core/Vec3i;Lnet/minecraft/world/level/levelgen/structure/placement/StructurePlacement$FrequencyReductionMethod;FILjava/util/Optional;IIILnet/minecraft/core/HolderSet;)V",
34+
at = @At("RETURN")
35+
)
36+
private void mfix$computeRadiusBounds(CallbackInfo ci) {
37+
double maxNoise = this.distance * 1.25;
38+
39+
double minDist = 4.0 * this.distance - maxNoise;
40+
double safeInnerRadius = minDist - MFIX_MAX_POSITION_ERROR;
41+
this.mfix$innerRadiusSq = (long)Math.max(0.0, Math.floor(safeInnerRadius * safeInnerRadius));
42+
43+
if (this.spread == 0) {
44+
this.mfix$outerRadiusSq = Long.MAX_VALUE;
45+
return;
46+
}
47+
48+
int maxCircle = this.mfix$computeMaxCircleIndex();
49+
double maxDist = 4.0 * this.distance + (double)this.distance * maxCircle * 6.0 + maxNoise;
50+
double safeOuterRadius = maxDist + MFIX_MAX_POSITION_ERROR;
51+
this.mfix$outerRadiusSq = (long)Math.ceil(safeOuterRadius * safeOuterRadius);
52+
}
53+
54+
@Unique
55+
private int mfix$computeMaxCircleIndex() {
56+
int ringSpread = this.spread;
57+
int total = 0;
58+
int circle = 0;
59+
60+
while (total + ringSpread < this.count) {
61+
total += ringSpread;
62+
circle++;
63+
ringSpread += 2 * ringSpread / (circle + 1);
64+
ringSpread = Math.min(ringSpread, this.count - total);
65+
}
66+
67+
return circle;
68+
}
69+
70+
/**
71+
* @author embeddedt, GPT-5.3-Codex
72+
* @reason Avoid calling getRingPositionsFor() when we know the current chunk lies outside the region where
73+
* concentric placement can even happen.
74+
*/
75+
@Inject(method = "isPlacementChunk", at = @At("HEAD"), cancellable = true)
76+
private void mfix$earlyRejectByRadius(ChunkGeneratorStructureState structureState, int x, int z,
77+
CallbackInfoReturnable<Boolean> cir) {
78+
long distSq = (long)x * x + (long)z * z;
79+
if (distSq < this.mfix$innerRadiusSq || distSq > this.mfix$outerRadiusSq) {
80+
cir.setReturnValue(false);
81+
}
82+
}
83+
}

src/main/java/org/embeddedt/modernfix/common/mixin/perf/cache_strongholds/ServerLevelMixin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ private void setCachePath(ChunkGeneratorStructureState instance, Operation<Void>
2424
@Local(ordinal = 0, argsOnly = true) LevelStorageSource.LevelStorageAccess levelStorageAccess,
2525
@Local(ordinal = 0, argsOnly = true) ResourceKey<Level> dimension,
2626
@Local(ordinal = 0, argsOnly = true) MinecraftServer server) {
27-
((IChunkGenerator)instance).mfix$setStrongholdCachePath(levelStorageAccess.getDimensionPath(dimension), server.registryAccess());
27+
((IChunkGenerator)instance).mfix$setStrongholdCachePath(levelStorageAccess.getDimensionPath(dimension), server);
2828
original.call(instance);
2929
}
3030
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
@RequiresFeatureLevel(FeatureLevel.BETA)
2+
package org.embeddedt.modernfix.common.mixin.perf.compact_entity_models;
3+
4+
import org.embeddedt.modernfix.annotation.FeatureLevel;
5+
import org.embeddedt.modernfix.annotation.RequiresFeatureLevel;

src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_languages/ClientLanguageMixin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,4 @@ private static Map<String, String> modifyLanguageMap(Map<String, String> storage
5050
List<Resource> collected = Objects.requireNonNullElse(usedResources.get(), List.of());
5151
return DynamicLanguageMap.forVanillaData(storage, collected);
5252
}
53-
}
53+
}

0 commit comments

Comments
 (0)