Created
May 1, 2022 23:45
-
-
Save Commoble/27bc6c64fc7f1023ea58e4e5aa24feab to your computer and use it in GitHub Desktop.
Registering and using configured/placed features in Forge for Minecraft 1.18.2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package commoble.featureexamplemod; | |
import java.util.List; | |
import net.minecraft.core.Registry; | |
import net.minecraft.data.worldgen.placement.PlacementUtils; | |
import net.minecraft.world.level.block.Blocks; | |
import net.minecraft.world.level.levelgen.GenerationStep.Decoration; | |
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; | |
import net.minecraft.world.level.levelgen.feature.Feature; | |
import net.minecraft.world.level.levelgen.feature.configurations.BlockPileConfiguration; | |
import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider; | |
import net.minecraft.world.level.levelgen.placement.InSquarePlacement; | |
import net.minecraft.world.level.levelgen.placement.PlacedFeature; | |
import net.minecraftforge.common.MinecraftForge; | |
import net.minecraftforge.event.world.BiomeLoadingEvent; | |
import net.minecraftforge.eventbus.api.IEventBus; | |
import net.minecraftforge.fml.common.Mod; | |
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; | |
import net.minecraftforge.registries.DeferredRegister; | |
import net.minecraftforge.registries.RegistryObject; | |
@Mod(FeatureExampleMod.MODID) | |
public class FeatureExampleMod | |
{ | |
public static final String MODID = "featureexample"; | |
private static final DeferredRegister<ConfiguredFeature<?,?>> CONFIGURED_FEATURES = | |
DeferredRegister.create(Registry.CONFIGURED_FEATURE_REGISTRY, MODID); | |
public static final DeferredRegister<PlacedFeature> PLACED_FEATURES = | |
DeferredRegister.create(Registry.PLACED_FEATURE_REGISTRY, MODID); | |
private static final String TNT_PILE_NAME = "tnt_pile"; | |
// your ConfiguredFeature RegistryObject fields must use <?,?> as the generic params for technical reasons | |
private static final RegistryObject<ConfiguredFeature<?,?>> CONFIGURED_TNT_PILE = | |
CONFIGURED_FEATURES.register(TNT_PILE_NAME, | |
// ConfiguredFeature takes a feature type and a featureconfig. | |
// You generally can't static init featureconfigs ahead of time, as they | |
// very often have hard references to blocks (such as this one does). | |
// The feature type defines the generation logic, the feature config is extra data used by that logic. | |
// Feature.BLOCK_PILE generates blocks in a pile, it takes a BlockPileConfiguration. | |
() -> new ConfiguredFeature<>(Feature.BLOCK_PILE, | |
// BlockPileConfiguration takes a blockstate provider, we use one that always provides TNT. | |
new BlockPileConfiguration(BlockStateProvider.simple(Blocks.TNT)))); | |
// A PlacedFeature is a configured feature and a list of placement modifiers. | |
// This is what goes into biomes, the placement modifiers determine where and how often to | |
// place the configured feature. | |
// Each placed feature in any of the biomes in a chunk generates in that chunk when the chunk generates. | |
// When a feature generates in a chunk, the chunk's local 0,0,0 origin coordinate is given to the | |
// list of placement modifiers (if any). | |
// Each placement modifier converts the input position to zero or more output positions, each of which | |
// is given to the next placement modifier. | |
// The ConfiguredFeature is generated at the positions generated after all placement modifiers have run. | |
private static final RegistryObject<PlacedFeature> PLACED_TNT_PILE = | |
PLACED_FEATURES.register(TNT_PILE_NAME, | |
() -> new PlacedFeature(CONFIGURED_TNT_PILE.getHolder().get(), | |
// InSquarePlacement.spread() takes the input position | |
// and randomizes the X and Z coordinates within the chunk | |
// PlacementUtils.HEIGHTMAP sets the Y-coordinate of the input position to the heightmap. | |
// This causes the tnt pile to be generated at a random surface position in the chunk. | |
List.of(InSquarePlacement.spread(), PlacementUtils.HEIGHTMAP))); | |
public FeatureExampleMod() | |
{ | |
IEventBus modBus = FMLJavaModLoadingContext.get().getModEventBus(); | |
IEventBus forgeBus = MinecraftForge.EVENT_BUS; | |
CONFIGURED_FEATURES.register(modBus); | |
PLACED_FEATURES.register(modBus); | |
forgeBus.addListener(this::onBiomeLoading); | |
} | |
// BiomeLoadingEvent can be used to add placed features to existing biomes. | |
// Placed features added in the BiomeLoadingEvent must have been previously registered. | |
// JSON features cannot be added to biomes via the BiomeLoadingEvent. | |
private void onBiomeLoading(BiomeLoadingEvent event) | |
{ | |
event.getGeneration().addFeature(Decoration.VEGETAL_DECORATION, PLACED_TNT_PILE.getHolder().get()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment