[1.16.3] The configuredfeature form of Bee Nest Feature should be registered
TelepathicGrunt opened this issue ยท 7 comments
Hello! I was testing out ResourceBees Mod with my own mods and had found that the ConfiguredFeature form of the Bee Nest Feature ( resourcefulbees:bee_nest_feature ) is not registered. This can be an issue for mod compatibility as under certain conditions, unregistered ConfiguredFeatures can basically prevent other mod's registered ConfiguredFeatures from spawning if in the same generation stage.
By that I mean, if mod A adds an unregistered CF to the ore generation stage and the biome's codec reaches it first, it will choke and basically nuke mob B's registered CFs afterwards. Here's a case where BetterCaves forgot to register their CF and caused several CFs from Oh The Biomes You'll Go to stop spawning in the world: YUNG-GANG/YUNGs-Better-Caves#75
Here's a more detailed explanation of why this happens in the biome's codec:
Specifically, when you call .withConfiguration on a Feature, you create a ConfiguredFeature. This is what should be registered to the WorldgenRegisties.
Here's an example from my mod RepurposedStructures of me registering all my ConfiguredFeatures in case you plan on adding more and want to see one way of organizing everything.
https://github.com/TelepathicGrunt/RepurposedStructures/blob/a4e3365e3867b8510952ebf658c415de6e412927/src/main/java/com/telepathicgrunt/repurposedstructures/RSConfiguredFeatures.java#L184-L185
I hope this helps!
I will take a look at that. Thank you very much for the info! I was not aware of the need for the registration :)
Hopefully I did this right. The world gen stuff is one area I really need to learn more about. I basically followed vanilla stuff (for the most part I suppose) but I don't fully understand what actually is happening during the generation phase. I tend to just keep tweaking numbers until I get something that seems OK.
Anyway code still needs to get committed and pushed but this is what I have now:
https://gist.github.com/7ea015d9020d5116462a6ba8681e44ea
By tweaking numbers, do you mean the ChanceConfig part after Placement.CHANCE? That's the chance of that feature picking a location for that chunk. It is 1/n with n being the number you pass in. So ChanceConfig(100) would be 1/100 chance of that one chunk attempting to spawn your feature.
The Placement.HEIGHTMAP_WORLD_SURFACE and Placement.TOP_SOLID_HEIGHTMAP picks a random spot on the chunk at the top of the terrain. Well, TOP_SOLID_HEIGHTMAP I think can return a position on top of the solid blocks placed by another feature but HEIGHTMAP_WORLD_SURFACE should be the terrain surface mostly.
Let me know if there anything else that's a bit confusing. but otherwise, that gist looks correct to me!
yeah I figured out the chance config and how that worked. It was more so the rest of the placements and what each one did. There's not much info available to explain what each one is for or why it should be picked over another one. so trying to figure out what one gives me what I'm looking for is a bit difficult.
For example I had to make the nether spawn nests much more frequently than the overworld bc the way the nether terrain works, the nests were extremely difficult to find compared to the overworld surface.
Also I have to tweak the code in the gist a bit. Mod doesn't load bc of the deferred register. is it possible to use deferred register for Configured Features? or should I just register the Bee nest Feature through the event subscriber instead so it doesn't give an NPE?
I'm not sure if deferred can even work with the configured worldgen stuff as forge does not have a registry for them. You could register configuredfeatures in FMLCommonSetupEvent safely tho. It just has to be registered at any time before a world is selected.
For the nether thing, I checked what the warped fungi do and they do .decorate(Placement.COUNT_MULTILAYER.configure(new FeatureSpreadConfig(8))
. Looking at how COUNT_MULTILAYER works, it seems like it picks a random xz spot in a chunk and then returns a list of every position in that xz spot that has a surface (ledges in nether). The 8 repeats that 8 times. That means if you find a warped fungi and go down, there should be another in the exact same spot in the ledge below which is probably what you don't want.
What I think you should do for the nether nests (which you might already be doing) is .decorate(Features.Placements.NETHER_ORE).spreadHorizontally().repeat(32)
. The repeat is how many positions you want to pick in the chunk. Then the spreadHorizontally will randomize the xz coordinate in that chunk for each position. Then the NETHER_ORE will pick a y value between 20 and 128 for each position. In your nether nest, you would add the check to see if the spot is valid (air with a solid block below or something) and that should work nicely for the most part. Though the repeat may have to be set somewhat high as the surface of ledges is a pretty small target to hit compared to the rest of the nether. There's no easy small solution for this sorry
I just wrapped the configured feature stuff in a static inner class. it was a result of static initialization for classes that caused the issue. Also searching Forge Discord I was able to find that I can just do the registration from the FMLCommonSetup Event. So I now call the registration method from there instead.
As for my nether nest generation. currently I am doing this:
.configure(IFeatureConfig.NO_FEATURE_CONFIG) .decorate(Placement.TOP_SOLID_HEIGHTMAP.configure(new NoPlacementConfig())) .decorate(Placement.CHANCE.configure(new ChanceConfig(Config.NETHER_NEST_GENERATION_CHANCE.get())));
but I'll play around with what you suggested and see what the generation looks like with it. thanks! :)
Fixed in ccb1f05
Thanks again for the info!