From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Wed, 15 Jul 2020 11:49:36 -0500
Subject: [PATCH] Configurable feature seed settings


diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/BambooFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/BambooFeature.java
index 7f3792fce13fbc27364b7d881933f54138717f51..f16c2ea9c44bb9889f4b12cb89367ef90a9bf222 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/BambooFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/BambooFeature.java
@@ -27,7 +27,7 @@ public class BambooFeature extends Feature<ProbabilityFeatureConfiguration> {
         int i = 0;
         BlockPos blockPos = context.origin();
         WorldGenLevel worldGenLevel = context.level();
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureBamboo); // Purpur
         ProbabilityFeatureConfiguration probabilityFeatureConfiguration = context.config();
         BlockPos.MutableBlockPos mutableBlockPos = blockPos.mutable();
         BlockPos.MutableBlockPos mutableBlockPos2 = blockPos.mutable();
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/BasaltColumnsFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/BasaltColumnsFeature.java
index 1949477637d826978e01547624bfccdb5048afb1..1af28ee54dc061d9ab1f06d07f4b8d58e7794677 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/BasaltColumnsFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/BasaltColumnsFeature.java
@@ -29,7 +29,7 @@ public class BasaltColumnsFeature extends Feature<ColumnFeatureConfiguration> {
         int i = context.chunkGenerator().getSeaLevel();
         BlockPos blockPos = context.origin();
         WorldGenLevel worldGenLevel = context.level();
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureBasaltColumns); // Purpur
         ColumnFeatureConfiguration columnFeatureConfiguration = context.config();
         if (!canPlaceAt(worldGenLevel, i, blockPos.mutable())) {
             return false;
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/BasaltPillarFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/BasaltPillarFeature.java
index 94c01df47765c7e7e9cc4cd59b87e14ead4e4e86..39b6d627ff7c59b91ab22d5eba8658232784b50f 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/BasaltPillarFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/BasaltPillarFeature.java
@@ -19,7 +19,7 @@ public class BasaltPillarFeature extends Feature<NoneFeatureConfiguration> {
     public boolean place(FeaturePlaceContext<NoneFeatureConfiguration> context) {
         BlockPos blockPos = context.origin();
         WorldGenLevel worldGenLevel = context.level();
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureBasaltPillar); // Purpur
         if (worldGenLevel.isEmptyBlock(blockPos) && !worldGenLevel.isEmptyBlock(blockPos.above())) {
             BlockPos.MutableBlockPos mutableBlockPos = blockPos.mutable();
             BlockPos.MutableBlockPos mutableBlockPos2 = blockPos.mutable();
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/BaseDiskFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/BaseDiskFeature.java
index 080bc62fa178bb84ad8672268e75be2ad554dfd2..b48084e3b63bda65ab58d5966dc5b0c94cef2992 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/BaseDiskFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/BaseDiskFeature.java
@@ -14,17 +14,20 @@ public class BaseDiskFeature extends Feature<DiskConfiguration> {
         super(configCodec);
     }
 
+    protected net.minecraft.core.BlockPos origin; // Purpur
+    protected java.util.Random random; // Purpur
+
     @Override
     public boolean place(FeaturePlaceContext<DiskConfiguration> context) {
         DiskConfiguration diskConfiguration = context.config();
-        BlockPos blockPos = context.origin();
+        BlockPos blockPos = this.origin; // Purpur
         WorldGenLevel worldGenLevel = context.level();
         boolean bl = false;
         int i = blockPos.getY();
         int j = i + diskConfiguration.halfHeight;
         int k = i - diskConfiguration.halfHeight - 1;
         boolean bl2 = diskConfiguration.state.getBlock() instanceof FallingBlock;
-        int l = diskConfiguration.radius.sample(context.random());
+        int l = diskConfiguration.radius.sample(this.random); // Purpur
 
         for(int m = blockPos.getX() - l; m <= blockPos.getX() + l; ++m) {
             for(int n = blockPos.getZ() - l; n <= blockPos.getZ() + l; ++n) {
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/BlockBlobFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/BlockBlobFeature.java
index fb7002cbc3a80e390f3220e1e8a8c3ad85b97b52..455d6ac2824a8a6cfa8cc89f7f108d2c855c692c 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/BlockBlobFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/BlockBlobFeature.java
@@ -16,7 +16,7 @@ public class BlockBlobFeature extends Feature<BlockStateConfiguration> {
     public boolean place(FeaturePlaceContext<BlockStateConfiguration> context) {
         BlockPos blockPos = context.origin();
         WorldGenLevel worldGenLevel = context.level();
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureForestRock); // Purpur
 
         BlockStateConfiguration blockStateConfiguration;
         for(blockStateConfiguration = context.config(); blockPos.getY() > worldGenLevel.getMinBuildHeight() + 3; blockPos = blockPos.below()) {
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/BlockPileFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/BlockPileFeature.java
index 2cdb1f0dd3e5d184f4cf5f3807c0e76913e62be0..749577d6a8fc01cd89fef885961de2cf59145f75 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/BlockPileFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/BlockPileFeature.java
@@ -19,7 +19,7 @@ public class BlockPileFeature extends Feature<BlockPileConfiguration> {
     public boolean place(FeaturePlaceContext<BlockPileConfiguration> context) {
         BlockPos blockPos = context.origin();
         WorldGenLevel worldGenLevel = context.level();
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureBlockPile); // Purpur
         BlockPileConfiguration blockPileConfiguration = context.config();
         if (blockPos.getY() < worldGenLevel.getMinBuildHeight() + 5) {
             return false;
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/BlueIceFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/BlueIceFeature.java
index fd289d06417a96a95265f0da835b7ca868eba6b6..0c9ca3866caf870f07c6a1c84832a0efad4934a5 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/BlueIceFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/BlueIceFeature.java
@@ -19,7 +19,7 @@ public class BlueIceFeature extends Feature<NoneFeatureConfiguration> {
     public boolean place(FeaturePlaceContext<NoneFeatureConfiguration> context) {
         BlockPos blockPos = context.origin();
         WorldGenLevel worldGenLevel = context.level();
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureBlueIce); // Purpur
         if (blockPos.getY() > worldGenLevel.getSeaLevel() - 1) {
             return false;
         } else if (!worldGenLevel.getBlockState(blockPos).is(Blocks.WATER) && !worldGenLevel.getBlockState(blockPos.below()).is(Blocks.WATER)) {
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/BonusChestFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/BonusChestFeature.java
index f0897875e9b61a9e49f0acf31fdfac6237dc32b3..47f14f5b331c925222e363ef3b42a5539c1b626f 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/BonusChestFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/BonusChestFeature.java
@@ -24,7 +24,7 @@ public class BonusChestFeature extends Feature<NoneFeatureConfiguration> {
 
     @Override
     public boolean place(FeaturePlaceContext<NoneFeatureConfiguration> context) {
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureBonusChest); // Purpur
         WorldGenLevel worldGenLevel = context.level();
         ChunkPos chunkPos = new ChunkPos(context.origin());
         List<Integer> list = IntStream.rangeClosed(chunkPos.getMinBlockX(), chunkPos.getMaxBlockX()).boxed().collect(Collectors.toList());
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/ChorusPlantFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/ChorusPlantFeature.java
index 6640061ecc11ec3e4a0203d8d6990489fcf10729..565f32a933090360412d9c98f8945f1719a768d3 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/ChorusPlantFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/ChorusPlantFeature.java
@@ -17,7 +17,7 @@ public class ChorusPlantFeature extends Feature<NoneFeatureConfiguration> {
     public boolean place(FeaturePlaceContext<NoneFeatureConfiguration> context) {
         WorldGenLevel worldGenLevel = context.level();
         BlockPos blockPos = context.origin();
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureChorusPlant); // Purpur
         if (worldGenLevel.isEmptyBlock(blockPos) && worldGenLevel.getBlockState(blockPos.below()).is(Blocks.END_STONE)) {
             ChorusFlowerBlock.generatePlant(worldGenLevel, blockPos, random, 8);
             return true;
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/CoralClawFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/CoralClawFeature.java
index 17f603fe4508fd8b803a2e921a169eccf0d20585..76b32e7cb8ec952475a98478294806426ce5a667 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/CoralClawFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/CoralClawFeature.java
@@ -17,6 +17,14 @@ public class CoralClawFeature extends CoralFeature {
         super(configCodec);
     }
 
+    // Purpur start
+    @Override
+    public boolean place(FeaturePlaceContext<NoneFeatureConfiguration> context) {
+        this.random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureCoralClaw);
+        return super.place(context);
+    }
+    // Purpur end
+
     @Override
     protected boolean placeFeature(LevelAccessor world, Random random, BlockPos pos, BlockState state) {
         if (!this.placeCoralBlock(world, random, pos, state)) {
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/CoralFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/CoralFeature.java
index 15b99d94b7d3e494a2fe4a205f9145b5fabbc125..650296b6526d06df0bca12262db90aec380d35f3 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/CoralFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/CoralFeature.java
@@ -18,9 +18,11 @@ public abstract class CoralFeature extends Feature<NoneFeatureConfiguration> {
         super(configCodec);
     }
 
+    protected Random random; // Purpur
+
     @Override
     public boolean place(FeaturePlaceContext<NoneFeatureConfiguration> context) {
-        Random random = context.random();
+        //Random random = context.random(); // Purpur
         WorldGenLevel worldGenLevel = context.level();
         BlockPos blockPos = context.origin();
         BlockState blockState = BlockTags.CORAL_BLOCKS.getRandomElement(random).defaultBlockState();
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/CoralMushroomFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/CoralMushroomFeature.java
index 8c2b3a037bac75fcadafd368ff8416f5de00df7f..85522d9c8ac4893aedb208b0f054ff0016808e56 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/CoralMushroomFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/CoralMushroomFeature.java
@@ -13,6 +13,14 @@ public class CoralMushroomFeature extends CoralFeature {
         super(configCodec);
     }
 
+    // Purpur start
+    @Override
+    public boolean place(FeaturePlaceContext<NoneFeatureConfiguration> context) {
+        this.random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureCoralMushroom);
+        return super.place(context);
+    }
+    // Purpur end
+
     @Override
     protected boolean placeFeature(LevelAccessor world, Random random, BlockPos pos, BlockState state) {
         int i = random.nextInt(3) + 3;
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/CoralTreeFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/CoralTreeFeature.java
index 8d1985c96277a50c39858ee7754ed3d34d10d8cb..4cb63f98aca829154c67f354c64d7bef4af095cb 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/CoralTreeFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/CoralTreeFeature.java
@@ -16,6 +16,14 @@ public class CoralTreeFeature extends CoralFeature {
         super(configCodec);
     }
 
+    // Purpur start
+    @Override
+    public boolean place(FeaturePlaceContext<NoneFeatureConfiguration> context) {
+        this.random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureCoralTree);
+        return super.place(context);
+    }
+    // Purpur end
+
     @Override
     protected boolean placeFeature(LevelAccessor world, Random random, BlockPos pos, BlockState state) {
         BlockPos.MutableBlockPos mutableBlockPos = pos.mutable();
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/DecoratedFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/DecoratedFeature.java
index ae11f1ecf23b38b84ab09f66796d1509a21bfbd8..2d102ea80d3f8e8aad0d57626450a7f30bb6c346 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/DecoratedFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/DecoratedFeature.java
@@ -21,7 +21,7 @@ public class DecoratedFeature extends Feature<DecoratedFeatureConfiguration> {
         WorldGenLevel worldGenLevel = context.level();
         DecoratedFeatureConfiguration decoratedFeatureConfiguration = context.config();
         ChunkGenerator chunkGenerator = context.chunkGenerator();
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureDecorated); // Purpur
         BlockPos blockPos = context.origin();
         ConfiguredFeature<?, ?> configuredFeature = decoratedFeatureConfiguration.feature.get();
         decoratedFeatureConfiguration.decorator.getPositions(new DecorationContext(worldGenLevel, chunkGenerator), random, blockPos).forEach((blockPosx) -> {
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/DefaultFlowerFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/DefaultFlowerFeature.java
index 2bc983496d77058ecbb89d33c5614d798d321b85..4e715ba8c4cbffc681ec3c1256d286538a38bebd 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/DefaultFlowerFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/DefaultFlowerFeature.java
@@ -29,6 +29,7 @@ public class DefaultFlowerFeature extends AbstractFlowerFeature<RandomPatchConfi
 
     @Override
     public BlockState getRandomFlower(Random random, BlockPos pos, RandomPatchConfiguration config) {
+        random = getRnd(random, net.pl3x.purpur.PurpurConfig.seedFeatureFlower); // Purpur
         return config.stateProvider.getState(random, pos);
     }
 }
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/DeltaFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/DeltaFeature.java
index fa0d751fbde63c739266495699d28154cd342f79..fb66f270b459919f885ddd09a1c2fa2957c8164d 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/DeltaFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/DeltaFeature.java
@@ -24,7 +24,7 @@ public class DeltaFeature extends Feature<DeltaFeatureConfiguration> {
     @Override
     public boolean place(FeaturePlaceContext<DeltaFeatureConfiguration> context) {
         boolean bl = false;
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureDeltaFeature); // Purpur
         WorldGenLevel worldGenLevel = context.level();
         DeltaFeatureConfiguration deltaFeatureConfiguration = context.config();
         BlockPos blockPos = context.origin();
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/DiskReplaceFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/DiskReplaceFeature.java
index b29719a0af670261073ef2a1d87ca255f9de095b..a957765736a2c49a58254fb6bedbc8f961811224 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/DiskReplaceFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/DiskReplaceFeature.java
@@ -11,6 +11,8 @@ public class DiskReplaceFeature extends BaseDiskFeature {
 
     @Override
     public boolean place(FeaturePlaceContext<DiskConfiguration> context) {
+        this.origin = context.origin(); // Purpur
+        this.random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureDisk); // Purpur
         return !context.level().getFluidState(context.origin()).is(FluidTags.WATER) ? false : super.place(context);
     }
 }
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/DripstoneClusterFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/DripstoneClusterFeature.java
index eeda6ce19bef98f939a4ecd12e0e63c6bf6d3986..3f94aadc6216a83714be8af9e22ed56fb5bc1b93 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/DripstoneClusterFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/DripstoneClusterFeature.java
@@ -28,7 +28,7 @@ public class DripstoneClusterFeature extends Feature<DripstoneClusterConfigurati
         WorldGenLevel worldGenLevel = context.level();
         BlockPos blockPos = context.origin();
         DripstoneClusterConfiguration dripstoneClusterConfiguration = context.config();
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureDripstoneCluster); // Purpur
         if (!DripstoneUtils.isEmptyOrWater(worldGenLevel, blockPos)) {
             return false;
         } else {
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/EndIslandFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/EndIslandFeature.java
index 59867e86bc6ee02098a420e74bd249f66d50e319..58c506f4a2fb9b45e78d59383757421a9b86d1f6 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/EndIslandFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/EndIslandFeature.java
@@ -16,7 +16,7 @@ public class EndIslandFeature extends Feature<NoneFeatureConfiguration> {
     @Override
     public boolean place(FeaturePlaceContext<NoneFeatureConfiguration> context) {
         WorldGenLevel worldGenLevel = context.level();
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureEndIsland); // Purpur
         BlockPos blockPos = context.origin();
         float f = (float)(random.nextInt(3) + 4);
 
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/Feature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/Feature.java
index 66f97b70985ed728eadcf837f25e81a256c2033b..6120409ab412c1237b44862ed1c402c855ededf0 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/Feature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/Feature.java
@@ -118,6 +118,21 @@ public abstract class Feature<FC extends FeatureConfiguration> {
         return Registry.register(Registry.FEATURE, name, feature);
     }
 
+    // Purpur start
+    @org.jetbrains.annotations.Nullable
+    private java.util.Random rnd;
+
+    protected java.util.Random getRnd(java.util.Random rand, int seed) {
+        if (seed == -1) {
+            return rand;
+        }
+        if(this.rnd == null) {
+            this.rnd = new java.util.Random(seed);
+        }
+        return this.rnd;
+    }
+    // Purpur end
+
     public Feature(Codec<FC> configCodec) {
         this.configuredCodec = configCodec.fieldOf("config").xmap((config) -> {
             return new ConfiguredFeature<>(this, config);
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/FossilFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/FossilFeature.java
index 82ea6a21d5fe0853c8fe1ef245609f01e9dbadb7..5032d5d190835aa941dfe5a2203f5b22966f6f2f 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/FossilFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/FossilFeature.java
@@ -24,7 +24,7 @@ public class FossilFeature extends Feature<FossilFeatureConfiguration> {
 
     @Override
     public boolean place(FeaturePlaceContext<FossilFeatureConfiguration> context) {
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureFossil); // Purpur
         WorldGenLevel worldGenLevel = context.level();
         BlockPos blockPos = context.origin();
         Rotation rotation = Rotation.getRandom(random);
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/GeodeFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/GeodeFeature.java
index 74a0adf4adf2b701126724e08bb72fa4e8e8560a..37756eb9e84ad8d91e6ede9b6c9264b2dc8371d5 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/GeodeFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/GeodeFeature.java
@@ -34,7 +34,7 @@ public class GeodeFeature extends Feature<GeodeConfiguration> {
     @Override
     public boolean place(FeaturePlaceContext<GeodeConfiguration> context) {
         GeodeConfiguration geodeConfiguration = context.config();
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureGeode); // Purpur
         BlockPos blockPos = context.origin();
         WorldGenLevel worldGenLevel = context.level();
         int i = geodeConfiguration.minGenOffset;
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/GlowLichenFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/GlowLichenFeature.java
index f8e72b9e68e0ce7611005650bee24842099973a7..817c3117f1d7f0fe2d627e87444f71f8c8fd06df 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/GlowLichenFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/GlowLichenFeature.java
@@ -23,7 +23,7 @@ public class GlowLichenFeature extends Feature<GlowLichenConfiguration> {
     public boolean place(FeaturePlaceContext<GlowLichenConfiguration> context) {
         WorldGenLevel worldGenLevel = context.level();
         BlockPos blockPos = context.origin();
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureGlowLichen); // Purpur
         GlowLichenConfiguration glowLichenConfiguration = context.config();
         if (!isAirOrWater(worldGenLevel.getBlockState(blockPos))) {
             return false;
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/GlowstoneFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/GlowstoneFeature.java
index df6229c8d2d8bc182d113fa1508da5a3948516e2..2a1337006f06f399dd8885c1b0380389c1dde493 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/GlowstoneFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/GlowstoneFeature.java
@@ -18,7 +18,7 @@ public class GlowstoneFeature extends Feature<NoneFeatureConfiguration> {
     public boolean place(FeaturePlaceContext<NoneFeatureConfiguration> context) {
         WorldGenLevel worldGenLevel = context.level();
         BlockPos blockPos = context.origin();
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureGlowstoneBlob); // Purpur
         if (!worldGenLevel.isEmptyBlock(blockPos)) {
             return false;
         } else {
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/GrowingPlantFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/GrowingPlantFeature.java
index 6f0549c72d9fedae39da1427b6facbf938da5d3f..db22ef9d2a1529096b5b44cc76d909dfadc77e42 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/GrowingPlantFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/GrowingPlantFeature.java
@@ -17,7 +17,7 @@ public class GrowingPlantFeature extends Feature<GrowingPlantConfiguration> {
     public boolean place(FeaturePlaceContext<GrowingPlantConfiguration> context) {
         LevelAccessor levelAccessor = context.level();
         GrowingPlantConfiguration growingPlantConfiguration = context.config();
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureGrowingPlant); // Purpur
         int i = growingPlantConfiguration.heightDistribution.getRandomValue(random).orElseThrow(IllegalStateException::new).sample(random);
         BlockPos.MutableBlockPos mutableBlockPos = context.origin().mutable();
         BlockPos.MutableBlockPos mutableBlockPos2 = mutableBlockPos.mutable().move(growingPlantConfiguration.direction);
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/HugeBrownMushroomFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/HugeBrownMushroomFeature.java
index 9261ca82851fb28ac17fc636bacd22cd02b1cbc5..e55594840a9cede00bc997ac667438a695acd74a 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/HugeBrownMushroomFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/HugeBrownMushroomFeature.java
@@ -15,6 +15,7 @@ public class HugeBrownMushroomFeature extends AbstractHugeMushroomFeature {
 
     @Override
     protected void makeCap(LevelAccessor world, Random random, BlockPos start, int y, BlockPos.MutableBlockPos mutable, HugeMushroomFeatureConfiguration config) {
+        random = getRnd(random, net.pl3x.purpur.PurpurConfig.seedFeatureHugeBrownMushroom); // Purpur
         int i = config.foliageRadius;
 
         for(int j = -i; j <= i; ++j) {
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/HugeFungusFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/HugeFungusFeature.java
index 44ae76882096cc6270a39754adf6070433c1e8d7..4f1cc232ec3e9a498308cf00749d7cda5ba60542 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/HugeFungusFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/HugeFungusFeature.java
@@ -24,7 +24,7 @@ public class HugeFungusFeature extends Feature<HugeFungusConfiguration> {
     public boolean place(FeaturePlaceContext<HugeFungusConfiguration> context) {
         WorldGenLevel worldGenLevel = context.level();
         BlockPos blockPos = context.origin();
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureHugeFungus); // Purpur
         ChunkGenerator chunkGenerator = context.chunkGenerator();
         HugeFungusConfiguration hugeFungusConfiguration = context.config();
         Block block = hugeFungusConfiguration.validBaseState.getBlock();
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/HugeRedMushroomFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/HugeRedMushroomFeature.java
index c5e436fa3188bee2cd546a6bc59cdb6b90c5d816..27d4a21321729a52fb9879131cf413df12c1e25d 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/HugeRedMushroomFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/HugeRedMushroomFeature.java
@@ -15,6 +15,7 @@ public class HugeRedMushroomFeature extends AbstractHugeMushroomFeature {
 
     @Override
     protected void makeCap(LevelAccessor world, Random random, BlockPos start, int y, BlockPos.MutableBlockPos mutable, HugeMushroomFeatureConfiguration config) {
+        random = getRnd(random, net.pl3x.purpur.PurpurConfig.seedFeatureHugeRedMushroom); // Purpur
         for(int i = y - 3; i <= y; ++i) {
             int j = i < y ? config.foliageRadius : config.foliageRadius - 1;
             int k = config.foliageRadius - 2;
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/IcePatchFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/IcePatchFeature.java
index 17b03939edeb0a51fdaa4cb5313a9b8e0c81471e..d415263abda0505acd0af16724a3501a0e00f7bc 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/IcePatchFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/IcePatchFeature.java
@@ -16,14 +16,19 @@ public class IcePatchFeature extends BaseDiskFeature {
     @Override
     public boolean place(FeaturePlaceContext<DiskConfiguration> context) {
         WorldGenLevel worldGenLevel = context.level();
-        ChunkGenerator chunkGenerator = context.chunkGenerator();
-        Random random = context.random();
-        DiskConfiguration diskConfiguration = context.config();
+        // Purpur start
+        //ChunkGenerator chunkGenerator = context.chunkGenerator();
+        this.random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureIcePatch); // Purpur
+        //DiskConfiguration diskConfiguration = context.config();
+        // Purpur end
 
         BlockPos blockPos;
         for(blockPos = context.origin(); worldGenLevel.isEmptyBlock(blockPos) && blockPos.getY() > worldGenLevel.getMinBuildHeight() + 2; blockPos = blockPos.below()) {
         }
 
-        return !worldGenLevel.getBlockState(blockPos).is(Blocks.SNOW_BLOCK) ? false : super.place(new FeaturePlaceContext<>(worldGenLevel, chunkGenerator, random, blockPos, diskConfiguration));
+        // Purpur start - lets not allocate _another_ context here...
+        this.origin = blockPos;
+        return !worldGenLevel.getBlockState(blockPos).is(Blocks.SNOW_BLOCK) ? false : super.place(context);
+        // Purpur end
     }
 }
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/IceSpikeFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/IceSpikeFeature.java
index a580c19c4d6f00472da0a229808c5962322e5b7f..1fbf9b071e4253b860e863d3b79dfe4079e453a4 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/IceSpikeFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/IceSpikeFeature.java
@@ -17,7 +17,7 @@ public class IceSpikeFeature extends Feature<NoneFeatureConfiguration> {
     @Override
     public boolean place(FeaturePlaceContext<NoneFeatureConfiguration> context) {
         BlockPos blockPos = context.origin();
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureIceSpike); // Purpur
 
         WorldGenLevel worldGenLevel;
         for(worldGenLevel = context.level(); worldGenLevel.isEmptyBlock(blockPos) && blockPos.getY() > worldGenLevel.getMinBuildHeight() + 2; blockPos = blockPos.below()) {
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/IcebergFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/IcebergFeature.java
index c12ce0d8e4e0e3caa7cb4a17787498a546d8bcca..0726174d6e1b4c4653ae53b25e22e36fb68f4cb3 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/IcebergFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/IcebergFeature.java
@@ -22,7 +22,7 @@ public class IcebergFeature extends Feature<BlockStateConfiguration> {
         BlockPos blockPos = context.origin();
         WorldGenLevel worldGenLevel = context.level();
         blockPos = new BlockPos(blockPos.getX(), context.chunkGenerator().getSeaLevel(), blockPos.getZ());
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureIceberg); // Purpur
         boolean bl = random.nextDouble() > 0.7D;
         BlockState blockState = (context.config()).state;
         double d = random.nextDouble() * 2.0D * Math.PI;
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/KelpFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/KelpFeature.java
index ecf431bffe7da1f1a82b054213a736ad0fa17029..54a41a1536ada31402cdfe428c02492c0cc4b6fb 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/KelpFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/KelpFeature.java
@@ -20,7 +20,7 @@ public class KelpFeature extends Feature<NoneFeatureConfiguration> {
         int i = 0;
         WorldGenLevel worldGenLevel = context.level();
         BlockPos blockPos = context.origin();
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureKelp); // Purpur
         int j = worldGenLevel.getHeight(Heightmap.Types.OCEAN_FLOOR, blockPos.getX(), blockPos.getZ());
         BlockPos blockPos2 = new BlockPos(blockPos.getX(), j, blockPos.getZ());
         if (worldGenLevel.getBlockState(blockPos2).is(Blocks.WATER)) {
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/LakeFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/LakeFeature.java
index f3d9fc4b64089c5f406b346f92a2bcd00e98e370..5cc88872bf2eb54bb1ac04b1b837617a096b6f4f 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/LakeFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/LakeFeature.java
@@ -25,7 +25,7 @@ public class LakeFeature extends Feature<BlockStateConfiguration> {
     public boolean place(FeaturePlaceContext<BlockStateConfiguration> context) {
         BlockPos blockPos = context.origin();
         WorldGenLevel worldGenLevel = context.level();
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureLake); // Purpur
 
         BlockStateConfiguration blockStateConfiguration;
         for(blockStateConfiguration = context.config(); blockPos.getY() > worldGenLevel.getMinBuildHeight() + 5 && worldGenLevel.isEmptyBlock(blockPos); blockPos = blockPos.below()) {
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/LargeDripstoneFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/LargeDripstoneFeature.java
index 975e1f0fb37e1e289eba73cc6cb51adba7ba2667..523bbd94f4b83c0123873083267cf28fc64a2e33 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/LargeDripstoneFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/LargeDripstoneFeature.java
@@ -26,7 +26,7 @@ public class LargeDripstoneFeature extends Feature<LargeDripstoneConfiguration>
         WorldGenLevel worldGenLevel = context.level();
         BlockPos blockPos = context.origin();
         LargeDripstoneConfiguration largeDripstoneConfiguration = context.config();
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureLargeDripstone); // Purpur
         if (!DripstoneUtils.isEmptyOrWater(worldGenLevel, blockPos)) {
             return false;
         } else {
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/MonsterRoomFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/MonsterRoomFeature.java
index d36b6208077254af5f0ebed8e8ce20fd45cbb79d..d60a6e06cd5730f1efbccde71834b0f1b619b66b 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/MonsterRoomFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/MonsterRoomFeature.java
@@ -34,7 +34,7 @@ public class MonsterRoomFeature extends Feature<NoneFeatureConfiguration> {
     public boolean place(FeaturePlaceContext<NoneFeatureConfiguration> context) {
         Predicate<BlockState> predicate = Feature.isReplaceable(BlockTags.FEATURES_CANNOT_REPLACE.getName());
         BlockPos blockPos = context.origin();
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureMonsterRoom); // Purpur
         WorldGenLevel worldGenLevel = context.level();
         int i = 3;
         int j = random.nextInt(2) + 2;
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/NetherForestVegetationFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/NetherForestVegetationFeature.java
index c8af12a5989bb8d8800927c8b2d7988a5d26614c..3f90becb14be2cfd7467596da1b85ee4c8708421 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/NetherForestVegetationFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/NetherForestVegetationFeature.java
@@ -15,7 +15,8 @@ public class NetherForestVegetationFeature extends Feature<BlockPileConfiguratio
 
     @Override
     public boolean place(FeaturePlaceContext<BlockPileConfiguration> context) {
-        return place(context.level(), context.random(), context.origin(), context.config(), 8, 4);
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureNetherFortressVegetation); // Purpur
+        return place(context.level(), random, context.origin(), context.config(), 8, 4); // Purpur
     }
 
     public static boolean place(LevelAccessor world, Random random, BlockPos pos, BlockPileConfiguration config, int i, int j) {
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/OreFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/OreFeature.java
index dbe7d624aaaa8455217a5397a66ef6964a3e210f..a6f6a5481d360f8259a0fec84be7183885937d58 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/OreFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/OreFeature.java
@@ -22,7 +22,7 @@ public class OreFeature extends Feature<OreConfiguration> {
 
     @Override
     public boolean place(FeaturePlaceContext<OreConfiguration> context) {
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureOre); // Purpur
         BlockPos blockPos = context.origin();
         WorldGenLevel worldGenLevel = context.level();
         OreConfiguration oreConfiguration = context.config();
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/RandomBooleanSelectorFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/RandomBooleanSelectorFeature.java
index e7c0f1ae6b526e0f22bc9f9abc59e1dccc3cc063..b7fee9c4a5a3dc22e4a095d2d07b64252a83a608 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/RandomBooleanSelectorFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/RandomBooleanSelectorFeature.java
@@ -14,7 +14,7 @@ public class RandomBooleanSelectorFeature extends Feature<RandomBooleanFeatureCo
 
     @Override
     public boolean place(FeaturePlaceContext<RandomBooleanFeatureConfiguration> context) {
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureRandomBooleanSelector); // Purpur
         RandomBooleanFeatureConfiguration randomBooleanFeatureConfiguration = context.config();
         WorldGenLevel worldGenLevel = context.level();
         ChunkGenerator chunkGenerator = context.chunkGenerator();
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/RandomPatchFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/RandomPatchFeature.java
index 8dfa0a29fdf9977d9b6dd062821effd7fba47719..22d99ef44b9dc6c0fb095ea32afb552410e59962 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/RandomPatchFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/RandomPatchFeature.java
@@ -17,7 +17,7 @@ public class RandomPatchFeature extends Feature<RandomPatchConfiguration> {
     @Override
     public boolean place(FeaturePlaceContext<RandomPatchConfiguration> context) {
         RandomPatchConfiguration randomPatchConfiguration = context.config();
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureRandomPatch); // Purpur
         BlockPos blockPos = context.origin();
         WorldGenLevel worldGenLevel = context.level();
         BlockState blockState = randomPatchConfiguration.stateProvider.getState(random, blockPos);
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/RandomSelectorFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/RandomSelectorFeature.java
index 3188de86c094f2c820e8dad3086df37f867add34..bcfd697bda3521722576e4b1fcc327971820b5e7 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/RandomSelectorFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/RandomSelectorFeature.java
@@ -15,7 +15,7 @@ public class RandomSelectorFeature extends Feature<RandomFeatureConfiguration> {
     @Override
     public boolean place(FeaturePlaceContext<RandomFeatureConfiguration> context) {
         RandomFeatureConfiguration randomFeatureConfiguration = context.config();
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureRandomSelector); // Purpur
         WorldGenLevel worldGenLevel = context.level();
         ChunkGenerator chunkGenerator = context.chunkGenerator();
         BlockPos blockPos = context.origin();
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/ReplaceBlobsFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/ReplaceBlobsFeature.java
index efc970a27c556c3b8da6727ffdfda71c90f12556..6634bc093a3308d3b9bd491456ac115062fba2e4 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/ReplaceBlobsFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/ReplaceBlobsFeature.java
@@ -20,7 +20,7 @@ public class ReplaceBlobsFeature extends Feature<ReplaceSphereConfiguration> {
     public boolean place(FeaturePlaceContext<ReplaceSphereConfiguration> context) {
         ReplaceSphereConfiguration replaceSphereConfiguration = context.config();
         WorldGenLevel worldGenLevel = context.level();
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureNetherrackReplaceBlobs); // Purpur
         Block block = replaceSphereConfiguration.targetState.getBlock();
         BlockPos blockPos = findTarget(worldGenLevel, context.origin().mutable().clamp(Direction.Axis.Y, worldGenLevel.getMinBuildHeight() + 1, worldGenLevel.getMaxBuildHeight() - 1), block);
         if (blockPos == null) {
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/ReplaceBlockFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/ReplaceBlockFeature.java
index 72ed95adc043ba78979ba0518d975ff57b35d5e1..513ac0f8a98ae6e1ad6e554c2dd3b16888cb9b68 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/ReplaceBlockFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/ReplaceBlockFeature.java
@@ -16,9 +16,10 @@ public class ReplaceBlockFeature extends Feature<ReplaceBlockConfiguration> {
         WorldGenLevel worldGenLevel = context.level();
         BlockPos blockPos = context.origin();
         ReplaceBlockConfiguration replaceBlockConfiguration = context.config();
+        java.util.Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureReplaceSingleBlock); // Purpur
 
         for(OreConfiguration.TargetBlockState targetBlockState : replaceBlockConfiguration.targetStates) {
-            if (targetBlockState.target.test(worldGenLevel.getBlockState(blockPos), context.random())) {
+            if (targetBlockState.target.test(worldGenLevel.getBlockState(blockPos), random)) { // Purpur
                 worldGenLevel.setBlock(blockPos, targetBlockState.state, 2);
                 break;
             }
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/RootSystemFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/RootSystemFeature.java
index 0ca15ac28c198e96ac21208e3c6bd46377df9b3b..a0c0bd2a5173e6629aa1422efb5be79881acf440 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/RootSystemFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/RootSystemFeature.java
@@ -26,7 +26,7 @@ public class RootSystemFeature extends Feature<RootSystemConfiguration> {
         if (!worldGenLevel.getBlockState(blockPos).isAir()) {
             return false;
         } else {
-            Random random = context.random();
+            Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureRootSystem); // Purpur
             BlockPos blockPos2 = context.origin();
             RootSystemConfiguration rootSystemConfiguration = context.config();
             BlockPos.MutableBlockPos mutableBlockPos = blockPos2.mutable();
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/ScatteredOreFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/ScatteredOreFeature.java
index eb4abeee4009c8f271c51f6c711c03b7a7360937..eb8af78c3fa6bfd960644b419c4500bd37f9a8d4 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/ScatteredOreFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/ScatteredOreFeature.java
@@ -17,7 +17,7 @@ public class ScatteredOreFeature extends Feature<OreConfiguration> {
     @Override
     public boolean place(FeaturePlaceContext<OreConfiguration> context) {
         WorldGenLevel worldGenLevel = context.level();
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureScatteredOre); // Purpur
         OreConfiguration oreConfiguration = context.config();
         BlockPos blockPos = context.origin();
         int i = random.nextInt(oreConfiguration.size + 1);
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/SeaPickleFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/SeaPickleFeature.java
index 5b1dd00cf379e07ac8770ab7b7ceb20a377fd586..415297785c83835333aef1da552cd510f2c8e4f7 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/SeaPickleFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/SeaPickleFeature.java
@@ -18,7 +18,7 @@ public class SeaPickleFeature extends Feature<CountConfiguration> {
     @Override
     public boolean place(FeaturePlaceContext<CountConfiguration> context) {
         int i = 0;
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureSeaPickle); // Purpur
         WorldGenLevel worldGenLevel = context.level();
         BlockPos blockPos = context.origin();
         int j = context.config().count().sample(random);
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/SeagrassFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/SeagrassFeature.java
index fc5a9fba1ecfa8850d31ba68e92c537e65dbed78..f913486542f0ca35cd36eb19f25918505dd2e70a 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/SeagrassFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/SeagrassFeature.java
@@ -19,7 +19,7 @@ public class SeagrassFeature extends Feature<ProbabilityFeatureConfiguration> {
     @Override
     public boolean place(FeaturePlaceContext<ProbabilityFeatureConfiguration> context) {
         boolean bl = false;
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureSeagrass); // Purpur
         WorldGenLevel worldGenLevel = context.level();
         BlockPos blockPos = context.origin();
         ProbabilityFeatureConfiguration probabilityFeatureConfiguration = context.config();
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/SimpleBlockFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/SimpleBlockFeature.java
index 1aaa0d7b73e7b89202b3cedd284c3b739d1e3091..7bcde212bc61d6c883b443f97b4a5ae4d3990f39 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/SimpleBlockFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/SimpleBlockFeature.java
@@ -17,8 +17,9 @@ public class SimpleBlockFeature extends Feature<SimpleBlockConfiguration> {
         SimpleBlockConfiguration simpleBlockConfiguration = context.config();
         WorldGenLevel worldGenLevel = context.level();
         BlockPos blockPos = context.origin();
+        java.util.Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureSimpleBlock); // Purpur
         if ((simpleBlockConfiguration.placeOn.isEmpty() || simpleBlockConfiguration.placeOn.contains(worldGenLevel.getBlockState(blockPos.below()))) && (simpleBlockConfiguration.placeIn.isEmpty() || simpleBlockConfiguration.placeIn.contains(worldGenLevel.getBlockState(blockPos))) && (simpleBlockConfiguration.placeUnder.isEmpty() || simpleBlockConfiguration.placeUnder.contains(worldGenLevel.getBlockState(blockPos.above())))) {
-            BlockState blockState = simpleBlockConfiguration.toPlace.getState(context.random(), blockPos);
+            BlockState blockState = simpleBlockConfiguration.toPlace.getState(random, blockPos); // Purpur
             if (blockState.canSurvive(worldGenLevel, blockPos)) {
                 if (blockState.getBlock() instanceof DoublePlantBlock) {
                     if (!worldGenLevel.isEmptyBlock(blockPos.above())) {
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/SimpleRandomSelectorFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/SimpleRandomSelectorFeature.java
index 51ddafe889ebd3a78eaa31c8f32db4b2931f5a20..60eae6fb250840e689172fb639d79670c501b7bc 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/SimpleRandomSelectorFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/SimpleRandomSelectorFeature.java
@@ -14,7 +14,7 @@ public class SimpleRandomSelectorFeature extends Feature<SimpleRandomFeatureConf
 
     @Override
     public boolean place(FeaturePlaceContext<SimpleRandomFeatureConfiguration> context) {
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureSimpleRandomSelector); // Purpur
         SimpleRandomFeatureConfiguration simpleRandomFeatureConfiguration = context.config();
         WorldGenLevel worldGenLevel = context.level();
         BlockPos blockPos = context.origin();
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/SmallDripstoneFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/SmallDripstoneFeature.java
index 7fe7009538b392ccb7547d0268ac8a1a6f682270..eb8bda1c3f73c3c2727ab893daa8b00008b1c117 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/SmallDripstoneFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/SmallDripstoneFeature.java
@@ -18,7 +18,7 @@ public class SmallDripstoneFeature extends Feature<SmallDripstoneConfiguration>
     public boolean place(FeaturePlaceContext<SmallDripstoneConfiguration> context) {
         WorldGenLevel worldGenLevel = context.level();
         BlockPos blockPos = context.origin();
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureSmallDripstone); // Purpur
         SmallDripstoneConfiguration smallDripstoneConfiguration = context.config();
         if (!DripstoneUtils.isEmptyOrWater(worldGenLevel, blockPos)) {
             return false;
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/SpikeFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/SpikeFeature.java
index c03bf5bdb67b00c75f9fcfead882c4d944282244..5ad051dd62968fb861a4ed2ad5426d6429184173 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/SpikeFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/SpikeFeature.java
@@ -36,7 +36,8 @@ public class SpikeFeature extends Feature<SpikeConfiguration> {
     }
 
     public static List<SpikeFeature.EndSpike> getSpikesForLevel(WorldGenLevel world) {
-        Random random = new Random(world.getSeed());
+        int seed = net.pl3x.purpur.PurpurConfig.seedFeatureEndSpike; // Purpur
+        Random random = new Random(seed == -1 ? world.getSeed() : seed); // Purpur
         long l = random.nextLong() & 65535L;
         return SPIKE_CACHE.getUnchecked(l);
     }
@@ -45,7 +46,7 @@ public class SpikeFeature extends Feature<SpikeConfiguration> {
     public boolean place(FeaturePlaceContext<SpikeConfiguration> context) {
         SpikeConfiguration spikeConfiguration = context.config();
         WorldGenLevel worldGenLevel = context.level();
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureEndSpike); // Purpur
         BlockPos blockPos = context.origin();
         List<SpikeFeature.EndSpike> list = spikeConfiguration.getSpikes();
         if (list.isEmpty()) {
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/TreeFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/TreeFeature.java
index 0be9ce0734e3ba72893a7349bb9f83a94f4af30c..2f71e80f6c9d37a97d1d03b7a1d893c825b315fa 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/TreeFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/TreeFeature.java
@@ -76,6 +76,7 @@ public class TreeFeature extends Feature<TreeConfiguration> {
     }
 
     private boolean doPlace(WorldGenLevel world, Random random, BlockPos pos, BiConsumer<BlockPos, BlockState> trunkReplacer, BiConsumer<BlockPos, BlockState> foliageReplacer, TreeConfiguration config) {
+        random = getRnd(random, net.pl3x.purpur.PurpurConfig.seedFeatureTree); // Purpur
         int i = config.trunkPlacer.getTreeHeight(random);
         int j = config.foliagePlacer.foliageHeight(random, i, config);
         int k = i - j;
@@ -88,8 +89,9 @@ public class TreeFeature extends Feature<TreeConfiguration> {
                 int m = this.getMaxFreeTreeHeight(world, i, pos, config);
                 if (m >= i || optionalInt.isPresent() && m >= optionalInt.getAsInt()) {
                     List<FoliagePlacer.FoliageAttachment> list = config.trunkPlacer.placeTrunk(world, trunkReplacer, random, m, pos, config);
+                    final Random finalrandom = random; // Purpur
                     list.forEach((foliageAttachment) -> {
-                        config.foliagePlacer.createFoliage(world, foliageReplacer, random, config, m, foliageAttachment, j, l);
+                        config.foliagePlacer.createFoliage(world, foliageReplacer, finalrandom, config, m, foliageAttachment, j, l); // Purpur
                     });
                     return true;
                 } else {
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/TwistingVinesFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/TwistingVinesFeature.java
index c4d51a31343b92f62742506d7add2154a0b23015..799127f0bb1a91d640af6f542dbe304428a99092 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/TwistingVinesFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/TwistingVinesFeature.java
@@ -18,7 +18,8 @@ public class TwistingVinesFeature extends Feature<NoneFeatureConfiguration> {
 
     @Override
     public boolean place(FeaturePlaceContext<NoneFeatureConfiguration> context) {
-        return place(context.level(), context.random(), context.origin(), 8, 4, 8);
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureTwistingVines); // Purpur
+        return place(context.level(), random, context.origin(), 8, 4, 8); // Purpur
     }
 
     public static boolean place(LevelAccessor world, Random random, BlockPos pos, int horizontalSpread, int verticalSpread, int length) {
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/UnderwaterMagmaFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/UnderwaterMagmaFeature.java
index bd5466e532dc0f1b5a1df3bff3144d0bf7ff25f3..661680aa501dd57a228b7c4447969223592c88a8 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/UnderwaterMagmaFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/UnderwaterMagmaFeature.java
@@ -26,7 +26,7 @@ public class UnderwaterMagmaFeature extends Feature<UnderwaterMagmaConfiguration
         WorldGenLevel worldGenLevel = context.level();
         BlockPos blockPos = context.origin();
         UnderwaterMagmaConfiguration underwaterMagmaConfiguration = context.config();
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureUnderwaterMagma); // Purpur
         OptionalInt optionalInt = getFloorY(worldGenLevel, blockPos, underwaterMagmaConfiguration);
         if (!optionalInt.isPresent()) {
             return false;
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/VegetationPatchFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/VegetationPatchFeature.java
index 62165c0f5d1eba8c2734356bec33998d9dadbd1b..d9b1d92e1bb0123d9f7847a79ed5aa71ce7054d8 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/VegetationPatchFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/VegetationPatchFeature.java
@@ -23,9 +23,15 @@ public class VegetationPatchFeature extends Feature<VegetationPatchConfiguration
 
     @Override
     public boolean place(FeaturePlaceContext<VegetationPatchConfiguration> context) {
+        // Purpur start
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureVegetationPatch);
+        return place0(context, random);
+    }
+    protected boolean place0(FeaturePlaceContext<VegetationPatchConfiguration> context, Random random) {
+        // Purpur end
         WorldGenLevel worldGenLevel = context.level();
         VegetationPatchConfiguration vegetationPatchConfiguration = context.config();
-        Random random = context.random();
+        //Random random = context.random(); // Purpur
         BlockPos blockPos = context.origin();
         Predicate<BlockState> predicate = getReplaceableTag(vegetationPatchConfiguration);
         int i = vegetationPatchConfiguration.xzRadius.sample(random) + 1;
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/WaterloggedVegetationPatchFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/WaterloggedVegetationPatchFeature.java
index 62506ae3a49b0507d2d492da3a9baf96fea64a25..565e74a8314357a8e6e1a89c830011868d28c2a2 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/WaterloggedVegetationPatchFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/WaterloggedVegetationPatchFeature.java
@@ -19,6 +19,14 @@ public class WaterloggedVegetationPatchFeature extends VegetationPatchFeature {
         super(configCodec);
     }
 
+    // Purpur start
+    @Override
+    public boolean place(FeaturePlaceContext<VegetationPatchConfiguration> context) {
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureWaterloggedVegetationPatch); // Purpur
+        return place0(context, random);
+    }
+    // Purpur end
+
     @Override
     protected Set<BlockPos> placeGroundPatch(WorldGenLevel world, VegetationPatchConfiguration config, Random random, BlockPos pos, Predicate<BlockState> replaceable, int radiusX, int radiusZ) {
         Set<BlockPos> set = super.placeGroundPatch(world, config, random, pos, replaceable, radiusX, radiusZ);
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/WeepingVinesFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/WeepingVinesFeature.java
index ed3944a60d09495eb424dd11d00e8c3585177d51..fcf25cc905ece0213a0eb6365a0a57566ad29c9c 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/WeepingVinesFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/WeepingVinesFeature.java
@@ -23,7 +23,7 @@ public class WeepingVinesFeature extends Feature<NoneFeatureConfiguration> {
     public boolean place(FeaturePlaceContext<NoneFeatureConfiguration> context) {
         WorldGenLevel worldGenLevel = context.level();
         BlockPos blockPos = context.origin();
-        Random random = context.random();
+        Random random = getRnd(context.random(), net.pl3x.purpur.PurpurConfig.seedFeatureWeepingVines); // Purpur
         if (!worldGenLevel.isEmptyBlock(blockPos)) {
             return false;
         } else {
diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java
index 3bfddb1111f543a5badb26ca52b4dcef32a7cf1a..f8aeba21a04bcf3cc6c63bcf99ea3b5c2773741a 100644
--- a/src/main/java/net/pl3x/purpur/PurpurConfig.java
+++ b/src/main/java/net/pl3x/purpur/PurpurConfig.java
@@ -176,6 +176,128 @@ public class PurpurConfig {
         pingCommandOutput = getString("settings.messages.ping-command-output", pingCommandOutput);
     }
 
+    public static int seedFeatureBamboo = -1;
+    public static int seedFeatureBasaltColumns = -1;
+    public static int seedFeatureBasaltPillar = -1;
+    public static int seedFeatureBlockPile = -1;
+    public static int seedFeatureBlueIce = -1;
+    public static int seedFeatureBonusChest = -1;
+    public static int seedFeatureChorusPlant = -1;
+    public static int seedFeatureCoralClaw = -1;
+    public static int seedFeatureCoralMushroom = -1;
+    public static int seedFeatureCoralTree = -1;
+    public static int seedFeatureDecorated = -1;
+    public static int seedFeatureDeltaFeature = -1;
+    public static int seedFeatureDisk = -1;
+    public static int seedFeatureDripstoneCluster = -1;
+    public static int seedFeatureEndIsland = -1;
+    public static int seedFeatureEndSpike = -1;
+    public static int seedFeatureFlower = -1;
+    public static int seedFeatureForestRock = -1;
+    public static int seedFeatureFossil = -1;
+    public static int seedFeatureGeode = -1;
+    public static int seedFeatureGlowLichen = -1;
+    public static int seedFeatureGlowstoneBlob = -1;
+    public static int seedFeatureGrowingPlant = -1;
+    public static int seedFeatureHugeBrownMushroom = -1;
+    public static int seedFeatureHugeFungus = -1;
+    public static int seedFeatureHugeRedMushroom = -1;
+    public static int seedFeatureIcePatch = -1;
+    public static int seedFeatureIceSpike = -1;
+    public static int seedFeatureIceberg = -1;
+    public static int seedFeatureKelp = -1;
+    public static int seedFeatureLake = -1;
+    public static int seedFeatureLargeDripstone = -1;
+    public static int seedFeatureMonsterRoom = -1;
+    public static int seedFeatureNetherFortressVegetation = -1;
+    public static int seedFeatureNetherrackReplaceBlobs = -1;
+    public static int seedFeatureOre = -1;
+    public static int seedFeatureRandomBooleanSelector = -1;
+    public static int seedFeatureRandomPatch = -1;
+    public static int seedFeatureRandomSelector = -1;
+    public static int seedFeatureReplaceSingleBlock = -1;
+    public static int seedFeatureRootSystem = -1;
+    public static int seedFeatureScatteredOre = -1;
+    public static int seedFeatureSeaPickle = -1;
+    public static int seedFeatureSeagrass = -1;
+    public static int seedFeatureSimpleBlock = -1;
+    public static int seedFeatureSimpleRandomSelector = -1;
+    public static int seedFeatureSmallDripstone = -1;
+    public static int seedFeatureTree = -1;
+    public static int seedFeatureTwistingVines = -1;
+    public static int seedFeatureUnderwaterMagma = -1;
+    public static int seedFeatureVegetationPatch = -1;
+    public static int seedFeatureWaterloggedVegetationPatch = -1;
+    public static int seedFeatureWeepingVines = -1;
+    private static void seedSettings() {
+        if (version < 14) {
+            int oldValue = getInt("settings.seed.dungeon", -1);
+            set("settings.seed.feature.monster_room", oldValue);
+            set("settings.seed.dungeon", null);
+            oldValue = getInt("settings.seed.end-spike", -1);
+            set("settings.seed.feature.end_spike", oldValue);
+            set("settings.seed.end-spike", null);
+            oldValue = getInt("settings.seed.geode", -1);
+            set("settings.seed.feature.geode", oldValue);
+            set("settings.seed.geode", null);
+        }
+        seedFeatureBamboo = getInt("settings.seed.feature.bamboo", seedFeatureBamboo);
+        seedFeatureBasaltColumns = getInt("settings.seed.feature.basalt_columns", seedFeatureBasaltColumns);
+        seedFeatureBasaltPillar = getInt("settings.seed.feature.basalt_pillar", seedFeatureBasaltPillar);
+        seedFeatureBlockPile = getInt("settings.seed.feature.block_pile", seedFeatureBlockPile);
+        seedFeatureBlueIce = getInt("settings.seed.feature.blue_ice", seedFeatureBlueIce);
+        seedFeatureBonusChest = getInt("settings.seed.feature.bonus_chest", seedFeatureBonusChest);
+        seedFeatureChorusPlant = getInt("settings.seed.feature.chorus_plant", seedFeatureChorusPlant);
+        seedFeatureCoralClaw = getInt("settings.seed.feature.coral_claw", seedFeatureCoralClaw);
+        seedFeatureCoralMushroom = getInt("settings.seed.feature.coral_mushroom", seedFeatureCoralMushroom);
+        seedFeatureCoralTree = getInt("settings.seed.feature.coral_tree", seedFeatureCoralTree);
+        seedFeatureDecorated = getInt("settings.seed.feature.decorated", seedFeatureDecorated);
+        seedFeatureDeltaFeature = getInt("settings.seed.feature.delta_feature", seedFeatureDeltaFeature);
+        seedFeatureDisk = getInt("settings.seed.feature.disk", seedFeatureDisk);
+        seedFeatureDripstoneCluster = getInt("settings.seed.feature.dripstone_cluster", seedFeatureDripstoneCluster);
+        seedFeatureEndIsland = getInt("settings.seed.feature.end_island", seedFeatureEndIsland);
+        seedFeatureEndSpike = getInt("settings.seed.feature.end_spike", seedFeatureEndSpike);
+        seedFeatureFlower = getInt("settings.seed.feature.flower", seedFeatureFlower);
+        seedFeatureForestRock = getInt("settings.seed.feature.forest_rock", seedFeatureForestRock);
+        seedFeatureFossil = getInt("settings.seed.feature.fossil", seedFeatureFossil);
+        seedFeatureGeode = getInt("settings.seed.feature.geode", seedFeatureGeode);
+        seedFeatureGlowLichen = getInt("settings.seed.feature.glow_lichen", seedFeatureGlowLichen);
+        seedFeatureGlowstoneBlob = getInt("settings.seed.feature.glowstone_blob", seedFeatureGlowstoneBlob);
+        seedFeatureGrowingPlant = getInt("settings.seed.feature.growing_plant", seedFeatureGrowingPlant);
+        seedFeatureHugeBrownMushroom = getInt("settings.seed.feature.huge_brown_mushroom", seedFeatureHugeBrownMushroom);
+        seedFeatureHugeFungus = getInt("settings.seed.feature.huge_fungus", seedFeatureHugeFungus);
+        seedFeatureHugeRedMushroom = getInt("settings.seed.feature.huge_red_mushroom", seedFeatureHugeRedMushroom);
+        seedFeatureIcePatch = getInt("settings.seed.feature.ice_patch", seedFeatureIcePatch);
+        seedFeatureIceSpike = getInt("settings.seed.feature.ice_spike", seedFeatureIceSpike);
+        seedFeatureIceberg = getInt("settings.seed.feature.iceberg", seedFeatureIceberg);
+        seedFeatureKelp = getInt("settings.seed.feature.kelp", seedFeatureKelp);
+        seedFeatureLake = getInt("settings.seed.feature.lake", seedFeatureLake);
+        seedFeatureLargeDripstone = getInt("settings.seed.feature.large_dripstone", seedFeatureLargeDripstone);
+        seedFeatureMonsterRoom = getInt("settings.seed.feature.monster_room", seedFeatureMonsterRoom);
+        seedFeatureNetherFortressVegetation = getInt("settings.seed.feature.nether_forest_vegetation", seedFeatureNetherFortressVegetation);
+        seedFeatureNetherrackReplaceBlobs = getInt("settings.seed.feature.netherrack_replace_blobs", seedFeatureNetherrackReplaceBlobs);
+        seedFeatureOre = getInt("settings.seed.feature.ore", seedFeatureOre);
+        seedFeatureRandomBooleanSelector = getInt("settings.seed.feature.random_boolean_selector", seedFeatureRandomBooleanSelector);
+        seedFeatureRandomPatch = getInt("settings.seed.feature.random_patch", seedFeatureRandomPatch);
+        seedFeatureRandomSelector = getInt("settings.seed.feature.random_selector", seedFeatureRandomSelector);
+        seedFeatureReplaceSingleBlock = getInt("settings.seed.feature.replace_single_block", seedFeatureReplaceSingleBlock);
+        seedFeatureRootSystem = getInt("settings.seed.feature.root_system", seedFeatureRootSystem);
+        seedFeatureScatteredOre = getInt("settings.seed.feature.scattered_ore", seedFeatureScatteredOre);
+        seedFeatureSeaPickle = getInt("settings.seed.feature.sea_pickle", seedFeatureSeaPickle);
+        seedFeatureSeagrass = getInt("settings.seed.feature.seagrass", seedFeatureSeagrass);
+        seedFeatureSimpleBlock = getInt("settings.seed.feature.simple_block", seedFeatureSimpleBlock);
+        seedFeatureSimpleRandomSelector = getInt("settings.seed.feature.simple_random_selector", seedFeatureSimpleRandomSelector);
+        seedFeatureSmallDripstone = getInt("settings.seed.feature.small_dripstone", seedFeatureSmallDripstone);
+        seedFeatureTree = getInt("settings.seed.feature.tree", seedFeatureTree);
+        seedFeatureTwistingVines = getInt("settings.seed.feature.twisting_vines", seedFeatureTwistingVines);
+        seedFeatureUnderwaterMagma = getInt("settings.seed.feature.underwater_magma", seedFeatureUnderwaterMagma);
+        seedFeatureVegetationPatch = getInt("settings.seed.feature.vegetation_patch", seedFeatureVegetationPatch);
+        seedFeatureWaterloggedVegetationPatch = getInt("settings.seed.feature.waterlogged_vegetation_patch", seedFeatureWaterloggedVegetationPatch);
+        seedFeatureWeepingVines = getInt("settings.seed.feature.weeping_vines", seedFeatureWeepingVines);
+        // hide these from timings report
+        if (!TimingsManager.hiddenConfigs.contains("settings.seed")) TimingsManager.hiddenConfigs.add("settings.seed");
+    }
+
     public static String serverModName = "Purpur";
     private static void serverModName() {
         serverModName = getString("settings.server-mod-name", serverModName);
