Add DataGeneratorEntrypoint.buildRegistry ()

This commit is contained in:
modmuss50 2022-11-24 15:05:09 +00:00 committed by GitHub
parent 91f53ef5b6
commit ceb5661e2d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 251 additions and 52 deletions
fabric-biome-api-v1/src/testmod
generated/data/fabric-biome-api-v1-testmod/tags/worldgen/biome
java/net/fabricmc/fabric/test/biome
fabric-data-generation-api-v1

View file

@ -0,0 +1,7 @@
{
"replace": false,
"values": [
"fabric-biome-api-v1-testmod:custom_plains",
"fabric-biome-api-v1-testmod:test_end_highlands"
]
}

View file

@ -16,6 +16,9 @@
package net.fabricmc.fabric.test.biome;
import net.minecraft.registry.RegistryBuilder;
import net.minecraft.registry.RegistryKeys;
import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator;
public class DataGeneratorEntrypoint implements net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint {
@ -23,5 +26,11 @@ public class DataGeneratorEntrypoint implements net.fabricmc.fabric.api.datagen.
public void onInitializeDataGenerator(FabricDataGenerator dataGenerator) {
FabricDataGenerator.Pack pack = dataGenerator.createPack();
pack.addProvider(WorldgenProvider::new);
pack.addProvider(TestBiomeTagProvider::new);
}
@Override
public void buildRegistry(RegistryBuilder registryBuilder) {
registryBuilder.addRegistry(RegistryKeys.BIOME, TestBiomes::bootstrap);
}
}

View file

@ -16,11 +16,10 @@
package net.fabricmc.fabric.test.biome;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.tag.TagKey;
import net.minecraft.util.Identifier;
import net.minecraft.registry.RegistryKey;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.BiomeKeys;
import net.minecraft.world.biome.source.util.MultiNoiseUtil;
import net.minecraft.world.gen.GenerationStep;
@ -47,12 +46,6 @@ import net.fabricmc.fabric.api.biome.v1.TheEndBiomes;
public class FabricBiomeTest implements ModInitializer {
public static final String MOD_ID = "fabric-biome-api-v1-testmod";
public static final RegistryKey<Biome> TEST_CRIMSON_FOREST = RegistryKey.of(RegistryKeys.BIOME, new Identifier(MOD_ID, "test_crimson_forest"));
public static final RegistryKey<Biome> CUSTOM_PLAINS = RegistryKey.of(RegistryKeys.BIOME, new Identifier(MOD_ID, "custom_plains"));
public static final RegistryKey<Biome> TEST_END_HIGHLANDS = RegistryKey.of(RegistryKeys.BIOME, new Identifier(MOD_ID, "test_end_highlands"));
public static final RegistryKey<Biome> TEST_END_MIDLANDS = RegistryKey.of(RegistryKeys.BIOME, new Identifier(MOD_ID, "test_end_midlands"));
public static final RegistryKey<Biome> TEST_END_BARRRENS = RegistryKey.of(RegistryKeys.BIOME, new Identifier(MOD_ID, "test_end_barrens"));
public static final RegistryKey<ConfiguredFeature<?, ?>> COMMON_DESERT_WELL = RegistryKey.of(
RegistryKeys.CONFIGURED_FEATURE,
new Identifier(FabricBiomeTest.MOD_ID, "fab_desert_well")
@ -65,14 +58,14 @@ public class FabricBiomeTest implements ModInitializer {
@Override
public void onInitialize() {
NetherBiomes.addNetherBiome(BiomeKeys.PLAINS, MultiNoiseUtil.createNoiseHypercube(0.0F, 0.5F, 0.0F, 0.0F, 0.0f, 0, 0.1F));
NetherBiomes.addNetherBiome(TEST_CRIMSON_FOREST, MultiNoiseUtil.createNoiseHypercube(0.0F, -0.15F, 0.0f, 0.0F, 0.0f, 0.0F, 0.2F));
NetherBiomes.addNetherBiome(TestBiomes.TEST_CRIMSON_FOREST, MultiNoiseUtil.createNoiseHypercube(0.0F, -0.15F, 0.0f, 0.0F, 0.0f, 0.0F, 0.2F));
// TESTING HINT: to get to the end:
// /execute in minecraft:the_end run tp @s 0 90 0
TheEndBiomes.addHighlandsBiome(BiomeKeys.PLAINS, 5.0);
TheEndBiomes.addHighlandsBiome(TEST_END_HIGHLANDS, 5.0);
TheEndBiomes.addMidlandsBiome(TEST_END_HIGHLANDS, TEST_END_MIDLANDS, 10.0);
TheEndBiomes.addBarrensBiome(TEST_END_HIGHLANDS, TEST_END_BARRRENS, 10.0);
TheEndBiomes.addHighlandsBiome(TestBiomes.TEST_END_HIGHLANDS, 5.0);
TheEndBiomes.addMidlandsBiome(TestBiomes.TEST_END_HIGHLANDS, TestBiomes.TEST_END_MIDLANDS, 10.0);
TheEndBiomes.addBarrensBiome(TestBiomes.TEST_END_HIGHLANDS, TestBiomes.TEST_END_BARRRENS, 10.0);
BiomeModifications.create(new Identifier("fabric:test_mod"))
.add(ModificationPhase.ADDITIONS,

View file

@ -0,0 +1,41 @@
/*
* 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.test.biome;
import java.util.concurrent.CompletableFuture;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.registry.tag.TagKey;
import net.minecraft.util.Identifier;
import net.minecraft.world.biome.Biome;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider;
public class TestBiomeTagProvider extends FabricTagProvider<Biome> {
public TestBiomeTagProvider(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture) {
super(output, RegistryKeys.BIOME, registriesFuture);
}
@Override
protected void configure(RegistryWrapper.WrapperLookup registries) {
getOrCreateTagBuilder(TagKey.of(RegistryKeys.BIOME, new Identifier(FabricBiomeTest.MOD_ID, "biome_tag_test")))
.add(TestBiomes.CUSTOM_PLAINS)
.add(TestBiomes.TEST_END_HIGHLANDS);
}
}

View file

@ -0,0 +1,80 @@
/*
* 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.test.biome;
import net.minecraft.registry.Registerable;
import net.minecraft.registry.RegistryEntryLookup;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.sound.BiomeMoodSound;
import net.minecraft.util.Identifier;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.BiomeEffects;
import net.minecraft.world.biome.GenerationSettings;
import net.minecraft.world.biome.OverworldBiomeCreator;
import net.minecraft.world.biome.SpawnSettings;
import net.minecraft.world.biome.TheNetherBiomeCreator;
import net.minecraft.world.gen.GenerationStep;
import net.minecraft.world.gen.carver.ConfiguredCarver;
import net.minecraft.world.gen.feature.DefaultBiomeFeatures;
import net.minecraft.world.gen.feature.EndPlacedFeatures;
import net.minecraft.world.gen.feature.PlacedFeature;
public final class TestBiomes {
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"));
public static final RegistryKey<Biome> TEST_END_MIDLANDS = RegistryKey.of(RegistryKeys.BIOME, new Identifier(FabricBiomeTest.MOD_ID, "test_end_midlands"));
public static final RegistryKey<Biome> TEST_END_BARRRENS = RegistryKey.of(RegistryKeys.BIOME, new Identifier(FabricBiomeTest.MOD_ID, "test_end_barrens"));
private TestBiomes() {
}
public static void bootstrap(Registerable<Biome> biomeRegisterable) {
RegistryEntryLookup<PlacedFeature> placedFeatures = biomeRegisterable.getRegistryLookup(RegistryKeys.PLACED_FEATURE);
RegistryEntryLookup<ConfiguredCarver<?>> configuredCarvers = biomeRegisterable.getRegistryLookup(RegistryKeys.CONFIGURED_CARVER);
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));
biomeRegisterable.register(TEST_END_MIDLANDS, createEndMidlands());
biomeRegisterable.register(TEST_END_BARRRENS, createEndBarrens());
}
private static Biome createEndHighlands(RegistryEntryLookup<PlacedFeature> placedFeatures) {
GenerationSettings.Builder builder = new GenerationSettings.Builder()
.feature(GenerationStep.Feature.SURFACE_STRUCTURES, placedFeatures.getOrThrow(EndPlacedFeatures.END_GATEWAY_RETURN));
return composeEndSpawnSettings(builder);
}
private static Biome createEndMidlands() {
GenerationSettings.Builder builder = (new GenerationSettings.Builder());
return composeEndSpawnSettings(builder);
}
private static Biome createEndBarrens() {
GenerationSettings.Builder builder = (new GenerationSettings.Builder());
return composeEndSpawnSettings(builder);
}
private static Biome composeEndSpawnSettings(GenerationSettings.Builder builder) {
SpawnSettings.Builder builder2 = new SpawnSettings.Builder();
DefaultBiomeFeatures.addPlainsMobs(builder2);
return (new Biome.Builder()).precipitation(Biome.Precipitation.NONE).temperature(0.5F).downfall(0.5F).effects((new BiomeEffects.Builder()).waterColor(4159204).waterFogColor(329011).fogColor(10518688).skyColor(0).moodSound(
BiomeMoodSound.CAVE).build()).spawnSettings(builder2.build()).generationSettings(builder.build()).build();
}
}

View file

@ -19,20 +19,13 @@ package net.fabricmc.fabric.test.biome;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.sound.BiomeMoodSound;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.BiomeEffects;
import net.minecraft.world.biome.GenerationSettings;
import net.minecraft.world.biome.OverworldBiomeCreator;
import net.minecraft.world.biome.SpawnSettings;
import net.minecraft.world.biome.TheNetherBiomeCreator;
import net.minecraft.world.gen.GenerationStep;
import net.minecraft.world.gen.feature.ConfiguredFeature;
import net.minecraft.world.gen.feature.DefaultBiomeFeatures;
import net.minecraft.world.gen.feature.DefaultFeatureConfig;
import net.minecraft.world.gen.feature.EndPlacedFeatures;
import net.minecraft.world.gen.feature.Feature;
import net.minecraft.world.gen.feature.PlacedFeature;
import net.minecraft.world.gen.feature.PlacedFeatures;
@ -49,12 +42,19 @@ public class WorldgenProvider extends FabricDynamicRegistryProvider {
@Override
protected void configure(RegistryWrapper.WrapperLookup registries, Entries entries) {
entries.add(FabricBiomeTest.TEST_CRIMSON_FOREST, TheNetherBiomeCreator.createCrimsonForest(entries.placedFeatures(), entries.configuredCarvers()));
entries.add(FabricBiomeTest.CUSTOM_PLAINS, OverworldBiomeCreator.createPlains(entries.placedFeatures(), entries.configuredCarvers(), false, false, false));
entries.add(FabricBiomeTest.TEST_END_HIGHLANDS, createEndHighlands(entries));
;
entries.add(FabricBiomeTest.TEST_END_MIDLANDS, createEndMidlands(entries));
entries.add(FabricBiomeTest.TEST_END_BARRRENS, createEndBarrens(entries));
final RegistryWrapper.Impl<Biome> biomeRegistry = registries.getWrapperOrThrow(RegistryKeys.BIOME);
List<RegistryKey<Biome>> allBiomes = List.of(
TestBiomes.TEST_CRIMSON_FOREST,
TestBiomes.CUSTOM_PLAINS,
TestBiomes.TEST_END_HIGHLANDS,
TestBiomes.TEST_END_MIDLANDS,
TestBiomes.TEST_END_BARRRENS
);
for (RegistryKey<Biome> biomeRegistryKey : allBiomes) {
entries.add(biomeRegistryKey, biomeRegistry.getOrThrow(biomeRegistryKey).value());
}
ConfiguredFeature<?, ?> COMMON_DESERT_WELL = new ConfiguredFeature<>(Feature.DESERT_WELL, DefaultFeatureConfig.INSTANCE);
@ -69,27 +69,4 @@ public class WorldgenProvider extends FabricDynamicRegistryProvider {
public String getName() {
return "Fabric Biome Testmod";
}
// These are used for testing the spacing of custom end biomes.
private static Biome createEndHighlands(Entries entries) {
GenerationSettings.Builder builder = new GenerationSettings.Builder()
.feature(GenerationStep.Feature.SURFACE_STRUCTURES, entries.ref(EndPlacedFeatures.END_GATEWAY_RETURN));
return composeEndSpawnSettings(builder);
}
public static Biome createEndMidlands(Entries entries) {
GenerationSettings.Builder builder = (new GenerationSettings.Builder());
return composeEndSpawnSettings(builder);
}
public static Biome createEndBarrens(Entries entries) {
GenerationSettings.Builder builder = (new GenerationSettings.Builder());
return composeEndSpawnSettings(builder);
}
private static Biome composeEndSpawnSettings(GenerationSettings.Builder builder) {
SpawnSettings.Builder builder2 = new SpawnSettings.Builder();
DefaultBiomeFeatures.addPlainsMobs(builder2);
return (new Biome.Builder()).precipitation(Biome.Precipitation.NONE).temperature(0.5F).downfall(0.5F).effects((new BiomeEffects.Builder()).waterColor(4159204).waterFogColor(329011).fogColor(10518688).skyColor(0).moodSound(BiomeMoodSound.CAVE).build()).spawnSettings(builder2.build()).generationSettings(builder.build()).build();
}
}

View file

@ -18,6 +18,8 @@ package net.fabricmc.fabric.api.datagen.v1;
import org.jetbrains.annotations.Nullable;
import net.minecraft.registry.RegistryBuilder;
/**
* An entry point for data generation.
*
@ -45,4 +47,14 @@ public interface DataGeneratorEntrypoint {
default String getEffectiveModId() {
return null;
}
/**
* Build a registry containing dynamic registry entries.
*
* <p>This is invoked asynchronously.
*
* @param registryBuilder a {@link RegistryBuilder} instance
*/
default void buildRegistry(RegistryBuilder registryBuilder) {
}
}

View file

@ -18,6 +18,8 @@ package net.fabricmc.fabric.impl.datagen;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
@ -25,6 +27,7 @@ import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import com.mojang.logging.LogUtils;
import com.mojang.serialization.Lifecycle;
import org.apache.commons.lang3.ArrayUtils;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
@ -32,7 +35,13 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.minecraft.registry.BuiltinRegistries;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.registry.Registerable;
import net.minecraft.registry.Registries;
import net.minecraft.registry.RegistryBuilder;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.util.Util;
import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint;
import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator;
@ -96,8 +105,9 @@ public final class FabricDataGenHelper {
DataGeneratorEntrypoint.class.getName(), ENTRYPOINT_KEY);
}
// Load the registries synchronously
CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture = CompletableFuture.completedFuture(BuiltinRegistries.createWrapperLookup());
// Ensure that the DataGeneratorEntrypoint is constructed on the main thread.
final List<DataGeneratorEntrypoint> entrypoints = dataGeneratorInitializers.stream().map(EntrypointContainer::getEntrypoint).toList();
CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture = CompletableFuture.supplyAsync(() -> createRegistryWrapper(entrypoints), Util.getMainWorkerExecutor());
for (EntrypointContainer<DataGeneratorEntrypoint> entrypointContainer : dataGeneratorInitializers) {
final String id = entrypointContainer.getProvider().getMetadata().getId();
@ -128,6 +138,66 @@ public final class FabricDataGenHelper {
}
}
private static RegistryWrapper.WrapperLookup createRegistryWrapper(List<DataGeneratorEntrypoint> dataGeneratorInitializers) {
// Build a list of all the RegistryBuilder's including vanilla's
List<RegistryBuilder> builders = new ArrayList<>();
builders.add(BuiltinRegistries.REGISTRY_BUILDER);
for (DataGeneratorEntrypoint entrypoint : dataGeneratorInitializers) {
final var registryBuilder = new RegistryBuilder();
entrypoint.buildRegistry(registryBuilder);
builders.add(registryBuilder);
}
// Collect all the bootstrap functions, and merge the lifecycles.
class BuilderData {
final RegistryKey key;
List<RegistryBuilder.BootstrapFunction<?>> bootstrapFunctions;
Lifecycle lifecycle;
BuilderData(RegistryKey key) {
this.key = key;
this.bootstrapFunctions = new ArrayList<>();
this.lifecycle = null;
}
void with(RegistryBuilder.RegistryInfo<?> registryInfo) {
bootstrapFunctions.add(registryInfo.bootstrap());
lifecycle = registryInfo.lifecycle().add(lifecycle);
}
void apply(RegistryBuilder builder) {
builder.addRegistry(key, lifecycle, this::bootstrap);
}
void bootstrap(Registerable registerable) {
for (RegistryBuilder.BootstrapFunction<?> function : bootstrapFunctions) {
function.run(registerable);
}
}
}
Map<RegistryKey<?>, BuilderData> builderDataMap = new HashMap<>();
for (RegistryBuilder builder : builders) {
for (RegistryBuilder.RegistryInfo<?> info : builder.registries) {
builderDataMap.computeIfAbsent(info.key(), BuilderData::new)
.with(info);
}
}
// Apply all the builders into one.
RegistryBuilder merged = new RegistryBuilder();
for (BuilderData value : builderDataMap.values()) {
value.apply(merged);
}
RegistryWrapper.WrapperLookup wrapperLookup = merged.createWrapperLookup(DynamicRegistryManager.of(Registries.REGISTRIES));
BuiltinRegistries.validate(wrapperLookup);
return wrapperLookup;
}
/**
* Used to keep track of conditions associated to generated objects.
*/

View file

@ -25,6 +25,11 @@ accessible field net/minecraft/data/DataOutput$PathResolver directoryName
extendable method net/minecraft/data/DataGenerator$Pack <init> (Lnet/minecraft/data/DataGenerator;ZLjava/lang/String;Lnet/minecraft/data/DataOutput;)V
accessible field net/minecraft/registry/BuiltinRegistries REGISTRY_BUILDER Lnet/minecraft/registry/RegistryBuilder;
accessible method net/minecraft/registry/BuiltinRegistries validate (Lnet/minecraft/registry/RegistryWrapper$WrapperLookup;)V
accessible field net/minecraft/registry/RegistryBuilder registries Ljava/util/List;
accessible class net/minecraft/registry/RegistryBuilder$RegistryInfo
transitive-accessible method net/minecraft/data/family/BlockFamilies register (Lnet/minecraft/block/Block;)Lnet/minecraft/data/family/BlockFamily$Builder;
transitive-accessible field net/minecraft/data/client/BlockStateModelGenerator blockStateCollector Ljava/util/function/Consumer;

View file

@ -25,6 +25,11 @@ accessible field net/minecraft/data/DataOutput$PathResolver directoryName
extendable method net/minecraft/data/DataGenerator$Pack <init> (Lnet/minecraft/data/DataGenerator;ZLjava/lang/String;Lnet/minecraft/data/DataOutput;)V
accessible field net/minecraft/registry/BuiltinRegistries REGISTRY_BUILDER Lnet/minecraft/registry/RegistryBuilder;
accessible method net/minecraft/registry/BuiltinRegistries validate (Lnet/minecraft/registry/RegistryWrapper$WrapperLookup;)V
accessible field net/minecraft/registry/RegistryBuilder registries Ljava/util/List;
accessible class net/minecraft/registry/RegistryBuilder$RegistryInfo
transitive-accessible method net/minecraft/data/family/BlockFamilies register (Lnet/minecraft/block/Block;)Lnet/minecraft/data/family/BlockFamily$Builder;
transitive-accessible field net/minecraft/data/client/BlockStateModelGenerator blockStateCollector Ljava/util/function/Consumer;