Skip to content

Commit 2e8c003

Browse files
committed
Improve speed of searching for structures
1 parent 67e3a86 commit 2e8c003

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package org.embeddedt.modernfix.common.mixin.perf.faster_structure_location;
2+
3+
import net.minecraft.core.Holder;
4+
import net.minecraft.world.level.chunk.ChunkGenerator;
5+
import net.minecraft.world.level.levelgen.RandomState;
6+
import net.minecraft.world.level.levelgen.structure.Structure;
7+
import net.minecraft.world.level.levelgen.structure.placement.StructurePlacement;
8+
import org.spongepowered.asm.mixin.Mixin;
9+
import org.spongepowered.asm.mixin.gen.Invoker;
10+
11+
import java.util.List;
12+
13+
@Mixin(ChunkGenerator.class)
14+
public interface ChunkGeneratorAccessor {
15+
@Invoker("getPlacementsForStructure")
16+
List<StructurePlacement> invokeGetPlacementsForStructure(Holder<Structure> structure, RandomState random);
17+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package org.embeddedt.modernfix.common.mixin.perf.faster_structure_location;
2+
3+
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
4+
import net.minecraft.core.Registry;
5+
import net.minecraft.world.level.ChunkPos;
6+
import net.minecraft.world.level.chunk.ChunkGenerator;
7+
import net.minecraft.world.level.levelgen.RandomState;
8+
import net.minecraft.world.level.levelgen.structure.Structure;
9+
import net.minecraft.world.level.levelgen.structure.StructureCheck;
10+
import net.minecraft.world.level.levelgen.structure.StructureCheckResult;
11+
import org.spongepowered.asm.mixin.Final;
12+
import org.spongepowered.asm.mixin.Mixin;
13+
import org.spongepowered.asm.mixin.Shadow;
14+
import org.spongepowered.asm.mixin.injection.At;
15+
16+
@Mixin(StructureCheck.class)
17+
public class StructureCheckMixin {
18+
@Shadow @Final private ChunkGenerator chunkGenerator;
19+
@Shadow @Final private long seed;
20+
@Shadow @Final private Registry<Structure> structureConfigs;
21+
@Shadow @Final private RandomState randomState;
22+
23+
/**
24+
* @author embeddedt (inspired by 24w04a and Bytzo's comment on https://bugs.mojang.com/browse/MC-249136)
25+
* @reason Avoid running the canCreateStructure method (which can be expensive) if the structure placement already
26+
* forbids placing the structure in this chunk.
27+
*/
28+
@ModifyExpressionValue(method = "checkStart", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/levelgen/structure/StructureCheck;tryLoadFromStorage(Lnet/minecraft/world/level/ChunkPos;Lnet/minecraft/world/level/levelgen/structure/Structure;ZJ)Lnet/minecraft/world/level/levelgen/structure/StructureCheckResult;"))
29+
private StructureCheckResult mfix$checkForValidPosition(StructureCheckResult storageResult, ChunkPos chunkPos, Structure structure, boolean skipKnownStructures) {
30+
if (storageResult != null) {
31+
return storageResult;
32+
} else {
33+
// Check if any of the placements allow for this structure to be in this chunk
34+
var structureHolder = this.structureConfigs.getHolder(this.structureConfigs.getId(structure)).orElseThrow();
35+
for (var placement : ((ChunkGeneratorAccessor)this.chunkGenerator).invokeGetPlacementsForStructure(structureHolder, this.randomState)) {
36+
if (placement.isStructureChunk(this.chunkGenerator, this.randomState, this.seed, chunkPos.x, chunkPos.z)) {
37+
// Allowed - return null so regular check runs
38+
return null;
39+
}
40+
}
41+
// Not allowed - early exit by returning a non-null value
42+
return StructureCheckResult.START_NOT_PRESENT;
43+
}
44+
}
45+
}

0 commit comments

Comments
 (0)