1.19.4-pre1

This commit is contained in:
modmuss50 2023-02-22 19:56:50 +00:00
parent 711cde8a2a
commit 5da15ca1b9
15 changed files with 152 additions and 174 deletions
fabric-biome-api-v1/src
main
testmod
generated/data/fabric-biome-api-v1-testmod/worldgen/biome
java/net/fabricmc/fabric/test/biome
resources/data/fabric-biome-api-v1-testmod/worldgen/biome
fabric-data-generation-api-v1/src/main/java/net/fabricmc/fabric/mixin/datagen
fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/mixin/event/lifecycle
fabric-screen-handler-api-v1/src/main/java/net/fabricmc/fabric/mixin/screenhandler
fabric-transfer-api-v1/src/main/java/net/fabricmc/fabric/mixin/transfer
gradle.properties

View file

@ -17,29 +17,23 @@
package net.fabricmc.fabric.impl.biome;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.function.Function;
import com.google.common.base.Preconditions;
import com.mojang.datafixers.util.Pair;
import com.mojang.logging.LogUtils;
import org.slf4j.Logger;
import net.minecraft.registry.RegistryEntryLookup;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.class_8197;
import net.minecraft.registry.RegistryKey;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.source.BiomeSource;
import net.minecraft.world.biome.source.MultiNoiseBiomeSource;
import net.minecraft.world.biome.source.util.MultiNoiseUtil;
import net.fabricmc.fabric.impl.biome.modification.BuiltInRegistryKeys;
/**
* Internal data for modding Vanilla's {@link MultiNoiseBiomeSource.Preset#NETHER}.
* Internal data for modding Vanilla's {@link class_8197.Preset#NETHER}.
*/
public final class NetherBiomeData {
// Cached sets of the biomes that would generate from Vanilla's default biome source without consideration
@ -48,8 +42,6 @@ public final class NetherBiomeData {
private static final Map<RegistryKey<Biome>, MultiNoiseUtil.NoiseHypercube> NETHER_BIOME_NOISE_POINTS = new HashMap<>();
private static final Logger LOGGER = LogUtils.getLogger();
private NetherBiomeData() {
}
@ -60,55 +52,25 @@ public final class NetherBiomeData {
clearBiomeSourceCache();
}
public static Map<RegistryKey<Biome>, MultiNoiseUtil.NoiseHypercube> getNetherBiomeNoisePoints() {
return NETHER_BIOME_NOISE_POINTS;
}
public static boolean canGenerateInNether(RegistryKey<Biome> biome) {
if (NETHER_BIOMES.isEmpty()) {
MultiNoiseBiomeSource source = MultiNoiseBiomeSource.Preset.NETHER.getBiomeSource(BuiltInRegistryKeys.biomeRegistryWrapper());
for (RegistryEntry<Biome> entry : source.getBiomes()) {
entry.getKey().ifPresent(NETHER_BIOMES::add);
}
}
return NETHER_BIOMES.contains(biome) || NETHER_BIOME_NOISE_POINTS.containsKey(biome);
return class_8197.Preset.NETHER.method_49514().anyMatch(input -> input.equals(biome));
}
private static void clearBiomeSourceCache() {
NETHER_BIOMES.clear(); // Clear cached biome source data
}
private static MultiNoiseUtil.Entries<RegistryEntry<Biome>> withModdedBiomeEntries(MultiNoiseUtil.Entries<RegistryEntry<Biome>> entries, RegistryEntryLookup<Biome> biomes) {
public static <T> MultiNoiseUtil.Entries<T> withModdedBiomeEntries(MultiNoiseUtil.Entries<T> entries, Function<RegistryKey<Biome>, T> biomes) {
if (NETHER_BIOME_NOISE_POINTS.isEmpty()) {
return entries;
}
ArrayList<Pair<MultiNoiseUtil.NoiseHypercube, RegistryEntry<Biome>>> entryList = new ArrayList<>(entries.getEntries());
ArrayList<Pair<MultiNoiseUtil.NoiseHypercube, T>> entryList = new ArrayList<>(entries.getEntries());
for (Map.Entry<RegistryKey<Biome>, MultiNoiseUtil.NoiseHypercube> entry : NETHER_BIOME_NOISE_POINTS.entrySet()) {
RegistryEntry.Reference<Biome> biomeEntry = biomes.getOptional(entry.getKey()).orElse(null);
if (biomeEntry != null) {
entryList.add(Pair.of(entry.getValue(), biomeEntry));
} else {
LOGGER.warn("Nether biome {} not loaded", entry.getKey().getValue());
}
entryList.add(Pair.of(entry.getValue(), biomes.apply(entry.getKey())));
}
return new MultiNoiseUtil.Entries<>(entryList);
}
public static void modifyBiomeSource(RegistryEntryLookup<Biome> biomeRegistry, BiomeSource biomeSource) {
if (biomeSource instanceof MultiNoiseBiomeSource multiNoiseBiomeSource) {
if (((BiomeSourceAccess) multiNoiseBiomeSource).fabric_shouldModifyBiomeEntries() && multiNoiseBiomeSource.matchesInstance(MultiNoiseBiomeSource.Preset.NETHER)) {
multiNoiseBiomeSource.biomeEntries = NetherBiomeData.withModdedBiomeEntries(
MultiNoiseBiomeSource.Preset.NETHER.biomeSourceFunction.apply(biomeRegistry::getOrThrow),
biomeRegistry);
multiNoiseBiomeSource.biomes = multiNoiseBiomeSource.biomeEntries.getEntries().stream().map(Pair::getSecond).collect(Collectors.toSet());
((BiomeSourceAccess) multiNoiseBiomeSource).fabric_setModifyBiomeEntries(false);
}
}
return new MultiNoiseUtil.Entries<>(Collections.unmodifiableList(entryList));
}
}

View file

@ -16,13 +16,14 @@
package net.fabricmc.fabric.mixin.biome;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Supplier;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.Redirect;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.world.biome.Biome;
@ -30,13 +31,11 @@ import net.minecraft.world.biome.source.BiomeSource;
@Mixin(BiomeSource.class)
public class BiomeSourceMixin {
// Not marked as @Final because of AW
@Shadow
public Set<RegistryEntry<Biome>> biomes;
@Inject(method = "getBiomes", at = @At("HEAD"))
private void getBiomes(CallbackInfoReturnable<Set<RegistryEntry<Biome>>> ci) {
@Redirect(method = "getBiomes", at = @At(value = "INVOKE", target = "Ljava/util/function/Supplier;get()Ljava/lang/Object;"))
private Object getBiomes(Supplier<Set<RegistryEntry<Biome>>> instance) {
var biomes = new HashSet<>(instance.get());
fabric_modifyBiomeSet(biomes);
return Collections.unmodifiableSet(biomes);
}
protected void fabric_modifyBiomeSet(Set<RegistryEntry<Biome>> biomes) {

View file

@ -1,55 +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.mixin.biome;
import java.net.Proxy;
import com.mojang.datafixers.DataFixer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.resource.ResourcePackManager;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.SaveLoader;
import net.minecraft.server.WorldGenerationProgressListenerFactory;
import net.minecraft.util.ApiServices;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.world.dimension.DimensionOptions;
import net.minecraft.world.level.storage.LevelStorage;
import net.fabricmc.fabric.impl.biome.NetherBiomeData;
// Priority set just below biome modification mixin's
@Mixin(value = MinecraftServer.class, priority = 990)
public class MinecraftServerMixin {
@Shadow
private DynamicRegistryManager.Immutable getRegistryManager() {
throw new AssertionError();
}
@Inject(method = "<init>", at = @At("RETURN"))
private void addNetherBiomes(Thread serverThread, LevelStorage.Session session, ResourcePackManager dataPackManager, SaveLoader saveLoader, Proxy proxy, DataFixer dataFixer, ApiServices apiServices, WorldGenerationProgressListenerFactory worldGenerationProgressListenerFactory, CallbackInfo ci) {
Registry<DimensionOptions> registry = getRegistryManager().get(RegistryKeys.DIMENSION);
registry.stream().forEach(dimensionOptions -> NetherBiomeData.modifyBiomeSource(getRegistryManager().getWrapperOrThrow(RegistryKeys.BIOME), dimensionOptions.chunkGenerator().getBiomeSource()));
}
}

View file

@ -0,0 +1,38 @@
/*
* 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.mixin.biome;
import java.util.function.Function;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.registry.RegistryKey;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.source.util.MultiNoiseUtil;
import net.fabricmc.fabric.impl.biome.NetherBiomeData;
@Mixin(targets = "net/minecraft/class_8197$Preset$1")
public class NetherBiomePresetMixin {
@Inject(method = "apply", at = @At("RETURN"), cancellable = true)
public <T> void apply(Function<RegistryKey<Biome>, T> function, CallbackInfoReturnable<MultiNoiseUtil.Entries<T>> cir) {
cir.setReturnValue(NetherBiomeData.withModdedBiomeEntries(cir.getReturnValue(), function));
}
}

View file

@ -2,15 +2,7 @@ accessWidener v1 named
accessible class net/minecraft/world/biome/Biome$Weather
# Used to set nether biomes
accessible field net/minecraft/world/biome/source/MultiNoiseBiomeSource instance Ljava/util/Optional;
accessible class net/minecraft/world/biome/source/MultiNoiseBiomeSource$Instance
accessible field net/minecraft/world/biome/source/MultiNoiseBiomeSource$Preset biomeSourceFunction Lnet/minecraft/world/biome/source/MultiNoiseBiomeSource$Preset$BiomeSourceFunction;
accessible field net/minecraft/world/biome/source/MultiNoiseBiomeSource biomeEntries Lnet/minecraft/world/biome/source/util/MultiNoiseUtil$Entries;
mutable field net/minecraft/world/biome/source/MultiNoiseBiomeSource biomeEntries Lnet/minecraft/world/biome/source/util/MultiNoiseUtil$Entries;
# Rebuilding biome source feature lists
accessible field net/minecraft/world/biome/source/BiomeSource biomes Ljava/util/Set;
mutable field net/minecraft/world/biome/source/BiomeSource biomes Ljava/util/Set;
accessible class net/minecraft/class_8197$Preset$BiomeSourceFunction
# Top-Level Biome Fields Access
accessible field net/minecraft/world/biome/Biome weather Lnet/minecraft/world/biome/Biome$Weather;

View file

@ -3,11 +3,11 @@
"package": "net.fabricmc.fabric.mixin.biome",
"compatibilityLevel": "JAVA_16",
"mixins": [
"MinecraftServerMixin",
"BiomeSourceMixin",
"ChunkNoiseSamplerMixin",
"MultiNoiseBiomeSourceMixin",
"MultiNoiseUtilMultiNoiseSamplerMixin",
"NetherBiomePresetMixin",
"NoiseConfigMixin",
"TheEndBiomeSourceMixin",
"modification.DynamicRegistryManagerImmutableImplMixin",

View file

@ -0,0 +1,24 @@
{
"carvers": {},
"downfall": 0.4,
"effects": {
"fog_color": 12638463,
"sky_color": 7907327,
"water_color": 4159204,
"water_fog_color": 329011
},
"features": [],
"has_precipitation": false,
"spawn_costs": {},
"spawners": {
"ambient": [],
"axolotls": [],
"creature": [],
"misc": [],
"monster": [],
"underground_water_creature": [],
"water_ambient": [],
"water_creature": []
},
"temperature": 0.8
}

View file

@ -16,6 +16,8 @@
package net.fabricmc.fabric.test.biome;
import com.google.common.base.Preconditions;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.tag.TagKey;
@ -57,9 +59,14 @@ public class FabricBiomeTest implements ModInitializer {
@Override
public void onInitialize() {
Preconditions.checkArgument(NetherBiomes.canGenerateInNether(BiomeKeys.NETHER_WASTES));
Preconditions.checkArgument(!NetherBiomes.canGenerateInNether(BiomeKeys.END_HIGHLANDS));
NetherBiomes.addNetherBiome(BiomeKeys.PLAINS, MultiNoiseUtil.createNoiseHypercube(0.0F, 0.5F, 0.0F, 0.0F, 0.0f, 0, 0.1F));
NetherBiomes.addNetherBiome(TestBiomes.TEST_CRIMSON_FOREST, MultiNoiseUtil.createNoiseHypercube(0.0F, -0.15F, 0.0f, 0.0F, 0.0f, 0.0F, 0.2F));
Preconditions.checkArgument(NetherBiomes.canGenerateInNether(TestBiomes.TEST_CRIMSON_FOREST));
// TESTING HINT: to get to the end:
// /execute in minecraft:the_end run tp @s 0 90 0
TheEndBiomes.addHighlandsBiome(BiomeKeys.PLAINS, 5.0);
@ -92,11 +99,11 @@ public class FabricBiomeTest implements ModInitializer {
// Make sure data packs can define biomes
NetherBiomes.addNetherBiome(
RegistryKey.of(RegistryKeys.BIOME, new Identifier(MOD_ID, "example_biome")),
TestBiomes.EXAMPLE_BIOME,
MultiNoiseUtil.createNoiseHypercube(1.0f, 0.0f, 0.0f, 0.0f, 0.2f, 0.5f, 0.3f)
);
TheEndBiomes.addHighlandsBiome(
RegistryKey.of(RegistryKeys.BIOME, new Identifier(MOD_ID, "example_biome")),
TestBiomes.EXAMPLE_BIOME,
10.0
);
}

View file

@ -35,6 +35,7 @@ import net.minecraft.world.gen.feature.EndPlacedFeatures;
import net.minecraft.world.gen.feature.PlacedFeature;
public final class TestBiomes {
public static final RegistryKey<Biome> EXAMPLE_BIOME = RegistryKey.of(RegistryKeys.BIOME, new Identifier(FabricBiomeTest.MOD_ID, "example_biome"));
public static final RegistryKey<Biome> TEST_CRIMSON_FOREST = RegistryKey.of(RegistryKeys.BIOME, new Identifier(FabricBiomeTest.MOD_ID, "test_crimson_forest"));
public static final RegistryKey<Biome> CUSTOM_PLAINS = RegistryKey.of(RegistryKeys.BIOME, new Identifier(FabricBiomeTest.MOD_ID, "custom_plains"));
public static final RegistryKey<Biome> TEST_END_HIGHLANDS = RegistryKey.of(RegistryKeys.BIOME, new Identifier(FabricBiomeTest.MOD_ID, "test_end_highlands"));
@ -48,6 +49,7 @@ public final class TestBiomes {
RegistryEntryLookup<PlacedFeature> placedFeatures = biomeRegisterable.getRegistryLookup(RegistryKeys.PLACED_FEATURE);
RegistryEntryLookup<ConfiguredCarver<?>> configuredCarvers = biomeRegisterable.getRegistryLookup(RegistryKeys.CONFIGURED_CARVER);
biomeRegisterable.register(EXAMPLE_BIOME, createExample());
biomeRegisterable.register(TEST_CRIMSON_FOREST, TheNetherBiomeCreator.createCrimsonForest(placedFeatures, configuredCarvers));
biomeRegisterable.register(CUSTOM_PLAINS, OverworldBiomeCreator.createPlains(placedFeatures, configuredCarvers, false, false, false));
biomeRegisterable.register(TEST_END_HIGHLANDS, createEndHighlands(placedFeatures));
@ -55,6 +57,28 @@ public final class TestBiomes {
biomeRegisterable.register(TEST_END_BARRRENS, createEndBarrens());
}
private static Biome createExample() {
return new Biome.Builder()
.temperature(0.8f)
.downfall(0.4f)
.precipitation(false)
.effects(
new BiomeEffects.Builder()
.skyColor(7907327)
.fogColor(12638463)
.waterColor(4159204)
.waterFogColor(329011)
.build()
)
.spawnSettings(
new SpawnSettings.Builder().build()
)
.generationSettings(
new GenerationSettings.Builder().build()
)
.build();
}
private static Biome createEndHighlands(RegistryEntryLookup<PlacedFeature> placedFeatures) {
GenerationSettings.Builder builder = new GenerationSettings.Builder()
.feature(GenerationStep.Feature.SURFACE_STRUCTURES, placedFeatures.getOrThrow(EndPlacedFeatures.END_GATEWAY_RETURN));

View file

@ -1,15 +0,0 @@
{
"temperature": 0.8,
"downfall": 0.4,
"has_precipitation": true,
"effects": {
"sky_color": 7907327,
"fog_color": 12638463,
"water_color": 4159204,
"water_fog_color": 329011
},
"spawners": {},
"spawn_costs": {},
"carvers": {},
"features": []
}

View file

@ -16,6 +16,7 @@
package net.fabricmc.fabric.mixin.datagen;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
@ -31,14 +32,15 @@ import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import net.minecraft.data.DataWriter;
import net.minecraft.data.server.tag.TagProvider;
import net.minecraft.registry.tag.TagBuilder;
import net.minecraft.registry.tag.TagEntry;
import net.minecraft.util.Identifier;
import net.fabricmc.fabric.impl.datagen.FabricTagBuilder;
@Mixin(TagProvider.class)
public class TagProviderMixin {
@Inject(method = "method_27046", at = @At(value = "INVOKE", target = "Lnet/minecraft/data/DataOutput$PathResolver;resolveJson(Lnet/minecraft/util/Identifier;)Ljava/nio/file/Path;"), locals = LocalCapture.CAPTURE_FAILHARD)
public void addReplaced(Predicate<?> p, DataWriter dataWriter, Map.Entry<?, ?> entry, CallbackInfoReturnable<CompletableFuture<?>> ci, Identifier id, TagBuilder builder, List list, List list2, JsonElement jsonElement) {
@Inject(method = "method_27046", at = @At(value = "INVOKE", target = "Lnet/minecraft/data/DataProvider;writeToPath(Lnet/minecraft/data/DataWriter;Lcom/google/gson/JsonElement;Ljava/nio/file/Path;)Ljava/util/concurrent/CompletableFuture;"), locals = LocalCapture.CAPTURE_FAILHARD)
public void addReplaced(Predicate<Identifier> predicate, Predicate<Identifier> predicate2, DataWriter dataWriter, Map.Entry<Identifier, TagBuilder> entry, CallbackInfoReturnable<CompletableFuture<?>> cir, Identifier identifier, TagBuilder builder, List<TagEntry> list, List<TagEntry> list2, JsonElement jsonElement, Path path) {
if (builder instanceof FabricTagBuilder fabricTagBuilder) {
jsonElement.getAsJsonObject().addProperty("replace", fabricTagBuilder.fabric_isReplaced());
}

View file

@ -48,7 +48,7 @@ public abstract class MinecraftServerMixin {
ServerLifecycleEvents.SERVER_STARTING.invoker().onServerStarting((MinecraftServer) (Object) this);
}
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;method_49385()Lnet/minecraft/server/ServerMetadata;", ordinal = 0), method = "runServer")
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;createMetadata()Lnet/minecraft/server/ServerMetadata;", ordinal = 0), method = "runServer")
private void afterSetupServer(CallbackInfo info) {
ServerLifecycleEvents.SERVER_STARTED.invoker().onServerStarted((MinecraftServer) (Object) this);
}

View file

@ -65,7 +65,7 @@ public abstract class ServerPlayerEntityMixin extends PlayerEntity {
this.closeHandledScreen();
} else {
// Called by closeHandledScreen in vanilla
this.closeScreenHandler();
this.onHandledScreenClosed();
}
}

View file

@ -86,7 +86,7 @@ public class HopperBlockEntityMixin {
if (inputInventory != null) return;
// Otherwise inject our transfer logic.
BlockPos sourcePos = new BlockPos(hopper.getHopperX(), hopper.getHopperY() + 1.0D, hopper.getHopperZ());
BlockPos sourcePos = BlockPos.method_49637(hopper.getHopperX(), hopper.getHopperY() + 1.0D, hopper.getHopperZ());
Storage<ItemVariant> source = ItemStorage.SIDED.find(world, sourcePos, Direction.DOWN);
if (source != null) {

View file

@ -2,9 +2,9 @@ org.gradle.jvmargs=-Xmx2560M
org.gradle.parallel=true
fabric.loom.multiProjectOptimisation=true
version=0.74.1
minecraft_version=23w07a
yarn_version=+build.3
version=0.74.2
minecraft_version=1.19.4-pre1
yarn_version=+build.1
loader_version=0.14.14
installer_version=0.11.1
@ -12,52 +12,52 @@ prerelease=true
# Do not manually update, use the bumpversions task:
fabric-api-base-version=0.4.23
fabric-api-lookup-api-v1-version=1.6.23
fabric-biome-api-v1-version=13.0.3
fabric-api-lookup-api-v1-version=1.6.24
fabric-biome-api-v1-version=13.0.4
fabric-block-api-v1-version=1.0.5
fabric-blockrenderlayer-v1-version=1.1.32
fabric-command-api-v1-version=1.2.24
fabric-command-api-v2-version=2.2.3
fabric-commands-v0-version=0.2.41
fabric-containers-v0-version=0.1.49
fabric-content-registries-v0-version=3.5.5
fabric-command-api-v1-version=1.2.25
fabric-command-api-v2-version=2.2.4
fabric-commands-v0-version=0.2.42
fabric-containers-v0-version=0.1.50
fabric-content-registries-v0-version=3.5.6
fabric-crash-report-info-v1-version=0.2.14
fabric-data-generation-api-v1-version=11.3.1
fabric-data-generation-api-v1-version=11.3.2
fabric-dimensions-v1-version=2.1.44
fabric-entity-events-v1-version=1.5.12
fabric-events-interaction-v0-version=0.4.42
fabric-events-lifecycle-v0-version=0.2.49
fabric-events-lifecycle-v0-version=0.2.50
fabric-game-rule-api-v1-version=1.0.32
fabric-gametest-api-v1-version=1.2.0
fabric-item-api-v1-version=2.1.14
fabric-item-group-api-v1-version=3.0.1
fabric-gametest-api-v1-version=1.2.1
fabric-item-api-v1-version=2.1.15
fabric-item-group-api-v1-version=3.0.2
fabric-key-binding-api-v1-version=1.0.32
fabric-keybindings-v0-version=0.2.30
fabric-lifecycle-events-v1-version=2.2.13
fabric-loot-api-v2-version=1.1.23
fabric-loot-tables-v1-version=1.1.27
fabric-lifecycle-events-v1-version=2.2.14
fabric-loot-api-v2-version=1.1.24
fabric-loot-tables-v1-version=1.1.28
fabric-message-api-v1-version=5.0.16
fabric-mining-level-api-v1-version=2.1.35
fabric-mining-level-api-v1-version=2.1.36
fabric-models-v0-version=0.3.29
fabric-networking-api-v1-version=1.2.19
fabric-networking-v0-version=0.3.36
fabric-object-builder-api-v1-version=6.0.0
fabric-networking-api-v1-version=1.2.20
fabric-networking-v0-version=0.3.37
fabric-object-builder-api-v1-version=7.0.0
fabric-particles-v1-version=1.0.22
fabric-recipe-api-v1-version=1.0.3
fabric-registry-sync-v0-version=2.0.7
fabric-recipe-api-v1-version=1.0.4
fabric-registry-sync-v0-version=2.0.8
fabric-renderer-api-v1-version=2.2.3
fabric-renderer-indigo-version=1.0.1
fabric-renderer-registries-v1-version=3.2.35
fabric-renderer-registries-v1-version=3.2.36
fabric-rendering-data-attachment-v1-version=0.3.27
fabric-rendering-fluids-v1-version=3.0.20
fabric-rendering-v0-version=1.1.38
fabric-rendering-v1-version=2.0.1
fabric-rendering-v0-version=1.1.39
fabric-rendering-v1-version=2.0.2
fabric-resource-conditions-api-v1-version=2.3.0
fabric-resource-loader-v0-version=0.10.8
fabric-resource-loader-v0-version=0.10.9
fabric-screen-api-v1-version=1.0.43
fabric-screen-handler-api-v1-version=1.3.15
fabric-screen-handler-api-v1-version=1.3.16
fabric-sound-api-v1-version=1.0.8
fabric-transfer-api-v1-version=2.1.19
fabric-transitive-access-wideners-v1-version=3.0.1
fabric-transfer-api-v1-version=2.1.20
fabric-transitive-access-wideners-v1-version=3.0.2
fabric-convention-tags-v1-version=1.2.4
fabric-client-tags-api-v1-version=1.0.14