foundInOverworld, foundInNether, foundInEnd helper methods are not safe for modded biome sources
TelepathicGrunt opened this issue ยท 8 comments
All of Fabric team noticed that most modded ores will not spawn in BYG biomes. BYG is using Terrablender. Terrablender uses its own biome source. And Fabric API is using a field that's very specific to the vanilla overworld biome source which is bad for mod compat and is breaking modpacks using Terrablender. Instead, Fabric API should be using the overworld's biome source's possibleBiomes field that they hold always which should have all biomes that can actually spawn in overworld. Or ideally, use the existing minecraft:is_overworld
biome tag instead. This change should also be done for the nether and end helpers as well so all three helper methods functions properly regardless of the biome source used for the dimension.
These helpers seem to have issues as a somewhat similar issue happened in the past: #1703
The link you posted is from before biome tags were added.
It was discussed there that the method name is somewhat misleading.
It also discusses how the chunk generator / biome source don't exist when the biome modification happens.
It would be a breaking change to use minecraft:is_overworld in that method.
Probably no one would actually complain though. :-)
Maybe the method could be deprecated? With some javadoc saying to use:
BiomeSelectors.tag(BiomeTags.IS_OVERWORLD);
There appear to be some major changes in this area for the next minecraft release: #2632
Well it says specifically "assuming Vanilla's default biome source is used.". Since when these methods were created, it wasn't really possible to do otherwise.
warjort is completely right.
After some more digging the current running theory is that the Javadoc is incorrect, but the impl is correct.
TerraBelender injects its biomes seeming after the biome modifications have been applied here: https://github.com/Glitchfiend/TerraBlender/blob/e8c651c459a304fcd39d29d53d5407e5f5cedbe2/Fabric/src/main/java/terrablender/mixin/MixinMinecraftServer.java#L18-L19
As far as I can tell (using github, can validate it with a debugger in 30 seconds) this is after this: https://github.com/FabricMC/fabric/blob/1.18.2/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/impl/biome/modification/BiomeSelectionContextImpl.java#L105 Thus any mod using canGenerateIn wont be seeing the TB biomes.
Im happy to be wrong, but fabric seems ok to me. May be nice to figure out if there are any APIs you folks are missing so you dont need to reinvent the wheel?
Hi, sorry to randomly inject, but I'm updating my mods from 22w43a to 22w44a and I wanted to confirm that I am using the correct method to inject my ores into biomes correctly. I was getting a little confused about the discussion.
My code currently:
`
public static void addOres()
{
// Inject into Biomes
BiomeModifications.addFeature(overworldSelector(), GenerationStep.Feature.UNDERGROUND_ORES, RegistryKey.of(Registry.PLACED_FEATURE_KEY, new Identifier(Gobber2.MOD_ID, "ore_lucky_block_overworld")));
BiomeModifications.addFeature(overworldSelector(), GenerationStep.Feature.UNDERGROUND_ORES, RegistryKey.of(Registry.PLACED_FEATURE_KEY, new Identifier(Gobber2.MOD_ID, "ore_gobber_overworld")));
BiomeModifications.addFeature(netherSelector(), GenerationStep.Feature.UNDERGROUND_ORES, RegistryKey.of(Registry.PLACED_FEATURE_KEY, new Identifier(Gobber2.MOD_ID, "ore_lucky_block_nether")));
BiomeModifications.addFeature(netherSelector(), GenerationStep.Feature.UNDERGROUND_ORES, RegistryKey.of(Registry.PLACED_FEATURE_KEY, new Identifier(Gobber2.MOD_ID, "ore_gobber_nether")));
BiomeModifications.addFeature(endSelector(), GenerationStep.Feature.UNDERGROUND_ORES, RegistryKey.of(Registry.PLACED_FEATURE_KEY, new Identifier(Gobber2.MOD_ID, "ore_lucky_block_end")));
BiomeModifications.addFeature(endSelector(), GenerationStep.Feature.UNDERGROUND_ORES, RegistryKey.of(Registry.PLACED_FEATURE_KEY, new Identifier(Gobber2.MOD_ID, "ore_gobber_end")));
}
public static Predicate<BiomeSelectionContext> overworldSelector()
{
return context -> context.getBiomeRegistryEntry().isIn(BiomeTags.IS_OVERWORLD);
}
public static Predicate<BiomeSelectionContext> netherSelector()
{
return context -> context.getBiomeRegistryEntry().isIn(BiomeTags.IS_NETHER);
}
public static Predicate<BiomeSelectionContext> endSelector()
{
return context -> context.getBiomeRegistryEntry().isIn(BiomeTags.IS_END);
}
`
Well it says specifically "assuming Vanilla's default biome source is used.". Since when these methods were created, it wasn't really possible to do otherwise.
warjort is completely right.
To correct myself here by the way: The javadoc is actually incorrect. The method uses the real biome source used by the currently loading world, not just the Vanilla one.
I fixed MI's ore gen in TerraBlender biomes by using BiomeSelectors.tag(ConventionalBiomeTags.IN_OVERWORLD)
instead of BiomeSelectors.foundInOverworld()
. So this is a real issue, and the fix is easy, although I can't explain why it works.
I have opened a PR fixing this in TerraBlender here: Glitchfiend/TerraBlender#96