--- a/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
+++ b/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
@@ -1,3 +1,4 @@
+// keep
 package net.minecraft.world.level.levelgen;
 
 import com.google.common.annotations.VisibleForTesting;
@@ -6,7 +7,9 @@
 import com.mojang.serialization.MapCodec;
 import com.mojang.serialization.codecs.RecordCodecBuilder;
 import java.text.DecimalFormat;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Objects;
 import java.util.OptionalInt;
 import java.util.Set;
 import java.util.concurrent.CompletableFuture;
@@ -48,13 +51,14 @@
 import org.apache.commons.lang3.mutable.MutableObject;
 
 public final class NoiseBasedChunkGenerator extends ChunkGenerator {
-    public static final MapCodec<NoiseBasedChunkGenerator> CODEC = RecordCodecBuilder.mapCodec(
-        instance -> instance.group(
-                    BiomeSource.CODEC.fieldOf("biome_source").forGetter(generator -> generator.biomeSource),
-                    NoiseGeneratorSettings.CODEC.fieldOf("settings").forGetter(generator -> generator.settings)
-                )
-                .apply(instance, instance.stable(NoiseBasedChunkGenerator::new))
-    );
+
+    public static final MapCodec<NoiseBasedChunkGenerator> CODEC = RecordCodecBuilder.mapCodec((instance) -> {
+        return instance.group(BiomeSource.CODEC.fieldOf("biome_source").forGetter((chunkgeneratorabstract) -> {
+            return chunkgeneratorabstract.biomeSource;
+        }), NoiseGeneratorSettings.CODEC.fieldOf("settings").forGetter((chunkgeneratorabstract) -> {
+            return chunkgeneratorabstract.settings;
+        })).apply(instance, instance.stable(NoiseBasedChunkGenerator::new));
+    });
     private static final BlockState AIR = Blocks.AIR.defaultBlockState();
     public final Holder<NoiseGeneratorSettings> settings;
     private final Supplier<Aquifer.FluidPicker> globalFluidPicker;
@@ -62,42 +66,46 @@
     public NoiseBasedChunkGenerator(BiomeSource biomeSource, Holder<NoiseGeneratorSettings> settings) {
         super(biomeSource);
         this.settings = settings;
-        this.globalFluidPicker = Suppliers.memoize(() -> createFluidPicker(settings.value()));
+        this.globalFluidPicker = Suppliers.memoize(() -> {
+            return NoiseBasedChunkGenerator.createFluidPicker((NoiseGeneratorSettings) settings.value());
+        });
     }
 
     private static Aquifer.FluidPicker createFluidPicker(NoiseGeneratorSettings settings) {
-        Aquifer.FluidStatus fluidStatus = new Aquifer.FluidStatus(-54, Blocks.LAVA.defaultBlockState());
+        Aquifer.FluidStatus aquifer_b = new Aquifer.FluidStatus(-54, Blocks.LAVA.defaultBlockState());
         int i = settings.seaLevel();
-        Aquifer.FluidStatus fluidStatus2 = new Aquifer.FluidStatus(i, settings.defaultFluid());
-        Aquifer.FluidStatus fluidStatus3 = new Aquifer.FluidStatus(DimensionType.MIN_Y * 2, Blocks.AIR.defaultBlockState());
-        return (x, y, z) -> y < Math.min(-54, i) ? fluidStatus : fluidStatus2;
+        Aquifer.FluidStatus aquifer_b1 = new Aquifer.FluidStatus(i, settings.defaultFluid());
+        Aquifer.FluidStatus aquifer_b2 = new Aquifer.FluidStatus(DimensionType.MIN_Y * 2, Blocks.AIR.defaultBlockState());
+
+        return (j, k, l) -> {
+            return k < Math.min(-54, i) ? aquifer_b : aquifer_b1;
+        };
     }
 
     @Override
-    public CompletableFuture<ChunkAccess> createBiomes(
-        Executor executor, RandomState noiseConfig, Blender blender, StructureManager structureAccessor, ChunkAccess chunk
-    ) {
+    public CompletableFuture<ChunkAccess> createBiomes(Executor executor, RandomState noiseConfig, Blender blender, StructureManager structureAccessor, ChunkAccess chunk) {
         return CompletableFuture.supplyAsync(Util.wrapThreadWithTaskName("init_biomes", () -> {
             this.doCreateBiomes(blender, noiseConfig, structureAccessor, chunk);
             return chunk;
-        }), Util.backgroundExecutor());
+        }), executor); // Paper - run with supplied executor
     }
 
     private void doCreateBiomes(Blender blender, RandomState noiseConfig, StructureManager structureAccessor, ChunkAccess chunk) {
-        NoiseChunk noiseChunk = chunk.getOrCreateNoiseChunk(chunkx -> this.createNoiseChunk(chunkx, structureAccessor, blender, noiseConfig));
-        BiomeResolver biomeResolver = BelowZeroRetrogen.getBiomeResolver(blender.getBiomeResolver(this.biomeSource), chunk);
-        chunk.fillBiomesFromNoise(biomeResolver, noiseChunk.cachedClimateSampler(noiseConfig.router(), this.settings.value().spawnTarget()));
+        NoiseChunk noisechunk = chunk.getOrCreateNoiseChunk((ichunkaccess1) -> {
+            return this.createNoiseChunk(ichunkaccess1, structureAccessor, blender, noiseConfig);
+        });
+        BiomeResolver biomeresolver = BelowZeroRetrogen.getBiomeResolver(blender.getBiomeResolver(this.biomeSource), chunk);
+
+        chunk.fillBiomesFromNoise(biomeresolver, noisechunk.cachedClimateSampler(noiseConfig.router(), ((NoiseGeneratorSettings) this.settings.value()).spawnTarget()));
     }
 
     private NoiseChunk createNoiseChunk(ChunkAccess chunk, StructureManager world, Blender blender, RandomState noiseConfig) {
-        return NoiseChunk.forChunk(
-            chunk, noiseConfig, Beardifier.forStructuresInChunk(world, chunk.getPos()), this.settings.value(), this.globalFluidPicker.get(), blender
-        );
+        return NoiseChunk.forChunk(chunk, noiseConfig, Beardifier.forStructuresInChunk(world, chunk.getPos()), (NoiseGeneratorSettings) this.settings.value(), (Aquifer.FluidPicker) this.globalFluidPicker.get(), blender);
     }
 
     @Override
     protected MapCodec<? extends ChunkGenerator> codec() {
-        return CODEC;
+        return NoiseBasedChunkGenerator.CODEC;
     }
 
     public Holder<NoiseGeneratorSettings> generatorSettings() {
@@ -110,115 +118,88 @@
 
     @Override
     public int getBaseHeight(int x, int z, Heightmap.Types heightmap, LevelHeightAccessor world, RandomState noiseConfig) {
-        return this.iterateNoiseColumn(world, noiseConfig, x, z, null, heightmap.isOpaque()).orElse(world.getMinBuildHeight());
+        return this.iterateNoiseColumn(world, noiseConfig, x, z, (MutableObject) null, heightmap.isOpaque()).orElse(world.getMinBuildHeight());
     }
 
     @Override
     public NoiseColumn getBaseColumn(int x, int z, LevelHeightAccessor world, RandomState noiseConfig) {
-        MutableObject<NoiseColumn> mutableObject = new MutableObject<>();
-        this.iterateNoiseColumn(world, noiseConfig, x, z, mutableObject, null);
-        return mutableObject.getValue();
+        MutableObject<NoiseColumn> mutableobject = new MutableObject();
+
+        this.iterateNoiseColumn(world, noiseConfig, x, z, mutableobject, (Predicate) null);
+        return (NoiseColumn) mutableobject.getValue();
     }
 
     @Override
     public void addDebugScreenInfo(List<String> text, RandomState noiseConfig, BlockPos pos) {
-        DecimalFormat decimalFormat = new DecimalFormat("0.000");
-        NoiseRouter noiseRouter = noiseConfig.router();
-        DensityFunction.SinglePointContext singlePointContext = new DensityFunction.SinglePointContext(pos.getX(), pos.getY(), pos.getZ());
-        double d = noiseRouter.ridges().compute(singlePointContext);
-        text.add(
-            "NoiseRouter T: "
-                + decimalFormat.format(noiseRouter.temperature().compute(singlePointContext))
-                + " V: "
-                + decimalFormat.format(noiseRouter.vegetation().compute(singlePointContext))
-                + " C: "
-                + decimalFormat.format(noiseRouter.continents().compute(singlePointContext))
-                + " E: "
-                + decimalFormat.format(noiseRouter.erosion().compute(singlePointContext))
-                + " D: "
-                + decimalFormat.format(noiseRouter.depth().compute(singlePointContext))
-                + " W: "
-                + decimalFormat.format(d)
-                + " PV: "
-                + decimalFormat.format((double)NoiseRouterData.peaksAndValleys((float)d))
-                + " AS: "
-                + decimalFormat.format(noiseRouter.initialDensityWithoutJaggedness().compute(singlePointContext))
-                + " N: "
-                + decimalFormat.format(noiseRouter.finalDensity().compute(singlePointContext))
-        );
+        DecimalFormat decimalformat = new DecimalFormat("0.000");
+        NoiseRouter noiserouter = noiseConfig.router();
+        DensityFunction.SinglePointContext densityfunction_e = new DensityFunction.SinglePointContext(pos.getX(), pos.getY(), pos.getZ());
+        double d0 = noiserouter.ridges().compute(densityfunction_e);
+        String s = decimalformat.format(noiserouter.temperature().compute(densityfunction_e));
+
+        text.add("NoiseRouter T: " + s + " V: " + decimalformat.format(noiserouter.vegetation().compute(densityfunction_e)) + " C: " + decimalformat.format(noiserouter.continents().compute(densityfunction_e)) + " E: " + decimalformat.format(noiserouter.erosion().compute(densityfunction_e)) + " D: " + decimalformat.format(noiserouter.depth().compute(densityfunction_e)) + " W: " + decimalformat.format(d0) + " PV: " + decimalformat.format((double) NoiseRouterData.peaksAndValleys((float) d0)) + " AS: " + decimalformat.format(noiserouter.initialDensityWithoutJaggedness().compute(densityfunction_e)) + " N: " + decimalformat.format(noiserouter.finalDensity().compute(densityfunction_e)));
     }
 
-    private OptionalInt iterateNoiseColumn(
-        LevelHeightAccessor world,
-        RandomState noiseConfig,
-        int x,
-        int z,
-        @Nullable MutableObject<NoiseColumn> columnSample,
-        @Nullable Predicate<BlockState> stopPredicate
-    ) {
-        NoiseSettings noiseSettings = this.settings.value().noiseSettings().clampToHeightAccessor(world);
-        int i = noiseSettings.getCellHeight();
-        int j = noiseSettings.minY();
-        int k = Mth.floorDiv(j, i);
-        int l = Mth.floorDiv(noiseSettings.height(), i);
-        if (l <= 0) {
+    private OptionalInt iterateNoiseColumn(LevelHeightAccessor world, RandomState noiseConfig, int x, int z, @Nullable MutableObject<NoiseColumn> columnSample, @Nullable Predicate<BlockState> stopPredicate) {
+        NoiseSettings noisesettings = ((NoiseGeneratorSettings) this.settings.value()).noiseSettings().clampToHeightAccessor(world);
+        int k = noisesettings.getCellHeight();
+        int l = noisesettings.minY();
+        int i1 = Mth.floorDiv(l, k);
+        int j1 = Mth.floorDiv(noisesettings.height(), k);
+
+        if (j1 <= 0) {
             return OptionalInt.empty();
         } else {
-            BlockState[] blockStates;
+            BlockState[] aiblockdata;
+
             if (columnSample == null) {
-                blockStates = null;
+                aiblockdata = null;
             } else {
-                blockStates = new BlockState[noiseSettings.height()];
-                columnSample.setValue(new NoiseColumn(j, blockStates));
+                aiblockdata = new BlockState[noisesettings.height()];
+                columnSample.setValue(new NoiseColumn(l, aiblockdata));
             }
 
-            int m = noiseSettings.getCellWidth();
-            int n = Math.floorDiv(x, m);
-            int o = Math.floorDiv(z, m);
-            int p = Math.floorMod(x, m);
-            int q = Math.floorMod(z, m);
-            int r = n * m;
-            int s = o * m;
-            double d = (double)p / (double)m;
-            double e = (double)q / (double)m;
-            NoiseChunk noiseChunk = new NoiseChunk(
-                1,
-                noiseConfig,
-                r,
-                s,
-                noiseSettings,
-                DensityFunctions.BeardifierMarker.INSTANCE,
-                this.settings.value(),
-                this.globalFluidPicker.get(),
-                Blender.empty()
-            );
-            noiseChunk.initializeForFirstCellX();
-            noiseChunk.advanceCellX(0);
+            int k1 = noisesettings.getCellWidth();
+            int l1 = Math.floorDiv(x, k1);
+            int i2 = Math.floorDiv(z, k1);
+            int j2 = Math.floorMod(x, k1);
+            int k2 = Math.floorMod(z, k1);
+            int l2 = l1 * k1;
+            int i3 = i2 * k1;
+            double d0 = (double) j2 / (double) k1;
+            double d1 = (double) k2 / (double) k1;
+            NoiseChunk noisechunk = new NoiseChunk(1, noiseConfig, l2, i3, noisesettings, DensityFunctions.BeardifierMarker.INSTANCE, (NoiseGeneratorSettings) this.settings.value(), (Aquifer.FluidPicker) this.globalFluidPicker.get(), Blender.empty());
 
-            for (int t = l - 1; t >= 0; t--) {
-                noiseChunk.selectCellYZ(t, 0);
+            noisechunk.initializeForFirstCellX();
+            noisechunk.advanceCellX(0);
 
-                for (int u = i - 1; u >= 0; u--) {
-                    int v = (k + t) * i + u;
-                    double f = (double)u / (double)i;
-                    noiseChunk.updateForY(v, f);
-                    noiseChunk.updateForX(x, d);
-                    noiseChunk.updateForZ(z, e);
-                    BlockState blockState = noiseChunk.getInterpolatedState();
-                    BlockState blockState2 = blockState == null ? this.settings.value().defaultBlock() : blockState;
-                    if (blockStates != null) {
-                        int w = t * i + u;
-                        blockStates[w] = blockState2;
+            for (int j3 = j1 - 1; j3 >= 0; --j3) {
+                noisechunk.selectCellYZ(j3, 0);
+
+                for (int k3 = k - 1; k3 >= 0; --k3) {
+                    int l3 = (i1 + j3) * k + k3;
+                    double d2 = (double) k3 / (double) k;
+
+                    noisechunk.updateForY(l3, d2);
+                    noisechunk.updateForX(x, d0);
+                    noisechunk.updateForZ(z, d1);
+                    BlockState iblockdata = noisechunk.getInterpolatedState();
+                    BlockState iblockdata1 = iblockdata == null ? ((NoiseGeneratorSettings) this.settings.value()).defaultBlock() : iblockdata;
+
+                    if (aiblockdata != null) {
+                        int i4 = j3 * k + k3;
+
+                        aiblockdata[i4] = iblockdata1;
                     }
 
-                    if (stopPredicate != null && stopPredicate.test(blockState2)) {
-                        noiseChunk.stopInterpolation();
-                        return OptionalInt.of(v + 1);
+                    if (stopPredicate != null && stopPredicate.test(iblockdata1)) {
+                        noisechunk.stopInterpolation();
+                        return OptionalInt.of(l3 + 1);
                     }
                 }
             }
 
-            noiseChunk.stopInterpolation();
+            noisechunk.stopInterpolation();
             return OptionalInt.empty();
         }
     }
@@ -226,191 +207,167 @@
     @Override
     public void buildSurface(WorldGenRegion region, StructureManager structures, RandomState noiseConfig, ChunkAccess chunk) {
         if (!SharedConstants.debugVoidTerrain(chunk.getPos())) {
-            WorldGenerationContext worldGenerationContext = new WorldGenerationContext(this, region);
-            this.buildSurface(
-                chunk,
-                worldGenerationContext,
-                noiseConfig,
-                structures,
-                region.getBiomeManager(),
-                region.registryAccess().registryOrThrow(Registries.BIOME),
-                Blender.of(region)
-            );
+            WorldGenerationContext worldgenerationcontext = new WorldGenerationContext(this, region, region.getMinecraftWorld()); // Paper - Flat bedrock generator settings
+
+            this.buildSurface(chunk, worldgenerationcontext, noiseConfig, structures, region.getBiomeManager(), region.registryAccess().registryOrThrow(Registries.BIOME), Blender.of(region));
         }
     }
 
     @VisibleForTesting
-    public void buildSurface(
-        ChunkAccess chunk,
-        WorldGenerationContext heightContext,
-        RandomState noiseConfig,
-        StructureManager structureAccessor,
-        BiomeManager biomeAccess,
-        Registry<Biome> biomeRegistry,
-        Blender blender
-    ) {
-        NoiseChunk noiseChunk = chunk.getOrCreateNoiseChunk(chunkx -> this.createNoiseChunk(chunkx, structureAccessor, blender, noiseConfig));
-        NoiseGeneratorSettings noiseGeneratorSettings = this.settings.value();
-        noiseConfig.surfaceSystem()
-            .buildSurface(
-                noiseConfig,
-                biomeAccess,
-                biomeRegistry,
-                noiseGeneratorSettings.useLegacyRandomSource(),
-                heightContext,
-                chunk,
-                noiseChunk,
-                noiseGeneratorSettings.surfaceRule()
-            );
+    public void buildSurface(ChunkAccess chunk, WorldGenerationContext heightContext, RandomState noiseConfig, StructureManager structureAccessor, BiomeManager biomeAccess, Registry<Biome> biomeRegistry, Blender blender) {
+        NoiseChunk noisechunk = chunk.getOrCreateNoiseChunk((ichunkaccess1) -> {
+            return this.createNoiseChunk(ichunkaccess1, structureAccessor, blender, noiseConfig);
+        });
+        NoiseGeneratorSettings generatorsettingbase = (NoiseGeneratorSettings) this.settings.value();
+
+        noiseConfig.surfaceSystem().buildSurface(noiseConfig, biomeAccess, biomeRegistry, generatorsettingbase.useLegacyRandomSource(), heightContext, chunk, noisechunk, generatorsettingbase.surfaceRule());
     }
 
     @Override
-    public void applyCarvers(
-        WorldGenRegion chunkRegion,
-        long seed,
-        RandomState noiseConfig,
-        BiomeManager biomeAccess,
-        StructureManager structureAccessor,
-        ChunkAccess chunk,
-        GenerationStep.Carving carverStep
-    ) {
-        BiomeManager biomeManager = biomeAccess.withDifferentSource(
-            (biomeX, biomeY, biomeZ) -> this.biomeSource.getNoiseBiome(biomeX, biomeY, biomeZ, noiseConfig.sampler())
-        );
-        WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(RandomSupport.generateUniqueSeed()));
-        int i = 8;
-        ChunkPos chunkPos = chunk.getPos();
-        NoiseChunk noiseChunk = chunk.getOrCreateNoiseChunk(chunkx -> this.createNoiseChunk(chunkx, structureAccessor, Blender.of(chunkRegion), noiseConfig));
-        Aquifer aquifer = noiseChunk.aquifer();
-        CarvingContext carvingContext = new CarvingContext(
-            this, chunkRegion.registryAccess(), chunk.getHeightAccessorForGeneration(), noiseChunk, noiseConfig, this.settings.value().surfaceRule()
-        );
-        CarvingMask carvingMask = ((ProtoChunk)chunk).getOrCreateCarvingMask(carverStep);
+    public void applyCarvers(WorldGenRegion chunkRegion, long seed, RandomState noiseConfig, BiomeManager biomeAccess, StructureManager structureAccessor, ChunkAccess chunk, GenerationStep.Carving carverStep) {
+        BiomeManager biomemanager1 = biomeAccess.withDifferentSource((j, k, l) -> {
+            return this.biomeSource.getNoiseBiome(j, k, l, noiseConfig.sampler());
+        });
+        WorldgenRandom seededrandom = new WorldgenRandom(new LegacyRandomSource(RandomSupport.generateUniqueSeed()));
+        boolean flag = true;
+        ChunkPos chunkcoordintpair = chunk.getPos();
+        NoiseChunk noisechunk = chunk.getOrCreateNoiseChunk((ichunkaccess1) -> {
+            return this.createNoiseChunk(ichunkaccess1, structureAccessor, Blender.of(chunkRegion), noiseConfig);
+        });
+        Aquifer aquifer = noisechunk.aquifer();
+        CarvingContext carvingcontext = new CarvingContext(this, chunkRegion.registryAccess(), chunk.getHeightAccessorForGeneration(), noisechunk, noiseConfig, ((NoiseGeneratorSettings) this.settings.value()).surfaceRule(), chunkRegion.getMinecraftWorld()); // Paper - Flat bedrock generator settings
+        CarvingMask carvingmask = ((ProtoChunk) chunk).getOrCreateCarvingMask(carverStep);
 
-        for (int j = -8; j <= 8; j++) {
-            for (int k = -8; k <= 8; k++) {
-                ChunkPos chunkPos2 = new ChunkPos(chunkPos.x + j, chunkPos.z + k);
-                ChunkAccess chunkAccess = chunkRegion.getChunk(chunkPos2.x, chunkPos2.z);
-                BiomeGenerationSettings biomeGenerationSettings = chunkAccess.carverBiome(
-                    () -> this.getBiomeGenerationSettings(
-                            this.biomeSource
-                                .getNoiseBiome(
-                                    QuartPos.fromBlock(chunkPos2.getMinBlockX()), 0, QuartPos.fromBlock(chunkPos2.getMinBlockZ()), noiseConfig.sampler()
-                                )
-                        )
-                );
-                Iterable<Holder<ConfiguredWorldCarver<?>>> iterable = biomeGenerationSettings.getCarvers(carverStep);
+        for (int j = -8; j <= 8; ++j) {
+            for (int k = -8; k <= 8; ++k) {
+                ChunkPos chunkcoordintpair1 = new ChunkPos(chunkcoordintpair.x + j, chunkcoordintpair.z + k);
+                ChunkAccess ichunkaccess1 = chunkRegion.getChunk(chunkcoordintpair1.x, chunkcoordintpair1.z);
+                BiomeGenerationSettings biomesettingsgeneration = ichunkaccess1.carverBiome(() -> {
+                    return this.getBiomeGenerationSettings(this.biomeSource.getNoiseBiome(QuartPos.fromBlock(chunkcoordintpair1.getMinBlockX()), 0, QuartPos.fromBlock(chunkcoordintpair1.getMinBlockZ()), noiseConfig.sampler()));
+                });
+                Iterable<Holder<ConfiguredWorldCarver<?>>> iterable = biomesettingsgeneration.getCarvers(carverStep);
                 int l = 0;
 
-                for (Holder<ConfiguredWorldCarver<?>> holder : iterable) {
-                    ConfiguredWorldCarver<?> configuredWorldCarver = holder.value();
-                    worldgenRandom.setLargeFeatureSeed(seed + (long)l, chunkPos2.x, chunkPos2.z);
-                    if (configuredWorldCarver.isStartChunk(worldgenRandom)) {
-                        configuredWorldCarver.carve(carvingContext, chunk, biomeManager::getBiome, worldgenRandom, aquifer, chunkPos2, carvingMask);
-                    }
+                for (Iterator iterator = iterable.iterator(); iterator.hasNext(); ++l) {
+                    Holder<ConfiguredWorldCarver<?>> holder = (Holder) iterator.next();
+                    ConfiguredWorldCarver<?> worldgencarverwrapper = (ConfiguredWorldCarver) holder.value();
 
-                    l++;
+                    seededrandom.setLargeFeatureSeed(seed + (long) l, chunkcoordintpair1.x, chunkcoordintpair1.z);
+                    if (worldgencarverwrapper.isStartChunk(seededrandom)) {
+                        Objects.requireNonNull(biomemanager1);
+                        worldgencarverwrapper.carve(carvingcontext, chunk, biomemanager1::getBiome, seededrandom, aquifer, chunkcoordintpair1, carvingmask);
+                    }
                 }
             }
         }
+
     }
 
     @Override
-    public CompletableFuture<ChunkAccess> fillFromNoise(
-        Executor executor, Blender blender, RandomState noiseConfig, StructureManager structureAccessor, ChunkAccess chunk
-    ) {
-        NoiseSettings noiseSettings = this.settings.value().noiseSettings().clampToHeightAccessor(chunk.getHeightAccessorForGeneration());
-        int i = noiseSettings.minY();
-        int j = Mth.floorDiv(i, noiseSettings.getCellHeight());
-        int k = Mth.floorDiv(noiseSettings.height(), noiseSettings.getCellHeight());
+    public CompletableFuture<ChunkAccess> fillFromNoise(Executor executor, Blender blender, RandomState noiseConfig, StructureManager structureAccessor, ChunkAccess chunk) {
+        NoiseSettings noisesettings = ((NoiseGeneratorSettings) this.settings.value()).noiseSettings().clampToHeightAccessor(chunk.getHeightAccessorForGeneration());
+        int i = noisesettings.minY();
+        int j = Mth.floorDiv(i, noisesettings.getCellHeight());
+        int k = Mth.floorDiv(noisesettings.height(), noisesettings.getCellHeight());
+
         if (k <= 0) {
             return CompletableFuture.completedFuture(chunk);
         } else {
-            int l = chunk.getSectionIndex(k * noiseSettings.getCellHeight() - 1 + i);
-            int m = chunk.getSectionIndex(i);
+            int l = chunk.getSectionIndex(k * noisesettings.getCellHeight() - 1 + i);
+            int i1 = chunk.getSectionIndex(i);
             Set<LevelChunkSection> set = Sets.newHashSet();
 
-            for (int n = l; n >= m; n--) {
-                LevelChunkSection levelChunkSection = chunk.getSection(n);
-                levelChunkSection.acquire();
-                set.add(levelChunkSection);
+            for (int j1 = l; j1 >= i1; --j1) {
+                LevelChunkSection chunksection = chunk.getSection(j1);
+
+                chunksection.acquire();
+                set.add(chunksection);
             }
 
-            return CompletableFuture.supplyAsync(
-                    Util.wrapThreadWithTaskName("wgen_fill_noise", () -> this.doFill(blender, structureAccessor, noiseConfig, chunk, j, k)),
-                    Util.backgroundExecutor()
-                )
-                .whenCompleteAsync((chunkAccess, throwable) -> {
-                    for (LevelChunkSection levelChunkSectionx : set) {
-                        levelChunkSectionx.release();
-                    }
-                }, executor);
+            return CompletableFuture.supplyAsync(Util.wrapThreadWithTaskName("wgen_fill_noise", () -> {
+                return this.doFill(blender, structureAccessor, noiseConfig, chunk, j, k);
+            }), executor).whenCompleteAsync((ichunkaccess1, throwable) -> { // Paper - run with supplied executor
+                Iterator iterator = set.iterator();
+
+                while (iterator.hasNext()) {
+                    LevelChunkSection chunksection1 = (LevelChunkSection) iterator.next();
+
+                    chunksection1.release();
+                }
+
+            }, executor);
         }
     }
 
-    private ChunkAccess doFill(
-        Blender blender, StructureManager structureAccessor, RandomState noiseConfig, ChunkAccess chunk, int minimumCellY, int cellHeight
-    ) {
-        NoiseChunk noiseChunk = chunk.getOrCreateNoiseChunk(chunkx -> this.createNoiseChunk(chunkx, structureAccessor, blender, noiseConfig));
+    private ChunkAccess doFill(Blender blender, StructureManager structureAccessor, RandomState noiseConfig, ChunkAccess chunk, int minimumCellY, int cellHeight) {
+        NoiseChunk noisechunk = chunk.getOrCreateNoiseChunk((ichunkaccess1) -> {
+            return this.createNoiseChunk(ichunkaccess1, structureAccessor, blender, noiseConfig);
+        });
         Heightmap heightmap = chunk.getOrCreateHeightmapUnprimed(Heightmap.Types.OCEAN_FLOOR_WG);
-        Heightmap heightmap2 = chunk.getOrCreateHeightmapUnprimed(Heightmap.Types.WORLD_SURFACE_WG);
-        ChunkPos chunkPos = chunk.getPos();
-        int i = chunkPos.getMinBlockX();
-        int j = chunkPos.getMinBlockZ();
-        Aquifer aquifer = noiseChunk.aquifer();
-        noiseChunk.initializeForFirstCellX();
-        BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
-        int k = noiseChunk.cellWidth();
-        int l = noiseChunk.cellHeight();
-        int m = 16 / k;
-        int n = 16 / k;
+        Heightmap heightmap1 = chunk.getOrCreateHeightmapUnprimed(Heightmap.Types.WORLD_SURFACE_WG);
+        ChunkPos chunkcoordintpair = chunk.getPos();
+        int k = chunkcoordintpair.getMinBlockX();
+        int l = chunkcoordintpair.getMinBlockZ();
+        Aquifer aquifer = noisechunk.aquifer();
 
-        for (int o = 0; o < m; o++) {
-            noiseChunk.advanceCellX(o);
+        noisechunk.initializeForFirstCellX();
+        BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos();
+        int i1 = noisechunk.cellWidth();
+        int j1 = noisechunk.cellHeight();
+        int k1 = 16 / i1;
+        int l1 = 16 / i1;
 
-            for (int p = 0; p < n; p++) {
-                int q = chunk.getSectionsCount() - 1;
-                LevelChunkSection levelChunkSection = chunk.getSection(q);
+        for (int i2 = 0; i2 < k1; ++i2) {
+            noisechunk.advanceCellX(i2);
 
-                for (int r = cellHeight - 1; r >= 0; r--) {
-                    noiseChunk.selectCellYZ(r, p);
+            for (int j2 = 0; j2 < l1; ++j2) {
+                int k2 = chunk.getSectionsCount() - 1;
+                LevelChunkSection chunksection = chunk.getSection(k2);
 
-                    for (int s = l - 1; s >= 0; s--) {
-                        int t = (minimumCellY + r) * l + s;
-                        int u = t & 15;
-                        int v = chunk.getSectionIndex(t);
-                        if (q != v) {
-                            q = v;
-                            levelChunkSection = chunk.getSection(v);
+                for (int l2 = cellHeight - 1; l2 >= 0; --l2) {
+                    noisechunk.selectCellYZ(l2, j2);
+
+                    for (int i3 = j1 - 1; i3 >= 0; --i3) {
+                        int j3 = (minimumCellY + l2) * j1 + i3;
+                        int k3 = j3 & 15;
+                        int l3 = chunk.getSectionIndex(j3);
+
+                        if (k2 != l3) {
+                            k2 = l3;
+                            chunksection = chunk.getSection(l3);
                         }
 
-                        double d = (double)s / (double)l;
-                        noiseChunk.updateForY(t, d);
+                        double d0 = (double) i3 / (double) j1;
 
-                        for (int w = 0; w < k; w++) {
-                            int x = i + o * k + w;
-                            int y = x & 15;
-                            double e = (double)w / (double)k;
-                            noiseChunk.updateForX(x, e);
+                        noisechunk.updateForY(j3, d0);
 
-                            for (int z = 0; z < k; z++) {
-                                int aa = j + p * k + z;
-                                int ab = aa & 15;
-                                double f = (double)z / (double)k;
-                                noiseChunk.updateForZ(aa, f);
-                                BlockState blockState = noiseChunk.getInterpolatedState();
-                                if (blockState == null) {
-                                    blockState = this.settings.value().defaultBlock();
+                        for (int i4 = 0; i4 < i1; ++i4) {
+                            int j4 = k + i2 * i1 + i4;
+                            int k4 = j4 & 15;
+                            double d1 = (double) i4 / (double) i1;
+
+                            noisechunk.updateForX(j4, d1);
+
+                            for (int l4 = 0; l4 < i1; ++l4) {
+                                int i5 = l + j2 * i1 + l4;
+                                int j5 = i5 & 15;
+                                double d2 = (double) l4 / (double) i1;
+
+                                noisechunk.updateForZ(i5, d2);
+                                BlockState iblockdata = noisechunk.getInterpolatedState();
+
+                                if (iblockdata == null) {
+                                    iblockdata = ((NoiseGeneratorSettings) this.settings.value()).defaultBlock();
                                 }
 
-                                blockState = this.debugPreliminarySurfaceLevel(noiseChunk, x, t, aa, blockState);
-                                if (blockState != AIR && !SharedConstants.debugVoidTerrain(chunk.getPos())) {
-                                    levelChunkSection.setBlockState(y, u, ab, blockState, false);
-                                    heightmap.update(y, t, ab, blockState);
-                                    heightmap2.update(y, t, ab, blockState);
-                                    if (aquifer.shouldScheduleFluidUpdate() && !blockState.getFluidState().isEmpty()) {
-                                        mutableBlockPos.set(x, t, aa);
-                                        chunk.markPosForPostprocessing(mutableBlockPos);
+                                iblockdata = this.debugPreliminarySurfaceLevel(noisechunk, j4, j3, i5, iblockdata);
+                                if (iblockdata != NoiseBasedChunkGenerator.AIR && !SharedConstants.debugVoidTerrain(chunk.getPos())) {
+                                    chunksection.setBlockState(k4, k3, j5, iblockdata, false);
+                                    heightmap.update(k4, j3, j5, iblockdata);
+                                    heightmap1.update(k4, j3, j5, iblockdata);
+                                    if (aquifer.shouldScheduleFluidUpdate() && !iblockdata.getFluidState().isEmpty()) {
+                                        blockposition_mutableblockposition.set(j4, j3, i5);
+                                        chunk.markPosForPostprocessing(blockposition_mutableblockposition);
                                     }
                                 }
                             }
@@ -419,10 +376,10 @@
                 }
             }
 
-            noiseChunk.swapSlices();
+            noisechunk.swapSlices();
         }
 
-        noiseChunk.stopInterpolation();
+        noisechunk.stopInterpolation();
         return chunk;
     }
 
@@ -432,27 +389,28 @@
 
     @Override
     public int getGenDepth() {
-        return this.settings.value().noiseSettings().height();
+        return ((NoiseGeneratorSettings) this.settings.value()).noiseSettings().height();
     }
 
     @Override
     public int getSeaLevel() {
-        return this.settings.value().seaLevel();
+        return ((NoiseGeneratorSettings) this.settings.value()).seaLevel();
     }
 
     @Override
     public int getMinY() {
-        return this.settings.value().noiseSettings().minY();
+        return ((NoiseGeneratorSettings) this.settings.value()).noiseSettings().minY();
     }
 
     @Override
     public void spawnOriginalMobs(WorldGenRegion region) {
-        if (!this.settings.value().disableMobGeneration()) {
-            ChunkPos chunkPos = region.getCenter();
-            Holder<Biome> holder = region.getBiome(chunkPos.getWorldPosition().atY(region.getMaxBuildHeight() - 1));
-            WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(RandomSupport.generateUniqueSeed()));
-            worldgenRandom.setDecorationSeed(region.getSeed(), chunkPos.getMinBlockX(), chunkPos.getMinBlockZ());
-            NaturalSpawner.spawnMobsForChunkGeneration(region, holder, chunkPos, worldgenRandom);
+        if (!((NoiseGeneratorSettings) this.settings.value()).disableMobGeneration()) {
+            ChunkPos chunkcoordintpair = region.getCenter();
+            Holder<Biome> holder = region.getBiome(chunkcoordintpair.getWorldPosition().atY(region.getMaxBuildHeight() - 1));
+            WorldgenRandom seededrandom = new WorldgenRandom(new LegacyRandomSource(RandomSupport.generateUniqueSeed()));
+
+            seededrandom.setDecorationSeed(region.getSeed(), chunkcoordintpair.getMinBlockX(), chunkcoordintpair.getMinBlockZ());
+            NaturalSpawner.spawnMobsForChunkGeneration(region, holder, chunkcoordintpair, seededrandom);
         }
     }
 }
