diff --git a/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/mixin/biome/TheEndBiomeSourceMixin.java b/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/mixin/biome/TheEndBiomeSourceMixin.java
index 24221979d..35270e000 100644
--- a/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/mixin/biome/TheEndBiomeSourceMixin.java
+++ b/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/mixin/biome/TheEndBiomeSourceMixin.java
@@ -22,7 +22,7 @@ import java.util.Set;
 import java.util.function.Supplier;
 
 import com.google.common.base.Suppliers;
-import com.mojang.serialization.Codec;
+import com.mojang.serialization.MapCodec;
 import com.mojang.serialization.codecs.RecordCodecBuilder;
 import org.spongepowered.asm.mixin.Final;
 import org.spongepowered.asm.mixin.Mixin;
@@ -49,7 +49,7 @@ public class TheEndBiomeSourceMixin extends BiomeSourceMixin {
 	@Shadow
 	@Mutable
 	@Final
-	static Codec<TheEndBiomeSource> CODEC;
+	static MapCodec<TheEndBiomeSource> CODEC;
 
 	@Unique
 	private Supplier<TheEndBiomeData.Overrides> overrides;
@@ -66,7 +66,7 @@ public class TheEndBiomeSourceMixin extends BiomeSourceMixin {
 	 */
 	@Inject(method = "<clinit>", at = @At("TAIL"))
 	private static void modifyCodec(CallbackInfo ci) {
-		CODEC = RecordCodecBuilder.create((instance) -> {
+		CODEC = RecordCodecBuilder.mapCodec((instance) -> {
 			return instance.group(RegistryOps.getEntryLookupCodec(RegistryKeys.BIOME)).apply(instance, instance.stable(TheEndBiomeSource::createVanilla));
 		});
 	}
diff --git a/fabric-convention-tags-v1/src/generated/resources/data/c/tags/items/foods.json b/fabric-convention-tags-v1/src/generated/resources/data/c/tags/items/foods.json
index 59bcc58a6..652d8b713 100644
--- a/fabric-convention-tags-v1/src/generated/resources/data/c/tags/items/foods.json
+++ b/fabric-convention-tags-v1/src/generated/resources/data/c/tags/items/foods.json
@@ -39,6 +39,7 @@
     "minecraft:suspicious_stew",
     "minecraft:sweet_berries",
     "minecraft:glow_berries",
-    "minecraft:honey_bottle"
+    "minecraft:honey_bottle",
+    "minecraft:ominous_bottle"
   ]
 }
\ No newline at end of file
diff --git a/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/impl/attachment/AttachmentSerializingImpl.java b/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/impl/attachment/AttachmentSerializingImpl.java
index aceec0eb0..25de7b490 100644
--- a/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/impl/attachment/AttachmentSerializingImpl.java
+++ b/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/impl/attachment/AttachmentSerializingImpl.java
@@ -52,12 +52,11 @@ public class AttachmentSerializingImpl {
 			if (codec != null) {
 				RegistryOps<NbtElement> registryOps = wrapperLookup.getOps(NbtOps.INSTANCE);
 				codec.encodeStart(registryOps, entry.getValue())
-						.get()
-						.ifRight(partial -> {
+						.ifError(partial -> {
 							LOGGER.warn("Couldn't serialize attachment " + type.identifier() + ", skipping. Error:");
 							LOGGER.warn(partial.message());
 						})
-						.ifLeft(serialized -> compound.put(type.identifier().toString(), serialized));
+						.ifSuccess(serialized -> compound.put(type.identifier().toString(), serialized));
 			}
 		}
 
@@ -83,12 +82,11 @@ public class AttachmentSerializingImpl {
 				if (codec != null) {
 					RegistryOps<NbtElement> registryOps = wrapperLookup.getOps(NbtOps.INSTANCE);
 					codec.parse(registryOps, compound.get(key))
-							.get()
-							.ifRight(partial -> {
+							.ifError(partial -> {
 								LOGGER.warn("Couldn't deserialize attachment " + type.identifier() + ", skipping. Error:");
 								LOGGER.warn(partial.message());
 							})
-							.ifLeft(
+							.ifSuccess(
 									deserialized -> attachments.put(type, deserialized)
 							);
 				}
diff --git a/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/BlockEntityMixin.java b/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/BlockEntityMixin.java
index bc9dfd2fc..d5f010118 100644
--- a/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/BlockEntityMixin.java
+++ b/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/BlockEntityMixin.java
@@ -31,7 +31,7 @@ import net.fabricmc.fabric.impl.attachment.AttachmentTargetImpl;
 abstract class BlockEntityMixin implements AttachmentTargetImpl {
 	@Inject(
 			method = "method_17897", // lambda body in BlockEntity#createFromNbt
-			at = @At(value = "INVOKE", target = "Lnet/minecraft/block/entity/BlockEntity;readNbt(Lnet/minecraft/nbt/NbtCompound;Lnet/minecraft/registry/RegistryWrapper$WrapperLookup;)V")
+			at = @At(value = "INVOKE", target = "Lnet/minecraft/block/entity/BlockEntity;method_58690(Lnet/minecraft/nbt/NbtCompound;Lnet/minecraft/registry/RegistryWrapper$WrapperLookup;)V")
 	)
 	private static void readBlockEntityAttachments(NbtCompound nbt, RegistryWrapper.WrapperLookup wrapperLookup, String string, BlockEntity blockEntity, CallbackInfoReturnable<BlockEntity> cir) {
 		((AttachmentTargetImpl) blockEntity).fabric_readAttachmentsFromNbt(nbt, wrapperLookup);
diff --git a/fabric-data-generation-api-v1/src/main/java/net/fabricmc/fabric/api/datagen/v1/provider/FabricAdvancementProvider.java b/fabric-data-generation-api-v1/src/main/java/net/fabricmc/fabric/api/datagen/v1/provider/FabricAdvancementProvider.java
index 971704244..df99e8183 100644
--- a/fabric-data-generation-api-v1/src/main/java/net/fabricmc/fabric/api/datagen/v1/provider/FabricAdvancementProvider.java
+++ b/fabric-data-generation-api-v1/src/main/java/net/fabricmc/fabric/api/datagen/v1/provider/FabricAdvancementProvider.java
@@ -37,7 +37,6 @@ import net.minecraft.data.DataWriter;
 import net.minecraft.registry.RegistryOps;
 import net.minecraft.registry.RegistryWrapper;
 import net.minecraft.util.Identifier;
-import net.minecraft.util.Util;
 
 import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator;
 import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
@@ -94,7 +93,7 @@ public abstract class FabricAdvancementProvider implements DataProvider {
 					throw new IllegalStateException("Duplicate advancement " + advancement.id());
 				}
 
-				JsonObject advancementJson = Util.getResult(Advancement.CODEC.encodeStart(ops, advancement.value()), IllegalStateException::new).getAsJsonObject();
+				JsonObject advancementJson = Advancement.CODEC.encodeStart(ops, advancement.value()).getOrThrow(IllegalStateException::new).getAsJsonObject();
 				ConditionJsonProvider.write(advancementJson, FabricDataGenHelper.consumeConditions(advancement));
 				futures.add(DataProvider.writeToPath(writer, advancementJson, getOutputPath(advancement)));
 			}
diff --git a/fabric-data-generation-api-v1/src/main/java/net/fabricmc/fabric/api/datagen/v1/provider/FabricCodecDataProvider.java b/fabric-data-generation-api-v1/src/main/java/net/fabricmc/fabric/api/datagen/v1/provider/FabricCodecDataProvider.java
index b44b14f24..638465a8f 100644
--- a/fabric-data-generation-api-v1/src/main/java/net/fabricmc/fabric/api/datagen/v1/provider/FabricCodecDataProvider.java
+++ b/fabric-data-generation-api-v1/src/main/java/net/fabricmc/fabric/api/datagen/v1/provider/FabricCodecDataProvider.java
@@ -84,9 +84,9 @@ public abstract class FabricCodecDataProvider<T> implements DataProvider {
 
 	private JsonElement convert(Identifier id, T value, DynamicOps<JsonElement> ops) {
 		DataResult<JsonElement> dataResult = this.codec.encodeStart(ops, value);
-		return dataResult.get()
-				.mapRight(partial -> "Invalid entry %s: %s".formatted(id, partial.message()))
-				.orThrow();
+		return dataResult
+				.mapError(message -> "Invalid entry %s: %s".formatted(id, message))
+				.getOrThrow();
 	}
 
 	private CompletableFuture<?> write(DataWriter writer, Map<Identifier, JsonElement> entries) {
diff --git a/fabric-data-generation-api-v1/src/main/java/net/fabricmc/fabric/api/datagen/v1/provider/FabricRecipeProvider.java b/fabric-data-generation-api-v1/src/main/java/net/fabricmc/fabric/api/datagen/v1/provider/FabricRecipeProvider.java
index b2fc005d9..08d8919d0 100644
--- a/fabric-data-generation-api-v1/src/main/java/net/fabricmc/fabric/api/datagen/v1/provider/FabricRecipeProvider.java
+++ b/fabric-data-generation-api-v1/src/main/java/net/fabricmc/fabric/api/datagen/v1/provider/FabricRecipeProvider.java
@@ -41,7 +41,6 @@ import net.minecraft.recipe.Recipe;
 import net.minecraft.registry.RegistryOps;
 import net.minecraft.registry.RegistryWrapper;
 import net.minecraft.util.Identifier;
-import net.minecraft.util.Util;
 
 import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator;
 import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
@@ -100,14 +99,14 @@ public abstract class FabricRecipeProvider extends RecipeProvider {
 				}
 
 				RegistryOps<JsonElement> registryOps = wrapperLookup.getOps(JsonOps.INSTANCE);
-				JsonObject recipeJson = Util.getResult(Recipe.CODEC.encodeStart(registryOps, recipe), IllegalStateException::new).getAsJsonObject();
+				JsonObject recipeJson = Recipe.CODEC.encodeStart(registryOps, recipe).getOrThrow(IllegalStateException::new).getAsJsonObject();
 				ConditionJsonProvider[] conditions = FabricDataGenHelper.consumeConditions(recipe);
 				ConditionJsonProvider.write(recipeJson, conditions);
 
 				list.add(DataProvider.writeToPath(writer, recipeJson, recipesPathResolver.resolveJson(identifier)));
 
 				if (advancement != null) {
-					JsonObject advancementJson = Util.getResult(Advancement.CODEC.encodeStart(registryOps, advancement.value()), IllegalStateException::new).getAsJsonObject();
+					JsonObject advancementJson = Advancement.CODEC.encodeStart(registryOps, advancement.value()).getOrThrow(IllegalStateException::new).getAsJsonObject();
 					ConditionJsonProvider.write(advancementJson, conditions);
 					list.add(DataProvider.writeToPath(writer, advancementJson, advancementsPathResolver.resolveJson(getRecipeIdentifier(advancement.id()))));
 				}
diff --git a/fabric-data-generation-api-v1/src/main/java/net/fabricmc/fabric/impl/datagen/loot/FabricLootTableProviderImpl.java b/fabric-data-generation-api-v1/src/main/java/net/fabricmc/fabric/impl/datagen/loot/FabricLootTableProviderImpl.java
index 8c72e7da9..2e425eda8 100644
--- a/fabric-data-generation-api-v1/src/main/java/net/fabricmc/fabric/impl/datagen/loot/FabricLootTableProviderImpl.java
+++ b/fabric-data-generation-api-v1/src/main/java/net/fabricmc/fabric/impl/datagen/loot/FabricLootTableProviderImpl.java
@@ -36,7 +36,6 @@ import net.minecraft.loot.context.LootContextType;
 import net.minecraft.registry.RegistryOps;
 import net.minecraft.registry.RegistryWrapper;
 import net.minecraft.util.Identifier;
-import net.minecraft.util.Util;
 
 import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
 import net.fabricmc.fabric.api.datagen.v1.provider.FabricBlockLootTableProvider;
@@ -72,7 +71,7 @@ public final class FabricLootTableProviderImpl {
 			final List<CompletableFuture<?>> futures = new ArrayList<>();
 
 			for (Map.Entry<Identifier, LootTable> entry : builders.entrySet()) {
-				JsonObject tableJson = (JsonObject) Util.getResult(LootTable.CODEC.encodeStart(ops, entry.getValue()), IllegalStateException::new);
+				JsonObject tableJson = (JsonObject) LootTable.CODEC.encodeStart(ops, entry.getValue()).getOrThrow(IllegalStateException::new);
 				ConditionJsonProvider.write(tableJson, conditionMap.remove(entry.getKey()));
 				futures.add(DataProvider.writeToPath(writer, tableJson, getOutputPath(fabricDataOutput, entry.getKey())));
 			}
diff --git a/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/impl/dimension/FailSoftMapCodec.java b/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/impl/dimension/FailSoftMapCodec.java
index ae46760aa..949dd1cf3 100644
--- a/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/impl/dimension/FailSoftMapCodec.java
+++ b/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/impl/dimension/FailSoftMapCodec.java
@@ -17,6 +17,7 @@
 package net.fabricmc.fabric.impl.dimension;
 
 import java.util.Map;
+import java.util.Optional;
 
 import com.google.common.collect.ImmutableMap;
 import com.mojang.datafixers.util.Pair;
@@ -65,15 +66,19 @@ public record FailSoftMapCodec<K, V>(Codec<K> keyCodec, Codec<V> elementCodec) i
 				final DataResult<K> k = keyCodec().parse(ops, pair.getFirst());
 				final DataResult<V> v = elementCodec().parse(ops, pair.getSecond());
 
-				k.get().ifRight(kPartialResult -> {
-					LOGGER.error("Failed to decode key {} from {}  {}", k, pair, kPartialResult);
-				});
-				v.get().ifRight(vPartialResult -> {
-					LOGGER.error("Failed to decode value {} from {}  {}", v, pair, vPartialResult);
-				});
+				Optional<K> optionalK = k.result();
+				Optional<V> optionalV = v.result();
 
-				if (k.get().left().isPresent() && v.get().left().isPresent()) {
-					builder.put(k.get().left().get(), v.get().left().get());
+				if (optionalK.isEmpty()) {
+					LOGGER.error("Failed to decode key {} from {}  {}", k, pair, k.resultOrPartial());
+				}
+
+				if (optionalV.isEmpty()) {
+					LOGGER.error("Failed to decode value {} from {}  {}", k, pair, v.resultOrPartial());
+				}
+
+				if (optionalK.isPresent() && optionalV.isPresent()) {
+					builder.put(optionalK.get(), optionalV.get());
 				} else {
 					// ignore failure
 				}
diff --git a/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/TaggedChoiceTypeMixin.java b/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/TaggedChoiceTypeMixin.java
index f0339e408..1900f3af7 100644
--- a/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/TaggedChoiceTypeMixin.java
+++ b/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/TaggedChoiceTypeMixin.java
@@ -51,7 +51,7 @@ public class TaggedChoiceTypeMixin<K> implements TaggedChoiceTypeExtension {
 	 * This will avoid deserialization failure from DFU when upgrading level.dat that contains mod custom generator types.
 	 */
 	@Inject(
-			method = "getCodec", at = @At("HEAD"), cancellable = true, remap = false
+			method = "getMapCodec", at = @At("HEAD"), cancellable = true, remap = false
 	)
 	private void onGetCodec(K k, CallbackInfoReturnable<DataResult<? extends Codec<?>>> cir) {
 		if (failSoft) {
diff --git a/fabric-dimensions-v1/src/testmod/java/net/fabricmc/fabric/test/dimension/VoidChunkGenerator.java b/fabric-dimensions-v1/src/testmod/java/net/fabricmc/fabric/test/dimension/VoidChunkGenerator.java
index 1c04554e4..0e0557051 100644
--- a/fabric-dimensions-v1/src/testmod/java/net/fabricmc/fabric/test/dimension/VoidChunkGenerator.java
+++ b/fabric-dimensions-v1/src/testmod/java/net/fabricmc/fabric/test/dimension/VoidChunkGenerator.java
@@ -20,7 +20,7 @@ import java.util.List;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.Executor;
 
-import com.mojang.serialization.Codec;
+import com.mojang.serialization.MapCodec;
 import com.mojang.serialization.codecs.RecordCodecBuilder;
 
 import net.minecraft.block.BlockState;
@@ -44,7 +44,7 @@ import net.minecraft.world.gen.chunk.VerticalBlockSample;
 import net.minecraft.world.gen.noise.NoiseConfig;
 
 public class VoidChunkGenerator extends ChunkGenerator {
-	public static final Codec<VoidChunkGenerator> CODEC = RecordCodecBuilder.create((instance) ->
+	public static final MapCodec<VoidChunkGenerator> CODEC = RecordCodecBuilder.mapCodec((instance) ->
 			instance.group(RegistryOps.getEntryLookupCodec(RegistryKeys.BIOME))
 					.apply(instance, instance.stable(VoidChunkGenerator::new)));
 
@@ -53,7 +53,7 @@ public class VoidChunkGenerator extends ChunkGenerator {
 	}
 
 	@Override
-	protected Codec<? extends ChunkGenerator> getCodec() {
+	protected MapCodec<? extends ChunkGenerator> getCodec() {
 		return CODEC;
 	}
 
diff --git a/fabric-loot-api-v2/src/testmod/java/net/fabricmc/fabric/test/loot/LootTest.java b/fabric-loot-api-v2/src/testmod/java/net/fabricmc/fabric/test/loot/LootTest.java
index 113d9c913..febaa4795 100644
--- a/fabric-loot-api-v2/src/testmod/java/net/fabricmc/fabric/test/loot/LootTest.java
+++ b/fabric-loot-api-v2/src/testmod/java/net/fabricmc/fabric/test/loot/LootTest.java
@@ -75,7 +75,7 @@ public class LootTest implements ModInitializer {
 				LootPool pool = LootPool.builder()
 						.with(ItemEntry.builder(Items.GOLD_INGOT).build())
 						.conditionally(SurvivesExplosionLootCondition.builder().build())
-						.apply(SetNameLootFunction.builder(Text.literal("Gold from White Wool")).build())
+						.apply(SetNameLootFunction.builder(Text.literal("Gold from White Wool"), SetNameLootFunction.class_9475.CUSTOM_NAME).build())
 						.build();
 
 				tableBuilder.pool(pool);
diff --git a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/FabricEntityTypeBuilder.java b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/FabricEntityTypeBuilder.java
index 5805935da..d8d1b02f4 100644
--- a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/FabricEntityTypeBuilder.java
+++ b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/FabricEntityTypeBuilder.java
@@ -275,7 +275,8 @@ public class FabricEntityTypeBuilder<T extends Entity> {
 	public EntityType<T> build() {
 		// Modded DFU is a dream, currently not possible without screwing it up.
 
-		return new FabricEntityType<>(this.factory, this.spawnGroup, this.saveable, this.summonable, this.fireImmune, this.spawnableFarFromPlayer, this.specificSpawnBlocks, dimensions, trackRange, trackedUpdateRate, forceTrackedVelocityUpdates, this.requiredFeatures);
+		//TODO 1.20.5, new field
+		return new FabricEntityType<>(this.factory, this.spawnGroup, this.saveable, this.summonable, this.fireImmune, this.spawnableFarFromPlayer, this.specificSpawnBlocks, dimensions, 1, trackRange, trackedUpdateRate, forceTrackedVelocityUpdates, this.requiredFeatures);
 	}
 
 	/**
diff --git a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/impl/object/builder/FabricEntityType.java b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/impl/object/builder/FabricEntityType.java
index c76c8e721..dde18eec8 100644
--- a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/impl/object/builder/FabricEntityType.java
+++ b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/impl/object/builder/FabricEntityType.java
@@ -28,8 +28,8 @@ import net.minecraft.resource.featuretoggle.FeatureSet;
 public class FabricEntityType<T extends Entity> extends EntityType<T> {
 	private final Boolean alwaysUpdateVelocity;
 
-	public FabricEntityType(EntityType.EntityFactory<T> factory, SpawnGroup spawnGroup, boolean bl, boolean summonable, boolean fireImmune, boolean spawnableFarFromPlayer, ImmutableSet<Block> spawnBlocks, EntityDimensions entityDimensions, int maxTrackDistance, int trackTickInterval, Boolean alwaysUpdateVelocity, FeatureSet featureSet) {
-		super(factory, spawnGroup, bl, summonable, fireImmune, spawnableFarFromPlayer, spawnBlocks, entityDimensions, maxTrackDistance, trackTickInterval, featureSet);
+	public FabricEntityType(EntityType.EntityFactory<T> factory, SpawnGroup spawnGroup, boolean bl, boolean summonable, boolean fireImmune, boolean spawnableFarFromPlayer, ImmutableSet<Block> spawnBlocks, EntityDimensions entityDimensions, float field_50125, int maxTrackDistance, int trackTickInterval, Boolean alwaysUpdateVelocity, FeatureSet featureSet) {
+		super(factory, spawnGroup, bl, summonable, fireImmune, spawnableFarFromPlayer, spawnBlocks, entityDimensions, field_50125, maxTrackDistance, trackTickInterval, featureSet);
 		this.alwaysUpdateVelocity = alwaysUpdateVelocity;
 	}
 
diff --git a/fabric-particles-v1/src/main/java/net/fabricmc/fabric/api/particle/v1/FabricParticleTypes.java b/fabric-particles-v1/src/main/java/net/fabricmc/fabric/api/particle/v1/FabricParticleTypes.java
index 71a33d3d7..e6258ecca 100644
--- a/fabric-particles-v1/src/main/java/net/fabricmc/fabric/api/particle/v1/FabricParticleTypes.java
+++ b/fabric-particles-v1/src/main/java/net/fabricmc/fabric/api/particle/v1/FabricParticleTypes.java
@@ -19,6 +19,7 @@ package net.fabricmc.fabric.api.particle.v1;
 import java.util.function.Function;
 
 import com.mojang.serialization.Codec;
+import com.mojang.serialization.MapCodec;
 
 import net.minecraft.network.RegistryByteBuf;
 import net.minecraft.network.codec.PacketCodec;
@@ -69,7 +70,7 @@ public final class FabricParticleTypes {
 	 * @param codec The codec for serialization.
 	 * @param packetCodec The packet codec for network serialization.
 	 */
-	public static <T extends ParticleEffect> ParticleType<T> complex(ParticleEffect.Factory<T> factory, final Function<ParticleType<T>, Codec<T>> codecGetter, final Codec<T> codec, final PacketCodec<? super RegistryByteBuf, T> packetCodec) {
+	public static <T extends ParticleEffect> ParticleType<T> complex(ParticleEffect.Factory<T> factory, final Function<ParticleType<T>, Codec<T>> codecGetter, final MapCodec<T> codec, final PacketCodec<? super RegistryByteBuf, T> packetCodec) {
 		return complex(false, factory, codec, packetCodec);
 	}
 
@@ -81,10 +82,10 @@ public final class FabricParticleTypes {
 	 * @param codec The codec for serialization.
 	 * @param packetCodec The packet codec for network serialization.
 	 */
-	public static <T extends ParticleEffect> ParticleType<T> complex(boolean alwaysSpawn, ParticleEffect.Factory<T> factory, final Codec<T> codec, final PacketCodec<? super RegistryByteBuf, T> packetCodec) {
+	public static <T extends ParticleEffect> ParticleType<T> complex(boolean alwaysSpawn, ParticleEffect.Factory<T> factory, final MapCodec<T> codec, final PacketCodec<? super RegistryByteBuf, T> packetCodec) {
 		return new ParticleType<T>(alwaysSpawn, factory) {
 			@Override
-			public Codec<T> getCodec() {
+			public MapCodec<T> getCodec() {
 				return codec;
 			}
 
@@ -103,7 +104,7 @@ public final class FabricParticleTypes {
 	 * @param codecGetter A function that, given the newly created type, returns the codec for serialization.
 	 * @param packetCodecGetter A function that, given the newly created type, returns the packet codec for network serialization.
 	 */
-	public static <T extends ParticleEffect> ParticleType<T> complex(ParticleEffect.Factory<T> factory, final Function<ParticleType<T>, Codec<T>> codecGetter, final Function<ParticleType<T>, PacketCodec<? super RegistryByteBuf, T>> packetCodecGetter) {
+	public static <T extends ParticleEffect> ParticleType<T> complex(ParticleEffect.Factory<T> factory, final Function<ParticleType<T>, MapCodec<T>> codecGetter, final Function<ParticleType<T>, PacketCodec<? super RegistryByteBuf, T>> packetCodecGetter) {
 		return complex(false, factory, codecGetter, packetCodecGetter);
 	}
 
@@ -116,10 +117,10 @@ public final class FabricParticleTypes {
 	 * @param codecGetter A function that, given the newly created type, returns the codec for serialization.
 	 * @param packetCodecGetter A function that, given the newly created type, returns the packet codec for network serialization.
 	 */
-	public static <T extends ParticleEffect> ParticleType<T> complex(boolean alwaysSpawn, ParticleEffect.Factory<T> factory, final Function<ParticleType<T>, Codec<T>> codecGetter, final Function<ParticleType<T>, PacketCodec<? super RegistryByteBuf, T>> packetCodecGetter) {
+	public static <T extends ParticleEffect> ParticleType<T> complex(boolean alwaysSpawn, ParticleEffect.Factory<T> factory, final Function<ParticleType<T>, MapCodec<T>> codecGetter, final Function<ParticleType<T>, PacketCodec<? super RegistryByteBuf, T>> packetCodecGetter) {
 		return new ParticleType<T>(alwaysSpawn, factory) {
 			@Override
-			public Codec<T> getCodec() {
+			public MapCodec<T> getCodec() {
 				return codecGetter.apply(this);
 			}
 
diff --git a/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/api/recipe/v1/ingredient/CustomIngredientSerializer.java b/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/api/recipe/v1/ingredient/CustomIngredientSerializer.java
index bc6664d04..8347d032d 100644
--- a/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/api/recipe/v1/ingredient/CustomIngredientSerializer.java
+++ b/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/api/recipe/v1/ingredient/CustomIngredientSerializer.java
@@ -16,7 +16,7 @@
 
 package net.fabricmc.fabric.api.recipe.v1.ingredient;
 
-import com.mojang.serialization.Codec;
+import com.mojang.serialization.MapCodec;
 import org.jetbrains.annotations.Nullable;
 
 import net.minecraft.network.RegistryByteBuf;
@@ -64,7 +64,7 @@ public interface CustomIngredientSerializer<T extends CustomIngredient> {
 	 * @see Ingredient#ALLOW_EMPTY_CODEC
 	 * @see Ingredient#DISALLOW_EMPTY_CODEC
 	 */
-	Codec<T> getCodec(boolean allowEmpty);
+	MapCodec<T> getCodec(boolean allowEmpty);
 
 	/**
 	 * {@return the packet codec for serializing this ingredient}.
diff --git a/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/builtin/AllIngredient.java b/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/builtin/AllIngredient.java
index e1145d864..4fe4694cb 100644
--- a/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/builtin/AllIngredient.java
+++ b/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/builtin/AllIngredient.java
@@ -21,6 +21,7 @@ import java.util.Arrays;
 import java.util.List;
 
 import com.mojang.serialization.Codec;
+import com.mojang.serialization.MapCodec;
 
 import net.minecraft.item.ItemStack;
 import net.minecraft.recipe.Ingredient;
@@ -29,15 +30,14 @@ import net.minecraft.util.Identifier;
 import net.fabricmc.fabric.api.recipe.v1.ingredient.CustomIngredientSerializer;
 
 public class AllIngredient extends CombinedIngredient {
-	private static final Codec<AllIngredient> ALLOW_EMPTY_CODEC = createCodec(Ingredient.ALLOW_EMPTY_CODEC);
-	private static final Codec<AllIngredient> DISALLOW_EMPTY_CODEC = createCodec(Ingredient.DISALLOW_EMPTY_CODEC);
+	private static final MapCodec<AllIngredient> ALLOW_EMPTY_CODEC = createCodec(Ingredient.ALLOW_EMPTY_CODEC);
+	private static final MapCodec<AllIngredient> DISALLOW_EMPTY_CODEC = createCodec(Ingredient.DISALLOW_EMPTY_CODEC);
 
-	private static Codec<AllIngredient> createCodec(Codec<Ingredient> ingredientCodec) {
+	private static MapCodec<AllIngredient> createCodec(Codec<Ingredient> ingredientCodec) {
 		return ingredientCodec
 				.listOf()
 				.fieldOf("ingredients")
-				.xmap(AllIngredient::new, AllIngredient::getIngredients)
-				.codec();
+				.xmap(AllIngredient::new, AllIngredient::getIngredients);
 	}
 
 	public static final CustomIngredientSerializer<AllIngredient> SERIALIZER =
diff --git a/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/builtin/AnyIngredient.java b/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/builtin/AnyIngredient.java
index b4c6cf6c4..82a741baf 100644
--- a/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/builtin/AnyIngredient.java
+++ b/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/builtin/AnyIngredient.java
@@ -21,6 +21,7 @@ import java.util.Arrays;
 import java.util.List;
 
 import com.mojang.serialization.Codec;
+import com.mojang.serialization.MapCodec;
 
 import net.minecraft.item.ItemStack;
 import net.minecraft.recipe.Ingredient;
@@ -29,15 +30,14 @@ import net.minecraft.util.Identifier;
 import net.fabricmc.fabric.api.recipe.v1.ingredient.CustomIngredientSerializer;
 
 public class AnyIngredient extends CombinedIngredient {
-	private static final Codec<AnyIngredient> ALLOW_EMPTY_CODEC = createCodec(Ingredient.ALLOW_EMPTY_CODEC);
-	private static final Codec<AnyIngredient> DISALLOW_EMPTY_CODEC = createCodec(Ingredient.DISALLOW_EMPTY_CODEC);
+	private static final MapCodec<AnyIngredient> ALLOW_EMPTY_CODEC = createCodec(Ingredient.ALLOW_EMPTY_CODEC);
+	private static final MapCodec<AnyIngredient> DISALLOW_EMPTY_CODEC = createCodec(Ingredient.DISALLOW_EMPTY_CODEC);
 
-	private static Codec<AnyIngredient> createCodec(Codec<Ingredient> ingredientCodec) {
+	private static MapCodec<AnyIngredient> createCodec(Codec<Ingredient> ingredientCodec) {
 		return ingredientCodec
 				.listOf()
 				.fieldOf("ingredients")
-				.xmap(AnyIngredient::new, AnyIngredient::getIngredients)
-				.codec();
+				.xmap(AnyIngredient::new, AnyIngredient::getIngredients);
 	}
 
 	public static final CustomIngredientSerializer<AnyIngredient> SERIALIZER =
diff --git a/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/builtin/CombinedIngredient.java b/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/builtin/CombinedIngredient.java
index 9b04d8a8a..7c9e1622f 100644
--- a/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/builtin/CombinedIngredient.java
+++ b/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/builtin/CombinedIngredient.java
@@ -19,7 +19,7 @@ package net.fabricmc.fabric.impl.recipe.ingredient.builtin;
 import java.util.List;
 import java.util.function.Function;
 
-import com.mojang.serialization.Codec;
+import com.mojang.serialization.MapCodec;
 
 import net.minecraft.network.RegistryByteBuf;
 import net.minecraft.network.codec.PacketCodec;
@@ -61,11 +61,11 @@ abstract class CombinedIngredient implements CustomIngredient {
 
 	static class Serializer<I extends CombinedIngredient> implements CustomIngredientSerializer<I> {
 		private final Identifier identifier;
-		private final Codec<I> allowEmptyCodec;
-		private final Codec<I> disallowEmptyCodec;
+		private final MapCodec<I> allowEmptyCodec;
+		private final MapCodec<I> disallowEmptyCodec;
 		private final PacketCodec<RegistryByteBuf, I> packetCodec;
 
-		Serializer(Identifier identifier, Function<List<Ingredient>, I> factory, Codec<I> allowEmptyCodec, Codec<I> disallowEmptyCodec) {
+		Serializer(Identifier identifier, Function<List<Ingredient>, I> factory, MapCodec<I> allowEmptyCodec, MapCodec<I> disallowEmptyCodec) {
 			this.identifier = identifier;
 			this.allowEmptyCodec = allowEmptyCodec;
 			this.disallowEmptyCodec = disallowEmptyCodec;
@@ -79,7 +79,7 @@ abstract class CombinedIngredient implements CustomIngredient {
 		}
 
 		@Override
-		public Codec<I> getCodec(boolean allowEmpty) {
+		public MapCodec<I> getCodec(boolean allowEmpty) {
 			return allowEmpty ? allowEmptyCodec : disallowEmptyCodec;
 		}
 
diff --git a/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/builtin/ComponentsIngredient.java b/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/builtin/ComponentsIngredient.java
index ef5bcfc9b..a9ca0fefe 100644
--- a/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/builtin/ComponentsIngredient.java
+++ b/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/builtin/ComponentsIngredient.java
@@ -23,6 +23,7 @@ import java.util.Objects;
 import java.util.Optional;
 
 import com.mojang.serialization.Codec;
+import com.mojang.serialization.MapCodec;
 import com.mojang.serialization.codecs.RecordCodecBuilder;
 import org.jetbrains.annotations.Nullable;
 
@@ -116,16 +117,16 @@ public class ComponentsIngredient implements CustomIngredient {
 
 	private static class Serializer implements CustomIngredientSerializer<ComponentsIngredient> {
 		private static final Identifier ID = new Identifier("fabric", "components");
-		private static final Codec<ComponentsIngredient> ALLOW_EMPTY_CODEC = createCodec(Ingredient.ALLOW_EMPTY_CODEC);
-		private static final Codec<ComponentsIngredient> DISALLOW_EMPTY_CODEC = createCodec(Ingredient.DISALLOW_EMPTY_CODEC);
+		private static final MapCodec<ComponentsIngredient> ALLOW_EMPTY_CODEC = createCodec(Ingredient.ALLOW_EMPTY_CODEC);
+		private static final MapCodec<ComponentsIngredient> DISALLOW_EMPTY_CODEC = createCodec(Ingredient.DISALLOW_EMPTY_CODEC);
 		private static final PacketCodec<RegistryByteBuf, ComponentsIngredient> PACKET_CODEC = PacketCodec.tuple(
 				Ingredient.PACKET_CODEC, ComponentsIngredient::getBase,
 				ComponentChanges.PACKET_CODEC, ComponentsIngredient::getComponents,
 				ComponentsIngredient::new
 		);
 
-		private static Codec<ComponentsIngredient> createCodec(Codec<Ingredient> ingredientCodec) {
-			return RecordCodecBuilder.create(instance ->
+		private static MapCodec<ComponentsIngredient> createCodec(Codec<Ingredient> ingredientCodec) {
+			return RecordCodecBuilder.mapCodec(instance ->
 					instance.group(
 							ingredientCodec.fieldOf("base").forGetter(ComponentsIngredient::getBase),
 							ComponentChanges.CODEC.fieldOf("components").forGetter(ComponentsIngredient::getComponents)
@@ -139,7 +140,7 @@ public class ComponentsIngredient implements CustomIngredient {
 		}
 
 		@Override
-		public Codec<ComponentsIngredient> getCodec(boolean allowEmpty) {
+		public MapCodec<ComponentsIngredient> getCodec(boolean allowEmpty) {
 			return allowEmpty ? ALLOW_EMPTY_CODEC : DISALLOW_EMPTY_CODEC;
 		}
 
diff --git a/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/builtin/CustomDataIngredient.java b/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/builtin/CustomDataIngredient.java
index acca30f52..b2962f61a 100644
--- a/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/builtin/CustomDataIngredient.java
+++ b/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/builtin/CustomDataIngredient.java
@@ -23,6 +23,7 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException;
 import com.mojang.datafixers.util.Either;
 import com.mojang.serialization.Codec;
 import com.mojang.serialization.DataResult;
+import com.mojang.serialization.MapCodec;
 import com.mojang.serialization.codecs.RecordCodecBuilder;
 
 import net.minecraft.component.DataComponentTypes;
@@ -35,7 +36,6 @@ import net.minecraft.network.codec.PacketCodec;
 import net.minecraft.network.codec.PacketCodecs;
 import net.minecraft.recipe.Ingredient;
 import net.minecraft.util.Identifier;
-import net.minecraft.util.dynamic.Codecs;
 
 import net.fabricmc.fabric.api.recipe.v1.ingredient.CustomIngredient;
 import net.fabricmc.fabric.api.recipe.v1.ingredient.CustomIngredientSerializer;
@@ -95,7 +95,7 @@ public class CustomDataIngredient implements CustomIngredient {
 		private static final Identifier ID = new Identifier("fabric", "custom_data");
 
 		// Supports decoding the NBT as a string as well as the object.
-		private static final Codec<NbtCompound> NBT_CODEC = Codecs.xor(
+		private static final Codec<NbtCompound> NBT_CODEC = Codec.xor(
 				Codec.STRING, NbtCompound.CODEC
 		).flatXmap(either -> either.map(s -> {
 			try {
@@ -105,8 +105,8 @@ public class CustomDataIngredient implements CustomIngredient {
 			}
 		}, DataResult::success), nbtCompound -> DataResult.success(Either.left(nbtCompound.asString())));
 
-		private static final Codec<CustomDataIngredient> ALLOW_EMPTY_CODEC = createCodec(Ingredient.ALLOW_EMPTY_CODEC);
-		private static final Codec<CustomDataIngredient> DISALLOW_EMPTY_CODEC = createCodec(Ingredient.DISALLOW_EMPTY_CODEC);
+		private static final MapCodec<CustomDataIngredient> ALLOW_EMPTY_CODEC = createCodec(Ingredient.ALLOW_EMPTY_CODEC);
+		private static final MapCodec<CustomDataIngredient> DISALLOW_EMPTY_CODEC = createCodec(Ingredient.DISALLOW_EMPTY_CODEC);
 
 		private static final PacketCodec<RegistryByteBuf, CustomDataIngredient> PACKET_CODEC = PacketCodec.tuple(
 				Ingredient.PACKET_CODEC, CustomDataIngredient::getBase,
@@ -114,8 +114,8 @@ public class CustomDataIngredient implements CustomIngredient {
 				CustomDataIngredient::new
 		);
 
-		private static Codec<CustomDataIngredient> createCodec(Codec<Ingredient> ingredientCodec) {
-			return RecordCodecBuilder.create(instance ->
+		private static MapCodec<CustomDataIngredient> createCodec(Codec<Ingredient> ingredientCodec) {
+			return RecordCodecBuilder.mapCodec(instance ->
 					instance.group(
 							ingredientCodec.fieldOf("base").forGetter(CustomDataIngredient::getBase),
 							NBT_CODEC.fieldOf("nbt").forGetter(CustomDataIngredient::getNbt)
@@ -129,7 +129,7 @@ public class CustomDataIngredient implements CustomIngredient {
 		}
 
 		@Override
-		public Codec<CustomDataIngredient> getCodec(boolean allowEmpty) {
+		public MapCodec<CustomDataIngredient> getCodec(boolean allowEmpty) {
 			return allowEmpty ? ALLOW_EMPTY_CODEC : DISALLOW_EMPTY_CODEC;
 		}
 
diff --git a/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/builtin/DifferenceIngredient.java b/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/builtin/DifferenceIngredient.java
index 83b7030ae..cb39f28c9 100644
--- a/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/builtin/DifferenceIngredient.java
+++ b/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/builtin/DifferenceIngredient.java
@@ -20,6 +20,7 @@ import java.util.ArrayList;
 import java.util.List;
 
 import com.mojang.serialization.Codec;
+import com.mojang.serialization.MapCodec;
 import com.mojang.serialization.codecs.RecordCodecBuilder;
 
 import net.minecraft.item.ItemStack;
@@ -74,16 +75,16 @@ public class DifferenceIngredient implements CustomIngredient {
 
 	private static class Serializer implements CustomIngredientSerializer<DifferenceIngredient> {
 		private static final Identifier ID = new Identifier("fabric", "difference");
-		private static final Codec<DifferenceIngredient> ALLOW_EMPTY_CODEC = createCodec(Ingredient.ALLOW_EMPTY_CODEC);
-		private static final Codec<DifferenceIngredient> DISALLOW_EMPTY_CODEC = createCodec(Ingredient.DISALLOW_EMPTY_CODEC);
+		private static final MapCodec<DifferenceIngredient> ALLOW_EMPTY_CODEC = createCodec(Ingredient.ALLOW_EMPTY_CODEC);
+		private static final MapCodec<DifferenceIngredient> DISALLOW_EMPTY_CODEC = createCodec(Ingredient.DISALLOW_EMPTY_CODEC);
 		private static final PacketCodec<RegistryByteBuf, DifferenceIngredient> PACKET_CODEC = PacketCodec.tuple(
 				Ingredient.PACKET_CODEC, DifferenceIngredient::getBase,
 				Ingredient.PACKET_CODEC, DifferenceIngredient::getSubtracted,
 				DifferenceIngredient::new
 		);
 
-		private static Codec<DifferenceIngredient> createCodec(Codec<Ingredient> ingredientCodec) {
-			return RecordCodecBuilder.create(instance ->
+		private static MapCodec<DifferenceIngredient> createCodec(Codec<Ingredient> ingredientCodec) {
+			return RecordCodecBuilder.mapCodec(instance ->
 					instance.group(
 							ingredientCodec.fieldOf("base").forGetter(DifferenceIngredient::getBase),
 							ingredientCodec.fieldOf("subtracted").forGetter(DifferenceIngredient::getSubtracted)
@@ -97,7 +98,7 @@ public class DifferenceIngredient implements CustomIngredient {
 		}
 
 		@Override
-		public Codec<DifferenceIngredient> getCodec(boolean allowEmpty) {
+		public MapCodec<DifferenceIngredient> getCodec(boolean allowEmpty) {
 			return allowEmpty ? ALLOW_EMPTY_CODEC : DISALLOW_EMPTY_CODEC;
 		}
 
diff --git a/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/mixin/recipe/ingredient/IngredientMixin.java b/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/mixin/recipe/ingredient/IngredientMixin.java
index 96bbe748c..1c5913a6b 100644
--- a/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/mixin/recipe/ingredient/IngredientMixin.java
+++ b/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/mixin/recipe/ingredient/IngredientMixin.java
@@ -27,7 +27,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
 import net.minecraft.network.RegistryByteBuf;
 import net.minecraft.network.codec.PacketCodec;
 import net.minecraft.recipe.Ingredient;
-import net.minecraft.util.dynamic.Codecs;
 
 import net.fabricmc.fabric.api.recipe.v1.ingredient.CustomIngredient;
 import net.fabricmc.fabric.api.recipe.v1.ingredient.FabricIngredient;
@@ -43,7 +42,7 @@ public class IngredientMixin implements FabricIngredient {
 				CustomIngredient::getSerializer,
 				serializer -> serializer.getCodec(allowEmpty));
 
-		cir.setReturnValue(Codecs.either(customIngredientCodec, cir.getReturnValue()).xmap(
+		cir.setReturnValue(Codec.either(customIngredientCodec, cir.getReturnValue()).xmap(
 				either -> either.map(CustomIngredient::toVanilla, ingredient -> ingredient),
 				ingredient -> {
 					CustomIngredient customIngredient = ingredient.getCustomIngredient();
diff --git a/fabric-recipe-api-v1/src/testmod/java/net/fabricmc/fabric/test/recipe/ingredient/SerializationTests.java b/fabric-recipe-api-v1/src/testmod/java/net/fabricmc/fabric/test/recipe/ingredient/SerializationTests.java
index 3f4cdce28..dfb83b54b 100644
--- a/fabric-recipe-api-v1/src/testmod/java/net/fabricmc/fabric/test/recipe/ingredient/SerializationTests.java
+++ b/fabric-recipe-api-v1/src/testmod/java/net/fabricmc/fabric/test/recipe/ingredient/SerializationTests.java
@@ -30,7 +30,6 @@ import net.minecraft.recipe.Ingredient;
 import net.minecraft.test.GameTest;
 import net.minecraft.test.GameTestException;
 import net.minecraft.test.TestContext;
-import net.minecraft.util.Util;
 
 import net.fabricmc.fabric.api.gametest.v1.FabricGameTest;
 import net.fabricmc.fabric.api.recipe.v1.ingredient.DefaultCustomIngredients;
@@ -58,7 +57,7 @@ public class SerializationTests {
 		JsonElement json = JsonParser.parseString(ingredientJson);
 
 		try {
-			Util.getResult(Ingredient.DISALLOW_EMPTY_CODEC.parse(JsonOps.INSTANCE, json), JsonParseException::new);
+			Ingredient.DISALLOW_EMPTY_CODEC.parse(JsonOps.INSTANCE, json).getOrThrow(JsonParseException::new);
 			throw new GameTestException("Using a custom ingredient inside an array ingredient should have failed.");
 		} catch (JsonParseException e) {
 			context.complete();
@@ -79,12 +78,10 @@ public class SerializationTests {
 					Ingredient.ofItems(Items.STONE)
 			);
 			Codec<Ingredient> ingredientCodec = allowEmpty ? Ingredient.ALLOW_EMPTY_CODEC : Ingredient.DISALLOW_EMPTY_CODEC;
-			JsonObject json = Util.getResult(ingredientCodec.encodeStart(JsonOps.INSTANCE, ingredient), IllegalStateException::new).getAsJsonObject();
+			JsonObject json = ingredientCodec.encodeStart(JsonOps.INSTANCE, ingredient).getOrThrow(IllegalStateException::new).getAsJsonObject();
 			context.assertTrue(json.toString().equals(ingredientJson), "Unexpected json: " + json);
 			// Make sure that we can deserialize it
-			Ingredient deserialized = Util.getResult(
-					ingredientCodec.parse(JsonOps.INSTANCE, json), JsonParseException::new
-			);
+			Ingredient deserialized = ingredientCodec.parse(JsonOps.INSTANCE, json).getOrThrow(JsonParseException::new);
 			context.assertTrue(deserialized.getCustomIngredient() != null, "Custom ingredient was not deserialized");
 			context.assertTrue(deserialized.getCustomIngredient().getSerializer() == ingredient.getCustomIngredient().getSerializer(), "Serializer did not match");
 		}
diff --git a/fabric-renderer-api-v1/src/client/java/net/fabricmc/fabric/mixin/renderer/client/WeightedBakedModelMixin.java b/fabric-renderer-api-v1/src/client/java/net/fabricmc/fabric/mixin/renderer/client/WeightedBakedModelMixin.java
index 53c508121..d31e00b26 100644
--- a/fabric-renderer-api-v1/src/client/java/net/fabricmc/fabric/mixin/renderer/client/WeightedBakedModelMixin.java
+++ b/fabric-renderer-api-v1/src/client/java/net/fabricmc/fabric/mixin/renderer/client/WeightedBakedModelMixin.java
@@ -54,7 +54,7 @@ public class WeightedBakedModelMixin implements FabricBakedModel {
 	@Inject(at = @At("RETURN"), method = "<init>")
 	private void onInit(List<Weighted.Present<BakedModel>> models, CallbackInfo cb) {
 		for (int i = 0; i < models.size(); i++) {
-			if (!models.get(i).getData().isVanillaAdapter()) {
+			if (!models.get(i).data().isVanillaAdapter()) {
 				isVanilla = false;
 				break;
 			}
@@ -71,7 +71,7 @@ public class WeightedBakedModelMixin implements FabricBakedModel {
 		Weighted.Present<BakedModel> selected = Weighting.getAt(this.models, Math.abs((int) randomSupplier.get().nextLong()) % this.totalWeight).orElse(null);
 
 		if (selected != null) {
-			selected.getData().emitBlockQuads(blockView, state, pos, () -> {
+			selected.data().emitBlockQuads(blockView, state, pos, () -> {
 				Random random = randomSupplier.get();
 				random.nextLong(); // Imitate vanilla modifying the random before passing it to the submodel
 				return random;
@@ -84,7 +84,7 @@ public class WeightedBakedModelMixin implements FabricBakedModel {
 		Weighted.Present<BakedModel> selected = Weighting.getAt(this.models, Math.abs((int) randomSupplier.get().nextLong()) % this.totalWeight).orElse(null);
 
 		if (selected != null) {
-			selected.getData().emitItemQuads(stack, () -> {
+			selected.data().emitItemQuads(stack, () -> {
 				Random random = randomSupplier.get();
 				random.nextLong(); // Imitate vanilla modifying the random before passing it to the submodel
 				return random;
diff --git a/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/CustomAtlasSourcesTest.java b/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/CustomAtlasSourcesTest.java
index ce3f0cf0e..7c00d49c0 100644
--- a/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/CustomAtlasSourcesTest.java
+++ b/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/CustomAtlasSourcesTest.java
@@ -21,7 +21,7 @@ import java.io.InputStream;
 import java.util.Optional;
 
 import com.mojang.logging.LogUtils;
-import com.mojang.serialization.Codec;
+import com.mojang.serialization.MapCodec;
 import com.mojang.serialization.codecs.RecordCodecBuilder;
 import org.slf4j.Logger;
 
@@ -49,7 +49,7 @@ public class CustomAtlasSourcesTest implements ClientModInitializer {
 
 	private static class DoubleAtlasSource implements AtlasSource {
 		private static final Logger LOGGER = LogUtils.getLogger();
-		public static final Codec<DoubleAtlasSource> CODEC = RecordCodecBuilder.create(instance -> instance.group(
+		public static final MapCodec<DoubleAtlasSource> CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group(
 				Identifier.CODEC.fieldOf("resource").forGetter(source -> source.resource),
 				Identifier.CODEC.fieldOf("sprite").forGetter(source -> source.sprite)
 		).apply(instance, DoubleAtlasSource::new));
diff --git a/fabric-screen-handler-api-v1/src/main/java/net/fabricmc/fabric/impl/screenhandler/Networking.java b/fabric-screen-handler-api-v1/src/main/java/net/fabricmc/fabric/impl/screenhandler/Networking.java
index 1b23bf146..44377f8a7 100644
--- a/fabric-screen-handler-api-v1/src/main/java/net/fabricmc/fabric/impl/screenhandler/Networking.java
+++ b/fabric-screen-handler-api-v1/src/main/java/net/fabricmc/fabric/impl/screenhandler/Networking.java
@@ -19,6 +19,7 @@ package net.fabricmc.fabric.impl.screenhandler;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
+import java.util.function.BiConsumer;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -27,6 +28,7 @@ import net.minecraft.network.RegistryByteBuf;
 import net.minecraft.network.codec.PacketCodec;
 import net.minecraft.network.packet.CustomPayload;
 import net.minecraft.registry.Registries;
+import net.minecraft.registry.Registry;
 import net.minecraft.screen.ScreenHandler;
 import net.minecraft.server.network.ServerPlayerEntity;
 import net.minecraft.text.Text;
@@ -81,13 +83,25 @@ public final class Networking implements ModInitializer {
 	@Override
 	public void onInitialize() {
 		PayloadTypeRegistry.playS2C().register(OpenScreenPayload.ID, OpenScreenPayload.CODEC);
-		RegistryEntryAddedCallback.event(Registries.SCREEN_HANDLER).register((rawId, id, type) -> {
+
+		forEachEntry(Registries.SCREEN_HANDLER, (type, id) -> {
 			if (type instanceof ExtendedScreenHandlerType<?, ?> extended) {
 				CODEC_BY_ID.put(id, extended.getPacketCodec());
 			}
 		});
 	}
 
+	// Calls the consumer for each registry entry that has been registered or will be registered.
+	private static <T> void forEachEntry(Registry<T> registry, BiConsumer<T, Identifier> consumer) {
+		for (T type : registry) {
+			consumer.accept(type, registry.getId(type));
+		}
+
+		RegistryEntryAddedCallback.event(registry).register((rawId, id, type) -> {
+			consumer.accept(type, id);
+		});
+	}
+
 	public record OpenScreenPayload<D>(Identifier identifier, int syncId, Text title, PacketCodec<RegistryByteBuf, D> innerCodec, D data) implements CustomPayload {
 		public static final PacketCodec<RegistryByteBuf, OpenScreenPayload<?>> CODEC = CustomPayload.codecOf(OpenScreenPayload::write, OpenScreenPayload::fromBuf);
 		public static final CustomPayload.Id<OpenScreenPayload<?>> ID = new Id<>(OPEN_ID);
diff --git a/fabric-transfer-api-v1/src/main/java/net/fabricmc/fabric/api/transfer/v1/storage/base/SingleVariantStorage.java b/fabric-transfer-api-v1/src/main/java/net/fabricmc/fabric/api/transfer/v1/storage/base/SingleVariantStorage.java
index 706e0effb..ab73c3978 100644
--- a/fabric-transfer-api-v1/src/main/java/net/fabricmc/fabric/api/transfer/v1/storage/base/SingleVariantStorage.java
+++ b/fabric-transfer-api-v1/src/main/java/net/fabricmc/fabric/api/transfer/v1/storage/base/SingleVariantStorage.java
@@ -28,7 +28,6 @@ import net.minecraft.nbt.NbtElement;
 import net.minecraft.nbt.NbtOps;
 import net.minecraft.registry.RegistryOps;
 import net.minecraft.registry.RegistryWrapper;
-import net.minecraft.util.Util;
 
 import net.fabricmc.fabric.api.transfer.v1.storage.StoragePreconditions;
 import net.fabricmc.fabric.api.transfer.v1.storage.TransferVariant;
@@ -198,7 +197,7 @@ public abstract class SingleVariantStorage<T extends TransferVariant<?>> extends
 	 */
 	public static <T extends TransferVariant<?>> void writeNbt(SingleVariantStorage<T> storage, Codec<T> codec, NbtCompound nbt, RegistryWrapper.WrapperLookup wrapperLookup) {
 		final RegistryOps<NbtElement> ops = wrapperLookup.getOps(NbtOps.INSTANCE);
-		nbt.put("variant", Util.getResult(codec.encodeStart(ops, storage.variant), RuntimeException::new));
+		nbt.put("variant", codec.encode(storage.variant, ops, nbt).getOrThrow(RuntimeException::new));
 		nbt.putLong("amount", storage.amount);
 	}
 }
diff --git a/fabric-transfer-api-v1/src/main/java/net/fabricmc/fabric/impl/transfer/VariantCodecs.java b/fabric-transfer-api-v1/src/main/java/net/fabricmc/fabric/impl/transfer/VariantCodecs.java
index bac5c6209..1ec91fa30 100644
--- a/fabric-transfer-api-v1/src/main/java/net/fabricmc/fabric/impl/transfer/VariantCodecs.java
+++ b/fabric-transfer-api-v1/src/main/java/net/fabricmc/fabric/impl/transfer/VariantCodecs.java
@@ -25,7 +25,6 @@ import net.minecraft.network.codec.PacketCodec;
 import net.minecraft.network.codec.PacketCodecs;
 import net.minecraft.registry.Registries;
 import net.minecraft.registry.RegistryKeys;
-import net.minecraft.util.dynamic.Codecs;
 
 import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant;
 import net.fabricmc.fabric.api.transfer.v1.item.ItemVariant;
@@ -35,7 +34,7 @@ import net.fabricmc.fabric.impl.transfer.item.ItemVariantImpl;
 public class VariantCodecs {
 	public static final Codec<ItemVariant> ITEM_CODEC = RecordCodecBuilder.create(instance -> instance.group(
 			Registries.ITEM.getEntryCodec().fieldOf("item").forGetter(ItemVariant::getRegistryEntry),
-			Codecs.createStrictOptionalFieldCodec(ComponentChanges.CODEC, "components", ComponentChanges.EMPTY).forGetter(ItemVariant::getComponents)
+			ComponentChanges.CODEC.optionalFieldOf("components", ComponentChanges.EMPTY).forGetter(ItemVariant::getComponents)
 		).apply(instance, ItemVariantImpl::of)
 	);
 	public static final PacketCodec<RegistryByteBuf, ItemVariant> ITEM_PACKET_CODEC = PacketCodec.tuple(
@@ -46,7 +45,7 @@ public class VariantCodecs {
 
 	public static final Codec<FluidVariant> FLUID_CODEC = RecordCodecBuilder.create(instance -> instance.group(
 			Registries.FLUID.getEntryCodec().fieldOf("fluid").forGetter(FluidVariant::getRegistryEntry),
-			Codecs.createStrictOptionalFieldCodec(ComponentChanges.CODEC, "components", ComponentChanges.EMPTY).forGetter(FluidVariant::getComponents)
+			ComponentChanges.CODEC.optionalFieldOf("components", ComponentChanges.EMPTY).forGetter(FluidVariant::getComponents)
 		).apply(instance, FluidVariantImpl::of)
 	);
 	public static final PacketCodec<RegistryByteBuf, FluidVariant> FLUID_PACKET_CODEC = PacketCodec.tuple(
diff --git a/fabric-transitive-access-wideners-v1/src/main/resources/fabric-transitive-access-wideners-v1.accesswidener b/fabric-transitive-access-wideners-v1/src/main/resources/fabric-transitive-access-wideners-v1.accesswidener
index 26b83597f..30d2345ea 100644
--- a/fabric-transitive-access-wideners-v1/src/main/resources/fabric-transitive-access-wideners-v1.accesswidener
+++ b/fabric-transitive-access-wideners-v1/src/main/resources/fabric-transitive-access-wideners-v1.accesswidener
@@ -102,7 +102,7 @@ transitive-accessible method net/minecraft/sound/SoundEvent of (Lnet/minecraft/u
 transitive-accessible method net/minecraft/sound/SoundEvent of (Lnet/minecraft/util/Identifier;)Lnet/minecraft/sound/SoundEvent;
 
 # Creating BlockStateProviderTypes
-transitive-accessible method net/minecraft/world/gen/stateprovider/BlockStateProviderType <init> (Lcom/mojang/serialization/Codec;)V
+transitive-accessible method net/minecraft/world/gen/stateprovider/BlockStateProviderType <init> (Lcom/mojang/serialization/MapCodec;)V
 
 # Creating custom biomes
 transitive-accessible method net/minecraft/world/biome/OverworldBiomeCreator getSkyColor (F)I
@@ -111,10 +111,10 @@ transitive-accessible method net/minecraft/world/biome/OverworldBiomeCreator get
 transitive-accessible field net/minecraft/structure/processor/StructureProcessorLists EMPTY Lnet/minecraft/registry/RegistryKey;
 
 # Creating custom trees
-transitive-accessible method net/minecraft/world/gen/foliage/FoliagePlacerType <init> (Lcom/mojang/serialization/Codec;)V
-transitive-accessible method net/minecraft/world/gen/treedecorator/TreeDecoratorType <init> (Lcom/mojang/serialization/Codec;)V
-transitive-accessible method net/minecraft/world/gen/trunk/TrunkPlacerType <init> (Lcom/mojang/serialization/Codec;)V
-transitive-accessible method net/minecraft/world/gen/root/RootPlacerType <init> (Lcom/mojang/serialization/Codec;)V
+transitive-accessible method net/minecraft/world/gen/foliage/FoliagePlacerType <init> (Lcom/mojang/serialization/MapCodec;)V
+transitive-accessible method net/minecraft/world/gen/treedecorator/TreeDecoratorType <init> (Lcom/mojang/serialization/MapCodec;)V
+transitive-accessible method net/minecraft/world/gen/trunk/TrunkPlacerType <init> (Lcom/mojang/serialization/MapCodec;)V
+transitive-accessible method net/minecraft/world/gen/root/RootPlacerType <init> (Lcom/mojang/serialization/MapCodec;)V
 
 # Working with custom damage sources
 transitive-accessible field net/minecraft/entity/damage/DamageSources registry Lnet/minecraft/registry/Registry;
diff --git a/fabric-transitive-access-wideners-v1/template.accesswidener b/fabric-transitive-access-wideners-v1/template.accesswidener
index a5809648b..414cf79b1 100644
--- a/fabric-transitive-access-wideners-v1/template.accesswidener
+++ b/fabric-transitive-access-wideners-v1/template.accesswidener
@@ -97,7 +97,7 @@ transitive-accessible method net/minecraft/sound/SoundEvent of (Lnet/minecraft/u
 transitive-accessible method net/minecraft/sound/SoundEvent of (Lnet/minecraft/util/Identifier;)Lnet/minecraft/sound/SoundEvent;
 
 # Creating BlockStateProviderTypes
-transitive-accessible method net/minecraft/world/gen/stateprovider/BlockStateProviderType <init> (Lcom/mojang/serialization/Codec;)V
+transitive-accessible method net/minecraft/world/gen/stateprovider/BlockStateProviderType <init> (Lcom/mojang/serialization/MapCodec;)V
 
 # Creating custom biomes
 transitive-accessible method net/minecraft/world/biome/OverworldBiomeCreator getSkyColor (F)I
@@ -106,10 +106,10 @@ transitive-accessible method net/minecraft/world/biome/OverworldBiomeCreator get
 transitive-accessible field net/minecraft/structure/processor/StructureProcessorLists EMPTY Lnet/minecraft/registry/RegistryKey;
 
 # Creating custom trees
-transitive-accessible method net/minecraft/world/gen/foliage/FoliagePlacerType <init> (Lcom/mojang/serialization/Codec;)V
-transitive-accessible method net/minecraft/world/gen/treedecorator/TreeDecoratorType <init> (Lcom/mojang/serialization/Codec;)V
-transitive-accessible method net/minecraft/world/gen/trunk/TrunkPlacerType <init> (Lcom/mojang/serialization/Codec;)V
-transitive-accessible method net/minecraft/world/gen/root/RootPlacerType <init> (Lcom/mojang/serialization/Codec;)V
+transitive-accessible method net/minecraft/world/gen/foliage/FoliagePlacerType <init> (Lcom/mojang/serialization/MapCodec;)V
+transitive-accessible method net/minecraft/world/gen/treedecorator/TreeDecoratorType <init> (Lcom/mojang/serialization/MapCodec;)V
+transitive-accessible method net/minecraft/world/gen/trunk/TrunkPlacerType <init> (Lcom/mojang/serialization/MapCodec;)V
+transitive-accessible method net/minecraft/world/gen/root/RootPlacerType <init> (Lcom/mojang/serialization/MapCodec;)V
 
 # Working with custom damage sources
 transitive-accessible field net/minecraft/entity/damage/DamageSources registry Lnet/minecraft/registry/Registry;
diff --git a/gradle.properties b/gradle.properties
index 6d4af8ea7..d2a9b795c 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -2,9 +2,9 @@ org.gradle.jvmargs=-Xmx2560M
 org.gradle.parallel=true
 fabric.loom.multiProjectOptimisation=true
 
-version=0.96.12
-minecraft_version=24w12a
-yarn_version=+build.5
+version=0.96.13
+minecraft_version=24w13a
+yarn_version=+build.2
 loader_version=0.15.6
 installer_version=0.11.1
 
@@ -13,51 +13,51 @@ curseforge_minecraft_version=1.20.5-Snapshot
 
 # Do not manually update, use the bumpversions task:
 fabric-api-base-version=0.4.38
-fabric-api-lookup-api-v1-version=1.6.56
-fabric-biome-api-v1-version=13.0.20
+fabric-api-lookup-api-v1-version=1.6.57
+fabric-biome-api-v1-version=13.0.21
 fabric-block-api-v1-version=1.0.18
 fabric-block-view-api-v2-version=1.0.6
 fabric-blockrenderlayer-v1-version=1.1.48
 fabric-command-api-v1-version=1.2.43
 fabric-command-api-v2-version=2.2.22
 fabric-commands-v0-version=0.2.60
-fabric-content-registries-v0-version=6.0.14
+fabric-content-registries-v0-version=6.0.15
 fabric-crash-report-info-v1-version=0.2.25
-fabric-data-attachment-api-v1-version=1.1.9
-fabric-data-generation-api-v1-version=18.0.0
-fabric-dimensions-v1-version=2.1.64
+fabric-data-attachment-api-v1-version=1.1.10
+fabric-data-generation-api-v1-version=18.0.1
+fabric-dimensions-v1-version=2.1.65
 fabric-entity-events-v1-version=1.6.6
 fabric-events-interaction-v0-version=0.7.4
-fabric-events-lifecycle-v0-version=0.2.84
+fabric-events-lifecycle-v0-version=0.2.85
 fabric-game-rule-api-v1-version=1.0.48
 fabric-gametest-api-v1-version=1.3.11
-fabric-item-api-v1-version=6.0.0
+fabric-item-api-v1-version=6.0.1
 fabric-item-group-api-v1-version=4.0.33
 fabric-key-binding-api-v1-version=1.0.43
 fabric-keybindings-v0-version=0.2.41
-fabric-lifecycle-events-v1-version=2.3.1
-fabric-loot-api-v2-version=2.1.13
+fabric-lifecycle-events-v1-version=2.3.2
+fabric-loot-api-v2-version=2.1.14
 fabric-message-api-v1-version=6.0.8
 fabric-model-loading-api-v1-version=1.0.10
 fabric-models-v0-version=0.4.9
 fabric-networking-api-v1-version=4.0.5
-fabric-object-builder-api-v1-version=15.0.0
-fabric-particles-v1-version=2.0.0
-fabric-recipe-api-v1-version=4.1.1
-fabric-registry-sync-v0-version=5.0.10
-fabric-renderer-api-v1-version=3.2.9
-fabric-renderer-indigo-version=1.5.9
-fabric-renderer-registries-v1-version=3.2.58
+fabric-object-builder-api-v1-version=15.0.1
+fabric-particles-v1-version=2.0.1
+fabric-recipe-api-v1-version=5.0.0
+fabric-registry-sync-v0-version=5.0.11
+fabric-renderer-api-v1-version=3.2.10
+fabric-renderer-indigo-version=1.5.10
+fabric-renderer-registries-v1-version=3.2.59
 fabric-rendering-data-attachment-v1-version=0.3.44
 fabric-rendering-fluids-v1-version=3.1.1
-fabric-rendering-v0-version=1.1.61
-fabric-rendering-v1-version=4.2.1
+fabric-rendering-v0-version=1.1.62
+fabric-rendering-v1-version=4.2.2
 fabric-resource-conditions-api-v1-version=3.0.0
 fabric-resource-loader-v0-version=1.0.0
 fabric-screen-api-v1-version=2.0.19
-fabric-screen-handler-api-v1-version=1.3.67
+fabric-screen-handler-api-v1-version=1.3.68
 fabric-sound-api-v1-version=1.0.19
-fabric-transfer-api-v1-version=5.1.2
-fabric-transitive-access-wideners-v1-version=6.0.6
-fabric-convention-tags-v1-version=1.5.14
+fabric-transfer-api-v1-version=5.1.3
+fabric-transitive-access-wideners-v1-version=6.0.7
+fabric-convention-tags-v1-version=1.5.15
 fabric-client-tags-api-v1-version=1.1.9