Isolate scaled noise generators

- Isolate biome-child and carving-child noise generators.
- Isolate decorator variance generators.
- Share fresh scaled-generator construction.
- Test shared-generator isolation at each caller.
This commit is contained in:
Brian Fopiano authored and GitHub committed 2026-10-02 07:48:01 -04:00
commit 6b82ea99e2
11 files changed
+264 -45

No files matched your search

@@ -93,6 +93,7 @@ import java.util.Objects;
@EqualsAndHashCode(callSuper = false)
public class IrisBiome extends IrisRegistrant implements Rarity {
private static final int BIOME_GENERATOR_CACHE_SIZE = 8;
private static final int CHILDREN_SEED_SALT = 2137;
private final transient AtomicCache<KMap<String, IrisBiomeGeneratorLink>> genCache = new AtomicCache<>();
private final transient AtomicCache<KMap<String, Integer>> genCacheMax = new AtomicCache<>();
@@ -511,7 +512,15 @@ public class IrisBiome extends IrisRegistrant implements Rarity {
}
public CNG getChildrenGenerator(RNG random, int sig, double scale) {
return childrenCell.aquire(() -> getChildStyle().create(random.nextParallelRNG(sig * 2137), getLoader()).bake().scale(scale).bake());
return childrenCell.aquire(() -> createChildrenGenerator(random, sig, scale));
}
private CNG createChildrenGenerator(RNG random, int sig, double scale) {
return getChildStyle().createScaledGenerator(deriveChildStyleSeed(random, sig), getLoader(), scale);
}
static RNG deriveChildStyleSeed(RNG random, int signature) {
return random.nextParallelRNG(signature * CHILDREN_SEED_SALT);
}
public KList<NativeBlockState> generateLayers(IrisDimension dim, double wx, double wz, RNG random, int maxDepth, int height, IrisData rdata, IrisComplex complex) {
@@ -151,15 +151,19 @@ public class IrisDecorator {
public CNG getVarianceGenerator(RNG rng, IrisData data) {
CNG cached = varianceGenerator.getIfPresent();
return cached != null ? cached : buildVarianceGeneratorOnce(rng, data);
}
if (cached != null) {
return cached;
}
private CNG buildVarianceGeneratorOnce(RNG rng, IrisData data) {
return varianceGenerator.aquire(() -> createVarianceGenerator(rng, data));
}
return varianceGenerator.aquire(() ->
variance.create(
rng.nextParallelRNG(getBlockData(data).size()), data)
.scale(1D / variance.getZoom()));
private CNG createVarianceGenerator(RNG rng, IrisData data) {
return variance.createNoCache(deriveVarianceSeed(rng, data), data).scale(1D / variance.getZoom());
}
RNG deriveVarianceSeed(RNG rng, IrisData data) {
return rng.nextParallelRNG(getBlockData(data).size());
}
public KList<IrisBlockData> add(String b) {
@@ -102,6 +102,10 @@ public class IrisGeneratorStyle {
return createNoCache(rng, data, 1, 0, false, resolveEngine(data));
}
public CNG createScaledGenerator(RNG rng, IrisData data, double scaleFactor) {
return createNoCache(rng, data).bake().scale(scaleFactor).bake();
}
public CNG createForLayer(RNG rng, IrisData data, int octaveMultiplier) {
return createNoCache(rng, data, Math.clamp(octaveMultiplier, 1, 16), 0, false, resolveEngine(data));
}
@@ -11,18 +11,18 @@ public final class ContinentGenerator {
}
public static CNG create(IrisDimension dimension, RNG parentSeedSource, IrisData packData) {
return scaleByContinentZoom(createContinentalStyleGenerator(dimension, parentSeedSource, packData), dimension);
return createScaledContinentalStyleGenerator(dimension, deriveContinentSeed(parentSeedSource), packData);
}
private static CNG createContinentalStyleGenerator(IrisDimension dimension, RNG parentSeedSource, IrisData packData) {
return dimension.getContinentalStyle().createNoCache(deriveContinentSeed(parentSeedSource), packData);
private static CNG createScaledContinentalStyleGenerator(IrisDimension dimension, RNG continentSeed, IrisData packData) {
return dimension.getContinentalStyle().createScaledGenerator(continentSeed, packData, inverseContinentZoom(dimension));
}
static RNG deriveContinentSeed(RNG parentSeedSource) {
return parentSeedSource.nextParallelRNG(CONTINENT_SEED_SALT);
}
private static CNG scaleByContinentZoom(CNG generator, IrisDimension dimension) {
return generator.bake().scale(1D / dimension.getContinentZoom()).bake();
private static double inverseContinentZoom(IrisDimension dimension) {
return 1D / dimension.getContinentZoom();
}
}
@@ -31,6 +31,8 @@ import java.util.concurrent.ConcurrentHashMap;
@Description("Dimension-level cave biome override with absolute world Y bounds.")
@Data
public class IrisDimensionCarvingEntry {
private static final int CHILDREN_SEED_SALT = 2137;
private static final double MINIMUM_CHILD_SHRINK_FACTOR = 0.0001D;
private final transient AtomicCache<IrisBiome> realBiome = new AtomicCache<>(true);
private final transient Map<Long, CNG> childGenerators = new ConcurrentHashMap<>();
@@ -81,13 +83,27 @@ public class IrisDimensionCarvingEntry {
}
public CNG getChildrenGenerator(long seed, IrisData data) {
return childGenerators.computeIfAbsent(deriveChildrenGeneratorSeed(seed), key -> createChildrenGenerator(key, data));
}
private CNG createChildrenGenerator(long childrenGeneratorSeed, IrisData data) {
return getChildStyle().createScaledGenerator(deriveChildStyleSeed(childrenGeneratorSeed), data, childShrinkFactor());
}
long deriveChildrenGeneratorSeed(long worldSeed) {
return worldSeed ^ (hashOfId() << 32) ^ CHILDREN_SEED_SALT;
}
static RNG deriveChildStyleSeed(long childrenGeneratorSeed) {
return new RNG(childrenGeneratorSeed).nextParallelRNG(CHILDREN_SEED_SALT);
}
private double childShrinkFactor() {
return Math.max(MINIMUM_CHILD_SHRINK_FACTOR, getChildShrinkFactor());
}
private long hashOfId() {
String entryId = getId();
long idHash = entryId == null ? 0L : entryId.trim().hashCode();
long generatorSeed = seed ^ (idHash << 32) ^ 2137L;
return childGenerators.computeIfAbsent(generatorSeed, key -> {
double scale = Math.max(0.0001D, getChildShrinkFactor());
RNG random = new RNG(key);
return getChildStyle().create(random.nextParallelRNG(2137), data).bake().scale(scale).bake();
});
return entryId == null ? 0L : entryId.trim().hashCode();
}
}