Stop noise carving from stalling new worlds

Noise carving ran inside the cave carving pass, which visits every
chunk within cave range of the chunk being generated, and it looked up
the biome and height of every column in all of them. Opening a studio
froze the server for about 35 seconds on its first chunk, even for
packs that don't use noise carving.

It now has its own mantle component that runs last and only for the
chunk being generated, and it does nothing when no biome in the pack
uses it. A fresh studio's spawn chunk is ready in about 1.4 seconds
again.

Model used: Claude Opus 5.5
This commit is contained in:
piexel
2026-10-19 14:22:07 +02:00
parent 8c39f9a01b
commit 8a1c7ac998
5 changed files with 71 additions and 2 deletions
@@ -24,6 +24,7 @@ import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.mantle.EngineMantle; import com.volmit.iris.engine.mantle.EngineMantle;
import com.volmit.iris.engine.mantle.MantleComponent; import com.volmit.iris.engine.mantle.MantleComponent;
import com.volmit.iris.engine.mantle.components.MantleCarvingComponent; import com.volmit.iris.engine.mantle.components.MantleCarvingComponent;
import com.volmit.iris.engine.mantle.components.MantleNoiseCarvingComponent;
import com.volmit.iris.engine.mantle.components.MantleFluidBodyComponent; import com.volmit.iris.engine.mantle.components.MantleFluidBodyComponent;
import com.volmit.iris.engine.mantle.components.MantleJigsawComponent; import com.volmit.iris.engine.mantle.components.MantleJigsawComponent;
import com.volmit.iris.engine.mantle.components.MantleObjectComponent; import com.volmit.iris.engine.mantle.components.MantleObjectComponent;
@@ -58,6 +59,7 @@ public class IrisEngineMantle implements EngineMantle {
this.mantle = new Mantle(new File(engine.getWorld().worldFolder(), "mantle"), engine.getTarget().getHeight()); this.mantle = new Mantle(new File(engine.getWorld().worldFolder(), "mantle"), engine.getTarget().getHeight());
components = new KMap<>(); components = new KMap<>();
registerComponent(new MantleCarvingComponent(this)); registerComponent(new MantleCarvingComponent(this));
registerComponent(new MantleNoiseCarvingComponent(this));
registerComponent(new MantleFluidBodyComponent(this)); registerComponent(new MantleFluidBodyComponent(this));
jigsaw = new MantleJigsawComponent(this); jigsaw = new MantleJigsawComponent(this);
registerComponent(jigsaw); registerComponent(jigsaw);
@@ -45,7 +45,6 @@ public class MantleCarvingComponent extends IrisMantleComponent {
IrisRegion region = getComplex().getRegionStream().get(xxx, zzz); IrisRegion region = getComplex().getRegionStream().get(xxx, zzz);
IrisBiome biome = getComplex().getTrueBiomeStream().get(xxx, zzz); IrisBiome biome = getComplex().getTrueBiomeStream().get(xxx, zzz);
carve(writer, rng, x, z, region, biome); carve(writer, rng, x, z, region, biome);
new NoiseTerrainCarver(getEngineMantle().getEngine()).carve(writer, x, z);
} }
@ChunkCoordinates @ChunkCoordinates
@@ -0,0 +1,66 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2022 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.engine.mantle.components;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.mantle.ComponentFlag;
import com.volmit.iris.engine.mantle.EngineMantle;
import com.volmit.iris.engine.mantle.IrisMantleComponent;
import com.volmit.iris.engine.mantle.MantleWriter;
import com.volmit.iris.util.context.ChunkContext;
import com.volmit.iris.util.mantle.flag.ReservedFlag;
/**
* Runs noise carving last and only for the chunk being generated: it never reaches into other chunks, and sampling
* every column's biome and height is too expensive to repeat across the reach of the other components.
*/
@ComponentFlag(ReservedFlag.NOISE_CARVED)
public class MantleNoiseCarvingComponent extends IrisMantleComponent {
private static final int RUNS_AFTER_OBJECTS = 2;
private final AtomicCache<Boolean> packUsesNoiseCarving = new AtomicCache<>();
public MantleNoiseCarvingComponent(EngineMantle engineMantle) {
super(engineMantle, ReservedFlag.NOISE_CARVED, RUNS_AFTER_OBJECTS);
}
@Override
public void generateLayer(MantleWriter writer, int x, int z, ChunkContext context) {
if (!packUsesNoiseCarving()) {
return;
}
new NoiseTerrainCarver(getEngineMantle().getEngine()).carve(writer, x, z);
}
@Override
public void hotload() {
super.hotload();
packUsesNoiseCarving.reset();
}
private boolean packUsesNoiseCarving() {
return packUsesNoiseCarving.aquire(() -> getDimension().getAllBiomes(this::getData).stream()
.anyMatch(biome -> biome.getNoiseCarving() != null));
}
@Override
protected int computeRadius() {
return 0;
}
}
@@ -41,6 +41,7 @@ public sealed interface MantleFlag permits CustomFlag, ReservedFlag {
MantleFlag DISCOVERED = ReservedFlag.DISCOVERED; MantleFlag DISCOVERED = ReservedFlag.DISCOVERED;
MantleFlag CUSTOM_ACTIVE = ReservedFlag.CUSTOM_ACTIVE; MantleFlag CUSTOM_ACTIVE = ReservedFlag.CUSTOM_ACTIVE;
MantleFlag SCRIPT = ReservedFlag.SCRIPT; MantleFlag SCRIPT = ReservedFlag.SCRIPT;
MantleFlag NOISE_CARVED = ReservedFlag.NOISE_CARVED;
int RESERVED_FLAGS = ReservedFlag.values().length; int RESERVED_FLAGS = ReservedFlag.values().length;
@@ -17,7 +17,8 @@ public enum ReservedFlag implements MantleFlag {
CUSTOM, CUSTOM,
DISCOVERED, DISCOVERED,
CUSTOM_ACTIVE, CUSTOM_ACTIVE,
SCRIPT; SCRIPT,
NOISE_CARVED;
@Override @Override
public boolean isCustom() { public boolean isCustom() {