Jump to content
View in the app

A better way to browse. Learn more.

Forge Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Featured Replies

Posted

The end goal is to disable certain aspects of vanilla ore/feature generation so I can replace them with my own features with custom values.

 

To disable vanilla ore generation, I've created an event handler for BiomeLoadingEvent. This allows me to get the BiomeGenerationSettingsBuilder which allows me to get the list of ConfiguredFeature's for the biome associated with the event call:

 

@SubscribeEvent(priority = EventPriority.LOWEST)
public static void BiomeLoadingIntercept(final BiomeLoadingEvent event) {
    BiomeGenerationSettingsBuilder gen = event.getGeneration();
    List<Supplier<ConfiguredFeature<?, ?>>> features = gen.getFeatures(GenerationStage.Decoration.UNDERGROUND_ORES);
    
    ...
}

 

I know this list is *probably* what I need, since if I just call features.clear(), all ore generation is successfully removed from the game. However, I want to be able to remove specific ores via config file, so I need some way to either remove by registry ID, or remove by object (ex. using the objects in net.minecraft.world.gen.feature.Features).

 

I've tried a number of things that don't seem to work:

  • Looping through the features list, feature.get().getFeature().getRegistryName() always returns minecraft:decorated and never anything more specific.
  • Looping through the features list, calling ForgeRegistries.getKey(feature) always returns minecraft:decorated.
  • Looping through the features list, calling net.minecraft.util.registry.WorldGenRegistries.CONFIGURED_FEATURE.getKey(feature) always returns NULL (presumably because vanilla registries aren't used by Forge, or something).
  • Calling features.contains(Features.ORE_COAL) (for example) is always false, like the biomes never contain the coal ore feature (but they do).

 

I think the way features are applied and stacked causes the features to lose their original registry values. Is there any way I can remove specific features from biomes?

 

Thanks

Edited by noahc3
Solved

  • Author
36 minutes ago, diesieben07 said:

You need to check if ConfiguredFeature#getFeature is a DecoratedFeature. If it is, you need to use ConfiguredFeature#getConfig, which will then be a DecoratedFeatureConfig. That has DecoratedFeatureConfig#feature, which is the original feature and its configuration.

Thanks, that worked. I had to dig through the features recursively since they weren't always one level deep:

 

    @SubscribeEvent(priority = EventPriority.LOWEST)
    public static void BiomeLoadingIntercept(final BiomeLoadingEvent event) {
        BiomeGenerationSettingsBuilder gen = event.getGeneration();

        for(Supplier<ConfiguredFeature<?, ?>> f : gen.getFeatures(GenerationStage.Decoration.UNDERGROUND_ORES)) {
            ConfiguredFeature<?, ?> resolved = resolve(f.get());
            if (resolved.feature instanceof OreFeature) {
                OreFeatureConfig oreConfig = (OreFeatureConfig) resolved.config;
                Logger.info(oreConfig.state.getBlock().getRegistryName());
                
                ... compare blockstates ...
            }
        }
    }

    private static ConfiguredFeature<?, ?> resolve(ConfiguredFeature<?, ?> f) {
        if (f.getFeature() instanceof DecoratedFeature) {
            ConfiguredFeature<?, ?> subFeature = ((DecoratedFeatureConfig)f.getConfig()).feature.get();
            return resolve(subFeature);
        } else {
            return f;
        }
    }

 

This seems inefficient, is this the simplest way?

  • 3 months later...
10 minutes ago, killerjdog51 said:

How did you remove/prevent the generation? Because when I use f.remove() I get a ConcurrentModificationException.

make your own thread, explain your issue further, and post the full log

19 hours ago, killerjdog51 said:

How did you remove/prevent the generation? Because when I use f.remove() I get a ConcurrentModificationException.

This is basic java knowledge. Don't modify collections while iterating...

On 4/18/2021 at 8:19 AM, DietmarKracht said:

This is basic java knowledge. Don't modify collections while iterating...

Thanks, I switched it to an iterator and it worked. I was able to remove the features after the game had loaded but before they generated. 

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

Important Information

By using this site, you agree to our Terms of Use.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.