User Tools

Site Tools


tutorial:ores

This is an old revision of the document!


Generating Custom Ores [1.17]

A lot of mods add their own ores, and you'll need a way to place them in existing biomes for players to find. In this tutorial, we'll look at adding ores to existing biomes. There are 2 steps that are required to add ores to biomes.

Note that the Biome Modification API is marked as experimental. If the API doesn't work, consider using the mixin version.

We'll assume you've already created your own ore block at this point. Wool block will serve as our replacement throughout this tutorial. Replace references to wool with your ore when appropriate.

Adding to the overworld biomes

In this section, our goal will be spawning the ore in the overworld.

We need to create a ConfiguredFeature. Make sure to register your ConfiguredFeature at onInitialize. Feel free to change the values to suit your mod.

public class ExampleMod implements ModInitializer {
  private static ConfiguredFeature<?, ?> ORE_WOOL_OVERWORLD = Feature.ORE
    .configure(new OreFeatureConfig(
      OreFeatureConfig.Rules.BASE_STONE_OVERWORLD,
      Blocks.WHITE_WOOL.getDefaultState(),
      9)) // Vein size
    .range(new RangeDecoratorConfig(
      // You can also use one of the other height providers if you don't want a uniform distribution
      UniformHeightProvider.create(YOffset.aboveBottom(0), YOffset.fixed(64)))) // Inclusive min and max height
    .spreadHorizontally()
    .repeat(20); // Number of veins per chunk
 
  @Override
  public void onInitialize() {
    RegistryKey<ConfiguredFeature<?, ?>> oreWoolOverworld = RegistryKey.of(Registry.CONFIGURED_FEATURE_KEY,
      new Identifier("tutorial", "ore_wool_overworld"));
    Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, oreWoolOverworld.getValue(), ORE_WOOL_OVERWORLD);
    BiomeModifications.addFeature(BiomeSelectors.foundInOverworld(), GenerationStep.Feature.UNDERGROUND_ORES, oreWoolOverworld);
  }
}

Result

You should see wool spawning in the overworld. You can use the command below to remove stone blocks surrounding you.

/fill ~-8 0 ~-8 ~8 ~ ~8 minecraft:air replace minecraft:stone

Adding to the nether biomes

In this section, based on the code in the previous section, we will add the ore to the nether biomes.

We have to replace OreFeatureConfig.Rules.BASE_STONE_OVERWORLD with OreFeatureConfig.Rules.BASE_STONE_NETHER because the ore has to replace different blocks in the nether than in the overworld.

public class ExampleMod implements ModInitializer {
  private static ConfiguredFeature<?, ?> ORE_WOOL_NETHER = Feature.ORE
    .configure(new OreFeatureConfig(
      OreFeatureConfig.Rules.BASE_STONE_NETHER, // We use OreFeatureConfig.Rules.BASE_STONE_NETHER for the Nether
      Blocks.WHITE_WOOL.getDefaultState(),
      9))
    .range(new RangeDecoratorConfig(
      UniformHeightProvider.create(YOffset.fixed(0), YOffset.fixed(64))))
    .spreadHorizontally()
    .repeat(20);
 
  @Override
  public void onInitialize() {
    RegistryKey<ConfiguredFeature<?, ?>> oreWoolNether = RegistryKey.of(Registry.CONFIGURED_FEATURE_WORLDGEN,
        new Identifier("tutorial", "ore_wool_nether"));
    Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, oreWoolNether.getValue(), ORE_WOOL_NETHER);
    BiomeModifications.addFeature(BiomeSelectors.foundInTheNether(), GenerationStep.Feature.UNDERGROUND_ORES, oreWoolNether);
  }
}

Adding to the end biomes

In this section, based on the code in the overworld section, we will add the ore to the end biomes.

We replace OreFeatureConfig.Rules.BASE_STONE_OVERWORLD with new BlockMatchRuleTest(Blocks.END_STONE) because end stone is used as the base block in The End.

public class ExampleMod implements ModInitializer {
  private static ConfiguredFeature<?, ?> ORE_WOOL_END = Feature.ORE
    .configure(new OreFeatureConfig(
      new BlockMatchRuleTest(Blocks.END_STONE), // Base block is end stone in The End biomes
      Blocks.WHITE_WOOL.getDefaultState(),
      9))
    .range(new RangeDecoratorConfig(
      UniformHeightProvider.create(YOffset.fixed(0), YOffset.fixed(64))))
    .spreadHorizontally()
    .repeat(20);
 
  @Override
  public void onInitialize() {
    RegistryKey<ConfiguredFeature<?, ?>> oreWoolEnd = RegistryKey.of(Registry.CONFIGURED_FEATURE_KEY,
        new Identifier("tutorial", "ore_wool_end"));
    Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, oreWoolEnd.getValue(), ORE_WOOL_END);
    BiomeModifications.addFeature(BiomeSelectors.foundInTheEnd(), GenerationStep.Feature.UNDERGROUND_ORES, oreWoolEnd);
  }
}
tutorial/ores.1625221178.txt.gz · Last modified: 2021/07/02 10:19 by siglong