From 58afd267131250a1d8b6e3a490bb001dc191aeb6 Mon Sep 17 00:00:00 2001
From: modmuss50 <modmuss50@gmail.com>
Date: Mon, 21 Feb 2022 11:58:35 +0000
Subject: [PATCH] 1.18.2-pre1 Biome API (#2010)

* Fix BiomeSelectors.tag

* Update fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/api/biome/v1/BiomeSelectionContext.java

Co-authored-by: Juuxel <6596629+Juuxel@users.noreply.github.com>

* Checkstyle

* Port Biome API

Co-authored-by: Juuxel <6596629+Juuxel@users.noreply.github.com>
---
 .../biome/v1/BiomeModificationContext.java    |  65 +-------
 .../api/biome/v1/BiomeModifications.java      |  12 --
 .../api/biome/v1/BiomeSelectionContext.java   |  14 +-
 .../fabric/api/biome/v1/BiomeSelectors.java   |   2 +-
 .../fabric/impl/biome/NetherBiomeData.java    |   2 +-
 .../BiomeModificationContextImpl.java         |  20 ---
 .../modification/BiomeModificationImpl.java   |   4 +-
 .../BiomeSelectionContextImpl.java            |  32 ++--
 .../BiomeStructureStartsImpl.java             | 150 ------------------
 .../fabric-biome-api-v1.accesswidener         |   4 +-
 .../fabric/test/biome/FabricBiomeTest.java    |  10 +-
 settings.gradle                               |   2 +-
 12 files changed, 38 insertions(+), 279 deletions(-)
 delete mode 100644 fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/impl/biome/modification/BiomeStructureStartsImpl.java

diff --git a/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/api/biome/v1/BiomeModificationContext.java b/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/api/biome/v1/BiomeModificationContext.java
index c5a985873..6ac6ccaa1 100644
--- a/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/api/biome/v1/BiomeModificationContext.java
+++ b/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/api/biome/v1/BiomeModificationContext.java
@@ -21,7 +21,6 @@ import java.util.function.BiPredicate;
 
 import org.jetbrains.annotations.NotNull;
 
-import net.minecraft.world.gen.feature.PlacedFeature;
 import net.minecraft.entity.EntityType;
 import net.minecraft.entity.SpawnGroup;
 import net.minecraft.sound.BiomeAdditionsSound;
@@ -36,8 +35,7 @@ import net.minecraft.world.biome.BiomeParticleConfig;
 import net.minecraft.world.biome.SpawnSettings;
 import net.minecraft.world.gen.GenerationStep;
 import net.minecraft.world.gen.carver.ConfiguredCarver;
-import net.minecraft.world.gen.feature.ConfiguredStructureFeature;
-import net.minecraft.world.gen.feature.StructureFeature;
+import net.minecraft.world.gen.feature.PlacedFeature;
 
 import net.fabricmc.fabric.impl.biome.modification.BuiltInRegistryKeys;
 
@@ -393,67 +391,6 @@ public interface BiomeModificationContext {
 		default boolean removeBuiltInCarver(GenerationStep.Carver step, ConfiguredCarver<?> configuredCarver) {
 			return removeCarver(step, BuiltInRegistryKeys.get(configuredCarver));
 		}
-
-		/**
-		 * Allows a configured structure to start in this biome.
-		 *
-		 * <p>Structures added this way may start in this biome, with respect to the {@link net.minecraft.world.gen.chunk.StructureConfig}
-		 * set in the {@link net.minecraft.world.gen.chunk.ChunkGenerator}, but structure pieces can always generate in chunks adjacent
-		 * to a started structure, regardless of biome.
-		 *
-		 * <p>Configured structures that have the same underlying {@link StructureFeature} as the given structure will be removed before
-		 * adding the new structure, since only one of them could actually generate.
-		 *
-		 * @see net.minecraft.world.biome.GenerationSettings.Builder#feature(GenerationStep.Feature, PlacedFeature)
-		 */
-		void addStructure(RegistryKey<ConfiguredStructureFeature<?, ?>> configuredStructureKey);
-
-		/**
-		 * Allows a configured structure from {@link BuiltinRegistries#CONFIGURED_STRUCTURE_FEATURE} to start in this biome.
-		 *
-		 * <p>This method is intended for use with the configured structures found in {@link net.minecraft.world.gen.feature.ConfiguredStructureFeatures}.
-		 *
-		 * <p><b>NOTE:</b> In case the configured structure is overridden using a datapack, the definition from the datapack
-		 * will be added to the biome.
-		 *
-		 * <p>Structures added this way may start in this biome, with respect to the {@link net.minecraft.world.gen.chunk.StructureConfig}
-		 * set in the {@link net.minecraft.world.gen.chunk.ChunkGenerator}, but structure pieces can always generate in chunks adjacent
-		 * to a started structure, regardless of biome.
-		 *
-		 * <p>Configured structures that have the same underlying {@link StructureFeature} as the given structure will be removed before
-		 * adding the new structure, since only one of them could actually generate.
-		 */
-		default void addBuiltInStructure(ConfiguredStructureFeature<?, ?> configuredStructure) {
-			addStructure(BuiltInRegistryKeys.get(configuredStructure));
-		}
-
-		/**
-		 * Removes a configured structure from the structures that are allowed to start in this biome.
-		 *
-		 * <p>Please see the note on {@link #addStructure(RegistryKey)} about structures pieces still generating
-		 * if adjacent biomes allow the structure to start.
-		 *
-		 * @return True if any structures were removed.
-		 */
-		boolean removeStructure(RegistryKey<ConfiguredStructureFeature<?, ?>> configuredStructureKey);
-
-		/**
-		 * Removes a structure from the structures that are allowed to start in this biome.
-		 *
-		 * <p>This will remove all configured variations of the given structure from this biome.
-		 *
-		 * <p>This can be used with modded structures or Vanilla structures from {@link net.minecraft.world.gen.feature.StructureFeature}.
-		 *
-		 * @return True if any structures were removed.
-		 */
-		boolean removeStructure(StructureFeature<?> structure);
-
-		/**
-		 * {@link #removeStructure(RegistryKey)} for built-in structures (see {@link #addBuiltInStructure(ConfiguredStructureFeature)}).
-		 */
-		default boolean removeBuiltInStructure(ConfiguredStructureFeature<?, ?> configuredStructure) {
-			return removeStructure(BuiltInRegistryKeys.get(configuredStructure));
-		}
 	}
 
 	interface SpawnSettingsContext {
diff --git a/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/api/biome/v1/BiomeModifications.java b/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/api/biome/v1/BiomeModifications.java
index 0700cc50d..ee8ffe1f1 100644
--- a/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/api/biome/v1/BiomeModifications.java
+++ b/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/api/biome/v1/BiomeModifications.java
@@ -28,7 +28,6 @@ import net.minecraft.util.registry.RegistryKey;
 import net.minecraft.world.biome.SpawnSettings;
 import net.minecraft.world.gen.GenerationStep;
 import net.minecraft.world.gen.carver.ConfiguredCarver;
-import net.minecraft.world.gen.feature.ConfiguredStructureFeature;
 import net.minecraft.world.gen.feature.PlacedFeature;
 
 /**
@@ -51,17 +50,6 @@ public final class BiomeModifications {
 		});
 	}
 
-	/**
-	 * Convenience method to add a structure to one or more biomes.
-	 *
-	 * @see BiomeSelectors
-	 */
-	public static void addStructure(Predicate<BiomeSelectionContext> biomeSelector, RegistryKey<ConfiguredStructureFeature<?, ?>> configuredStructureKey) {
-		create(configuredStructureKey.getValue()).add(ModificationPhase.ADDITIONS, biomeSelector, context -> {
-			context.getGenerationSettings().addStructure(configuredStructureKey);
-		});
-	}
-
 	/**
 	 * Convenience method to add a carver to one or more biomes.
 	 *
diff --git a/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/api/biome/v1/BiomeSelectionContext.java b/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/api/biome/v1/BiomeSelectionContext.java
index 277bcfee2..88a16f311 100644
--- a/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/api/biome/v1/BiomeSelectionContext.java
+++ b/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/api/biome/v1/BiomeSelectionContext.java
@@ -19,6 +19,7 @@ package net.fabricmc.fabric.api.biome.v1;
 import java.util.List;
 import java.util.Optional;
 
+import net.minecraft.tag.TagKey;
 import net.minecraft.util.registry.RegistryEntry;
 import net.minecraft.util.registry.RegistryEntryList;
 import net.minecraft.util.registry.RegistryKey;
@@ -41,6 +42,8 @@ public interface BiomeSelectionContext {
 	 */
 	Biome getBiome();
 
+	RegistryEntry<Biome> getBiomeRegistryEntry();
+
 	/**
 	 * Returns true if this biome has the given configured feature, which must be registered
 	 * in the {@link net.minecraft.util.registry.BuiltinRegistries}.
@@ -118,16 +121,16 @@ public interface BiomeSelectionContext {
 	 *
 	 * <p>This method is intended for use with the Vanilla configured structures found in {@link net.minecraft.world.gen.feature.ConfiguredStructureFeatures}.
 	 */
-	default boolean hasBuiltInStructure(ConfiguredStructureFeature<?, ?> configuredStructure) {
+	default boolean validForBuiltInStructure(ConfiguredStructureFeature<?, ?> configuredStructure) {
 		RegistryKey<ConfiguredStructureFeature<?, ?>> key = BuiltInRegistryKeys.get(configuredStructure);
-		return hasStructure(key);
+		return validForStructure(key);
 	}
 
 	/**
 	 * Returns true if the configured structure with the given key can start in this biome in any chunk generator
 	 * used by the current world-save.
 	 */
-	boolean hasStructure(RegistryKey<ConfiguredStructureFeature<?, ?>> key);
+	boolean validForStructure(RegistryKey<ConfiguredStructureFeature<?, ?>> key);
 
 	/**
 	 * Tries to retrieve the registry key for the given configured feature, which should be from this biomes
@@ -143,4 +146,9 @@ public interface BiomeSelectionContext {
 	 * <p>If no dimension options exist for the given dimension key, <code>false</code> is returned.
 	 */
 	boolean canGenerateIn(RegistryKey<DimensionOptions> dimensionKey);
+
+	/**
+	 * {@return true if this biome is in the given {@link TagKey}}.
+	 */
+	boolean hasTag(TagKey<Biome> tag);
 }
diff --git a/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/api/biome/v1/BiomeSelectors.java b/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/api/biome/v1/BiomeSelectors.java
index 0c46e16ff..f84c38f59 100644
--- a/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/api/biome/v1/BiomeSelectors.java
+++ b/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/api/biome/v1/BiomeSelectors.java
@@ -99,7 +99,7 @@ public final class BiomeSelectors {
 	 * @see net.fabricmc.fabric.api.tag.TagFactory#BIOME
 	 */
 	public static Predicate<BiomeSelectionContext> tag(TagKey<Biome> tag) {
-		return context -> BuiltinRegistries.BIOME.containsTag(tag);
+		return context -> context.hasTag(tag);
 	}
 
 	/**
diff --git a/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/impl/biome/NetherBiomeData.java b/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/impl/biome/NetherBiomeData.java
index b6b0e3ab0..1a11a5fda 100644
--- a/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/impl/biome/NetherBiomeData.java
+++ b/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/impl/biome/NetherBiomeData.java
@@ -60,7 +60,7 @@ public final class NetherBiomeData {
 		if (NETHER_BIOMES.isEmpty()) {
 			MultiNoiseBiomeSource source = MultiNoiseBiomeSource.Preset.NETHER.getBiomeSource(BuiltinRegistries.BIOME);
 
-			for (RegistryEntry<Biome> entry : source.getBiomes().toList()) {
+			for (RegistryEntry<Biome> entry : source.getBiomes()) {
 				BuiltinRegistries.BIOME.getKey(entry.value()).ifPresent(NETHER_BIOMES::add);
 			}
 		}
diff --git a/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/impl/biome/modification/BiomeModificationContextImpl.java b/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/impl/biome/modification/BiomeModificationContextImpl.java
index e63d18695..8c06b4b7a 100644
--- a/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/impl/biome/modification/BiomeModificationContextImpl.java
+++ b/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/impl/biome/modification/BiomeModificationContextImpl.java
@@ -55,7 +55,6 @@ import net.minecraft.world.gen.carver.ConfiguredCarver;
 import net.minecraft.world.gen.feature.ConfiguredStructureFeature;
 import net.minecraft.world.gen.feature.Feature;
 import net.minecraft.world.gen.feature.PlacedFeature;
-import net.minecraft.world.gen.feature.StructureFeature;
 
 import net.fabricmc.fabric.api.biome.v1.BiomeModificationContext;
 
@@ -322,25 +321,6 @@ public class BiomeModificationContextImpl implements BiomeModificationContext {
 			return false;
 		}
 
-		@Override
-		public void addStructure(RegistryKey<ConfiguredStructureFeature<?, ?>> configuredStructureKey) {
-			ConfiguredStructureFeature<?, ?> configuredStructure = structures.getOrThrow(configuredStructureKey);
-
-			BiomeStructureStartsImpl.addStart(registries, configuredStructure, biomeKey);
-		}
-
-		@Override
-		public boolean removeStructure(RegistryKey<ConfiguredStructureFeature<?, ?>> configuredStructureKey) {
-			ConfiguredStructureFeature<?, ?> configuredStructure = structures.getOrThrow(configuredStructureKey);
-
-			return BiomeStructureStartsImpl.removeStart(registries, configuredStructure, biomeKey);
-		}
-
-		@Override
-		public boolean removeStructure(StructureFeature<?> structure) {
-			return BiomeStructureStartsImpl.removeStructureStarts(registries, structure, biomeKey);
-		}
-
 		private <T> RegistryEntryList<T> plus(RegistryEntryList<T> values, RegistryEntry<T> entry) {
 			List<RegistryEntry<T>> list = new ArrayList<>(values.stream().toList());
 			list.add(entry);
diff --git a/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/impl/biome/modification/BiomeModificationImpl.java b/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/impl/biome/modification/BiomeModificationImpl.java
index 7801d0fe7..713a3a1e6 100644
--- a/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/impl/biome/modification/BiomeModificationImpl.java
+++ b/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/impl/biome/modification/BiomeModificationImpl.java
@@ -120,7 +120,7 @@ public class BiomeModificationImpl {
 
 		// Build a list of all biome keys in ascending order of their raw-id to get a consistent result in case
 		// someone does something stupid.
-		List<RegistryKey<Biome>> keys = biomes.getEntries().stream()
+		List<RegistryKey<Biome>> keys = biomes.getEntrySet().stream()
 				.map(Map.Entry::getKey)
 				.sorted(Comparator.comparingInt(key -> biomes.getRawId(biomes.getOrThrow(key))))
 				.toList();
@@ -170,7 +170,7 @@ public class BiomeModificationImpl {
 				BiomeSource biomeSource = dimension.getChunkGenerator().getBiomeSource();
 
 				// Replace the Supplier to force it to rebuild on next call
-				biomeSource.field_34469 = Suppliers.memoize(() -> {
+				biomeSource.indexedFeaturesSupplier = Suppliers.memoize(() -> {
 					return biomeSource.method_39525(biomeSource.biomes.stream().map(RegistryEntry::value).toList(), true);
 				});
 			}
diff --git a/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/impl/biome/modification/BiomeSelectionContextImpl.java b/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/impl/biome/modification/BiomeSelectionContextImpl.java
index 09046559e..ffd9462b5 100644
--- a/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/impl/biome/modification/BiomeSelectionContextImpl.java
+++ b/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/impl/biome/modification/BiomeSelectionContextImpl.java
@@ -20,12 +20,13 @@ import java.util.Optional;
 
 import org.jetbrains.annotations.ApiStatus;
 
+import net.minecraft.tag.TagKey;
 import net.minecraft.util.registry.DynamicRegistryManager;
 import net.minecraft.util.registry.Registry;
+import net.minecraft.util.registry.RegistryEntry;
 import net.minecraft.util.registry.RegistryKey;
 import net.minecraft.world.biome.Biome;
 import net.minecraft.world.dimension.DimensionOptions;
-import net.minecraft.world.gen.chunk.placement.StructuresConfig;
 import net.minecraft.world.gen.feature.ConfiguredFeature;
 import net.minecraft.world.gen.feature.ConfiguredStructureFeature;
 import net.minecraft.world.gen.feature.PlacedFeature;
@@ -39,12 +40,14 @@ public class BiomeSelectionContextImpl implements BiomeSelectionContext {
 	private final LevelProperties levelProperties;
 	private final RegistryKey<Biome> key;
 	private final Biome biome;
+	private final RegistryEntry<Biome> entry;
 
 	public BiomeSelectionContextImpl(DynamicRegistryManager dynamicRegistries, LevelProperties levelProperties, RegistryKey<Biome> key, Biome biome) {
 		this.dynamicRegistries = dynamicRegistries;
 		this.levelProperties = levelProperties;
 		this.key = key;
 		this.biome = biome;
+		this.entry = dynamicRegistries.get(Registry.BIOME_KEY).getEntry(this.key).orElseThrow();
 	}
 
 	@Override
@@ -57,6 +60,11 @@ public class BiomeSelectionContextImpl implements BiomeSelectionContext {
 		return biome;
 	}
 
+	@Override
+	public RegistryEntry<Biome> getBiomeRegistryEntry() {
+		return entry;
+	}
+
 	@Override
 	public Optional<RegistryKey<ConfiguredFeature<?, ?>>> getFeatureKey(ConfiguredFeature<?, ?> configuredFeature) {
 		Registry<ConfiguredFeature<?, ?>> registry = dynamicRegistries.get(Registry.CONFIGURED_FEATURE_KEY);
@@ -70,24 +78,14 @@ public class BiomeSelectionContextImpl implements BiomeSelectionContext {
 	}
 
 	@Override
-	public boolean hasStructure(RegistryKey<ConfiguredStructureFeature<?, ?>> key) {
+	public boolean validForStructure(RegistryKey<ConfiguredStructureFeature<?, ?>> key) {
 		ConfiguredStructureFeature<?, ?> instance = dynamicRegistries.get(Registry.CONFIGURED_STRUCTURE_FEATURE_KEY).get(key);
 
 		if (instance == null) {
 			return false;
 		}
 
-		// Since the biome->structure mapping is now stored in the chunk generator configuration, we check every
-		// chunk generator used by the current world-save.
-		for (DimensionOptions dimension : levelProperties.getGeneratorOptions().getDimensions()) {
-			StructuresConfig structuresConfig = dimension.getChunkGenerator().getStructuresConfig();
-
-			if (structuresConfig.getConfiguredStructureFeature(instance.feature).get(key).contains(getBiomeKey())) {
-				return true;
-			}
-		}
-
-		return false;
+		return instance.getBiomes().contains(getBiomeRegistryEntry());
 	}
 
 	@Override
@@ -104,6 +102,12 @@ public class BiomeSelectionContextImpl implements BiomeSelectionContext {
 			return false;
 		}
 
-		return dimension.getChunkGenerator().getBiomeSource().getBiomes().anyMatch(entry -> entry.value() == biome);
+		return dimension.getChunkGenerator().getBiomeSource().getBiomes().stream().anyMatch(entry -> entry.value() == biome);
+	}
+
+	@Override
+	public boolean hasTag(TagKey<Biome> tag) {
+		Registry<Biome> biomeRegistry = dynamicRegistries.get(Registry.BIOME_KEY);
+		return biomeRegistry.entryOf(getBiomeKey()).isIn(tag);
 	}
 }
diff --git a/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/impl/biome/modification/BiomeStructureStartsImpl.java b/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/impl/biome/modification/BiomeStructureStartsImpl.java
deleted file mode 100644
index 1c0851513..000000000
--- a/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/impl/biome/modification/BiomeStructureStartsImpl.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (c) 2016, 2017, 2018, 2019 FabricMC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.fabricmc.fabric.impl.biome.modification;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.function.Consumer;
-
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableMultimap;
-import com.google.common.collect.Multimap;
-import org.jetbrains.annotations.ApiStatus;
-
-import net.minecraft.util.registry.BuiltinRegistries;
-import net.minecraft.util.registry.DynamicRegistryManager;
-import net.minecraft.util.registry.Registry;
-import net.minecraft.util.registry.RegistryKey;
-import net.minecraft.world.biome.Biome;
-import net.minecraft.world.gen.chunk.ChunkGeneratorSettings;
-import net.minecraft.world.gen.feature.ConfiguredStructureFeature;
-import net.minecraft.world.gen.feature.StructureFeature;
-
-/**
- * Helps with modifying the structure start information stored in {@link ChunkGeneratorSettings}.
- */
-@ApiStatus.Internal
-public final class BiomeStructureStartsImpl {
-	private BiomeStructureStartsImpl() {
-	}
-
-	public static void addStart(
-			DynamicRegistryManager registries,
-			ConfiguredStructureFeature<?, ?> configuredStructure,
-			RegistryKey<Biome> biome
-	) {
-		changeStructureStarts(registries, structureMap -> {
-			Multimap<RegistryKey<ConfiguredStructureFeature<?, ?>>, RegistryKey<Biome>> configuredMap = structureMap.computeIfAbsent(configuredStructure.feature, k -> HashMultimap.create());
-
-			// This is tricky, the keys might be either from builtin (Vanilla) or dynamic registries (modded)
-			RegistryKey<ConfiguredStructureFeature<?, ?>> configuredStructureKey = registries.get(Registry.CONFIGURED_STRUCTURE_FEATURE_KEY).getKey(configuredStructure).orElseThrow();
-			RegistryKey<ConfiguredStructureFeature<?, ?>> mapKey = registries.get(Registry.CONFIGURED_STRUCTURE_FEATURE_KEY).getKey(configuredStructure)
-					.orElse(configuredStructureKey);
-
-			// orElse means the configured structure passed in is not a (potentially modified) Vanilla entry,
-			// but rather a modded one. In this case, this will create a new entry in the map.
-			configuredMap.put(mapKey, biome);
-		});
-	}
-
-	public static boolean removeStart(
-			DynamicRegistryManager registries,
-			ConfiguredStructureFeature<?, ?> configuredStructure,
-			RegistryKey<Biome> biome
-	) {
-		AtomicBoolean result = new AtomicBoolean(false);
-
-		changeStructureStarts(registries, structureMap -> {
-			Multimap<RegistryKey<ConfiguredStructureFeature<?, ?>>, RegistryKey<Biome>> configuredMap = structureMap.get(configuredStructure.feature);
-
-			if (configuredMap == null) {
-				return;
-			}
-
-			// This is tricky, the keys might be either from builtin (Vanilla) or dynamic registries (modded)
-			RegistryKey<ConfiguredStructureFeature<?, ?>> configuredStructureKey = registries.get(Registry.CONFIGURED_STRUCTURE_FEATURE_KEY).getKey(configuredStructure).orElseThrow();
-			ConfiguredStructureFeature<?, ?> mapKey = BuiltinRegistries.CONFIGURED_STRUCTURE_FEATURE.get(configuredStructureKey);
-
-			if (mapKey == null) {
-				// This means the configured structure passed in is not a (potentially modified) Vanilla entry,
-				// but rather a modded one. In this case, this will create a new entry in the map.
-				mapKey = configuredStructure;
-			}
-
-			if (configuredMap.remove(mapKey, biome)) {
-				result.set(true);
-			}
-		});
-
-		return result.get();
-	}
-
-	public static boolean removeStructureStarts(
-			DynamicRegistryManager registries,
-			StructureFeature<?> structure,
-			RegistryKey<Biome> biome
-	) {
-		AtomicBoolean result = new AtomicBoolean(false);
-
-		changeStructureStarts(registries, structureMap -> {
-			Multimap<RegistryKey<ConfiguredStructureFeature<?, ?>>, RegistryKey<Biome>> configuredMap = structureMap.get(structure);
-
-			if (configuredMap == null) {
-				return;
-			}
-
-			if (configuredMap.values().remove(biome)) {
-				result.set(true);
-			}
-		});
-
-		return result.get();
-	}
-
-	private static void changeStructureStarts(DynamicRegistryManager registries, Consumer<Map<StructureFeature<?>, Multimap<RegistryKey<ConfiguredStructureFeature<?, ?>>, RegistryKey<Biome>>>> modifier) {
-		Registry<ChunkGeneratorSettings> chunkGenSettingsRegistry = registries.get(Registry.CHUNK_GENERATOR_SETTINGS_KEY);
-
-		for (Map.Entry<RegistryKey<ChunkGeneratorSettings>, ChunkGeneratorSettings> entry : chunkGenSettingsRegistry.getEntries()) {
-			Map<StructureFeature<?>, Multimap<RegistryKey<ConfiguredStructureFeature<?, ?>>, RegistryKey<Biome>>> structureMap = unfreeze(entry.getValue());
-
-			modifier.accept(structureMap);
-
-			freeze(entry.getValue(), structureMap);
-		}
-	}
-
-	private static Map<StructureFeature<?>, Multimap<RegistryKey<ConfiguredStructureFeature<?, ?>>, RegistryKey<Biome>>> unfreeze(ChunkGeneratorSettings settings) {
-		ImmutableMap<StructureFeature<?>, ImmutableMultimap<RegistryKey<ConfiguredStructureFeature<?, ?>>, RegistryKey<Biome>>> frozenMap = settings.getStructuresConfig().configuredStructures;
-		Map<StructureFeature<?>, Multimap<RegistryKey<ConfiguredStructureFeature<?, ?>>, RegistryKey<Biome>>> result = new HashMap<>(frozenMap.size());
-
-		for (Map.Entry<StructureFeature<?>, ImmutableMultimap<RegistryKey<ConfiguredStructureFeature<?, ?>>, RegistryKey<Biome>>> entry : frozenMap.entrySet()) {
-			result.put(entry.getKey(), HashMultimap.create(entry.getValue()));
-		}
-
-		return result;
-	}
-
-	private static void freeze(ChunkGeneratorSettings settings, Map<StructureFeature<?>, Multimap<RegistryKey<ConfiguredStructureFeature<?, ?>>, RegistryKey<Biome>>> structureStarts) {
-		settings.getStructuresConfig().configuredStructures = structureStarts.entrySet().stream()
-				.collect(ImmutableMap.toImmutableMap(
-						Map.Entry::getKey,
-						e -> ImmutableMultimap.copyOf(e.getValue())
-				));
-	}
-}
diff --git a/fabric-biome-api-v1/src/main/resources/fabric-biome-api-v1.accesswidener b/fabric-biome-api-v1/src/main/resources/fabric-biome-api-v1.accesswidener
index 242b856e8..869660a35 100644
--- a/fabric-biome-api-v1/src/main/resources/fabric-biome-api-v1.accesswidener
+++ b/fabric-biome-api-v1/src/main/resources/fabric-biome-api-v1.accesswidener
@@ -4,8 +4,8 @@ accessible  class   net/minecraft/world/biome/Biome$Weather
 # Rebuilding biome source feature lists
 accessible method net/minecraft/world/biome/source/BiomeSource method_39525 (Ljava/util/List;Z)Ljava/util/List;
 accessible field net/minecraft/world/biome/source/BiomeSource biomes Ljava/util/Set;
-accessible field net/minecraft/world/biome/source/BiomeSource field_34469 Ljava/util/function/Supplier;
-mutable field net/minecraft/world/biome/source/BiomeSource field_34469 Ljava/util/function/Supplier;
+accessible field net/minecraft/world/biome/source/BiomeSource indexedFeaturesSupplier Ljava/util/function/Supplier;
+mutable field net/minecraft/world/biome/source/BiomeSource indexedFeaturesSupplier Ljava/util/function/Supplier;
 
 # Top-Level Biome Fields Access
 accessible field net/minecraft/world/biome/Biome weather Lnet/minecraft/world/biome/Biome$Weather;
diff --git a/fabric-biome-api-v1/src/testmod/java/net/fabricmc/fabric/test/biome/FabricBiomeTest.java b/fabric-biome-api-v1/src/testmod/java/net/fabricmc/fabric/test/biome/FabricBiomeTest.java
index 488c87342..b1f3f3879 100644
--- a/fabric-biome-api-v1/src/testmod/java/net/fabricmc/fabric/test/biome/FabricBiomeTest.java
+++ b/fabric-biome-api-v1/src/testmod/java/net/fabricmc/fabric/test/biome/FabricBiomeTest.java
@@ -83,14 +83,6 @@ public class FabricBiomeTest implements ModInitializer {
 		Registry.register(BuiltinRegistries.BIOME, TEST_END_MIDLANDS.getValue(), createEndMidlands());
 		Registry.register(BuiltinRegistries.BIOME, TEST_END_BARRRENS.getValue(), createEndBarrens());
 
-		BiomeModifications.create(new Identifier("fabric:end_test_structures"))
-				.add(ModificationPhase.ADDITIONS, BiomeSelectors.includeByKey(TEST_END_HIGHLANDS, TEST_END_MIDLANDS), ctx -> {
-					ctx.getGenerationSettings().addStructure(RegistryKey.of(Registry.CONFIGURED_STRUCTURE_FEATURE_KEY, new Identifier("end_city")));
-				})
-				.add(ModificationPhase.ADDITIONS, BiomeSelectors.includeByKey(BiomeKeys.PLAINS), ctx -> {
-					ctx.getGenerationSettings().addStructure(RegistryKey.of(Registry.CONFIGURED_STRUCTURE_FEATURE_KEY, new Identifier("end_city")));
-				});
-
 		// TESTING HINT: to get to the end:
 		// /execute in minecraft:the_end run tp @s 0 90 0
 		TheEndBiomes.addHighlandsBiome(TEST_END_HIGHLANDS, 5.0);
@@ -117,7 +109,7 @@ public class FabricBiomeTest implements ModInitializer {
 							);
 						})
 				.add(ModificationPhase.ADDITIONS,
-						BiomeSelectors.tag(TagKey.intern(Registry.BIOME_KEY, new Identifier(MOD_ID, "tag_selector_test"))),
+						BiomeSelectors.tag(TagKey.of(Registry.BIOME_KEY, new Identifier(MOD_ID, "tag_selector_test"))),
 						context -> context.getEffects().setSkyColor(0x770000));
 	}
 
diff --git a/settings.gradle b/settings.gradle
index 81f3177c1..ea427c28e 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -14,7 +14,7 @@ rootProject.name = "fabric-api"
 include 'fabric-api-base'
 
 include 'fabric-api-lookup-api-v1'
-//include 'fabric-biome-api-v1'
+include 'fabric-biome-api-v1'
 include 'fabric-blockrenderlayer-v1'
 include 'fabric-commands-v0'
 include 'fabric-command-api-v1'