Skip to content

Commit a29a4a8

Browse files
yynpsclaude
andcommitted
fix: SurfaceRuleProcessor crash - chunk unavailable during world generation
WorldGenRegion.getChunk() throws IllegalStateException when SurfaceRuleProcessor.process() -> CarvingContext.topMaterial() -> BiomeManager.getNoiseBiomeAtPosition() samples biome data from chunks outside the generation region boundary. This occurs during Aether structure placement when a block near the edge of the ±1 chunk bounds triggers a biome quart lookup that reaches into ±2 chunk range. Fix: wrap topMaterial() call in try-catch, fall back to unmodified block info when the chunk is unavailable. Structure blocks at affected positions use default Aether surface block instead. Fixes crash: java.lang.IllegalStateException: Requested chunk unavailable during world generation Crash UUID: 1ef27643-a82d-409d-a256-7bd08f8f06e9 Version bump: 1.5.11 -> 1.5.12 (uto26) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent af55d29 commit a29a4a8

File tree

2 files changed

+13
-3
lines changed

2 files changed

+13
-3
lines changed

gradle.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
org.gradle.jvmargs=-Xmx3G
1+
org.gradle.jvmargs=-Xmx2G -XX:+UseG1GC -XX:MaxGCPauseMillis=200
22
org.gradle.daemon=false
33
org.gradle.debug=false
44

@@ -9,7 +9,7 @@ neoForge.parchment.mappingsVersion=2024.06.23
99
mod_id=aether
1010
mod_group=com.aetherteam.aether
1111
mod_name=The Aether
12-
mod_version=1.5.11
12+
mod_version=1.5.12
1313
mod_license=Assets: All Rights Reserved; Code: LGPL-3.0
1414
mod_url=https://modrinth.com/mod/aether
1515
mod_update=https://github.com/The-Aether-Team/The-Aether/raw/1.21.1-develop/update.json

src/main/java/com/aetherteam/aether/world/processor/SurfaceRuleProcessor.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,17 @@ public StructureTemplate.StructureBlockInfo process(LevelReader level, BlockPos
5454
NoiseChunk noisechunk = ((ChunkAccessAccessor) chunkAccess).aether$getNoiseChunk();
5555
if (noisechunk != null) {
5656
CarvingContext carvingcontext = new CarvingContext(noiseBasedChunkGenerator, worldGenLevel.registryAccess(), chunkAccess.getHeightAccessorForGeneration(), noisechunk, serverChunkCache.randomState(), surfaceRule);
57-
Optional<BlockState> state = carvingcontext.topMaterial(worldGenLevel.getBiomeManager()::getNoiseBiomeAtPosition, chunkAccess, modifiedBlockInfo.pos(), false);
57+
// [uto26] Wrap topMaterial in try-catch: biome sampling via BiomeManager.getNoiseBiomeAtPosition
58+
// can reach into neighboring chunks outside the WorldGenRegion during structure generation,
59+
// causing IllegalStateException from WorldGenRegion.getChunk(). When this happens, fall back
60+
// to the unmodified block info (structure uses default Aether surface block).
61+
Optional<BlockState> state;
62+
try {
63+
state = carvingcontext.topMaterial(worldGenLevel.getBiomeManager()::getNoiseBiomeAtPosition, chunkAccess, modifiedBlockInfo.pos(), false);
64+
} catch (IllegalStateException e) {
65+
// Chunk unavailable during world generation — skip surface rule replacement
66+
return modifiedBlockInfo;
67+
}
5868
if (state.isPresent()) {
5969
if (modifiedBlockInfo.state().is(AetherTags.Blocks.AETHER_DIRT) && !modifiedBlockInfo.state().is(AetherBlocks.AETHER_DIRT.get()) && state.get().is(AetherTags.Blocks.AETHER_DIRT)) {
6070
return new StructureTemplate.StructureBlockInfo(modifiedBlockInfo.pos(), state.get(), null);

0 commit comments

Comments
 (0)