Closed ChimneySwift closed 4 years ago
Think I might have found the reason why and suspect this may already be known.
This method is used by the api to generate the bedrock as opposed to the vanilla method, which checks to see what bedrock needs to be generated:
private void a(IChunkAccess ichunkaccess, Random random) {
MutableBlockPosition blockposition_mutableblockposition = new MutableBlockPosition();
int i = ichunkaccess.getPos().d();
int j = ichunkaccess.getPos().e();
GeneratorSettingBase generatorsettingbase = (GeneratorSettingBase)this.h.get();
int k = generatorsettingbase.f();
int floorHeight = k;
int l = this.x - 1 - generatorsettingbase.e();
int roofHeight = l;
boolean flag = true;
boolean flag1 = l + 4 >= 0 && l < this.x;
boolean flag2 = k + 4 >= 0 && k < this.x;
if (flag1 || flag2) {
Iterator iterator = BlockPosition.b(i, 0, j, i + 15, 0, j + 15).iterator();
while(true) {
BlockPosition blockposition;
int i1;
do {
if (!iterator.hasNext()) {
return;
}
blockposition = (BlockPosition)iterator.next();
if (flag1) {
for(i1 = 0; i1 < 5; ++i1) {
if (i1 <= (ichunkaccess.generateFlatBedrock() ? roofHeight : random.nextInt(5))) {
ichunkaccess.setType(blockposition_mutableblockposition.d(blockposition.getX(), l - i1, blockposition.getZ()), Blocks.BEDROCK.getBlockData(), false);
}
}
}
} while(!flag2);
for(i1 = 4; i1 >= 0; --i1) {
if (i1 <= (ichunkaccess.generateFlatBedrock() ? floorHeight : random.nextInt(5))) {
ichunkaccess.setType(blockposition_mutableblockposition.d(blockposition.getX(), k + i1, blockposition.getZ()), Blocks.BEDROCK.getBlockData(), false);
}
}
}
}
}
Not sure if it's possible to implement this in the api but I'll see if I can get something working, otherwise I'll just replace the default generator with my own based off vanilla behaviour.
Edit: Note I'm using Paper, so some things like ichunkaccess.generateFlatBedrock()
are exclusive to Paper.
Suprising to see that it already kind of works with other dimensions. At least, I see that the chorus plants are generating.
A quick workaround would be to just disable bedrock (generator.getWorldDecorator().withoutDefaultBaseDecorations(BaseDecorationType.BEDROCK);
). But the proper fix would be to let the terrain generator use the settings from the correct dimension. If you can get that working, that would be great, otherwise I can also try to find some time for this.
Yeah I didn't notice any abnormalities in either of the other dimensions, just the bedrock which was reimplemented.
Honestly the way I'm using this isn't really as intended anyway so I'm pretty happy it's working at all at this point.
I've found a solution, though it's not very pretty. Not sure if there's a better solution however.
Turns out the reimplementation for bedrock generation was perfectly fine, however it was receiving generator settings meant for the overworld. I logged k (floorHeight) and l (roofHeight) in the bedrock generation function and noticed they always returned 0, 265
for all world environments, even though vanilla behaviour has these values set to 0, 127
for the nether and -10, 137
for the end.
I traced the creation of the GeneratorSettingBase class which is passed into InjectedChunkGenerator to WorldGeneratorImpl.extractSettings and noticed that while the method attempts to extract the vanilla settings from the provided ChunkGenerator, if during that process an error occured it would create a default, vanilla overworld one. The addition of a stacktrace told me it always did this, and I noticed that the ChunkGenerator class has no fields containing a GeneratorSettingBase, possibly a change to NMS that wasn't noticed because the setting extractor just handled it silently.
Anyway with the help of deobfuscated NMS cause the mappings spigot uses don't really do much for GeneratorSettingBase, I made 2 additional functions which do the same as the createDefaultSettings method but for the end and the nether. Some minor modifications to extractSettings and it returned the correct GeneratorSettingBase for nether/end dimensions.
I'll make a pull request with the changes to get it to work, but issue is that for some reason there's a function to get the GeneratorSettingBase defaults for the normal env, but no similar methods for the end or the nether, so generating new ones is much more messy.
Anyway, here you can see them working correctly:
Describe the bug Pretty clear what's happening from my screenshot.
Not entirely sure what is occurring since I never touched bedrock generation, though possibly the api isn't designed to work with the end/nether, apologies if I missed something.
If you couldn't already tell, ChunkLogger only logs coordinates and doesn't touch any generation. For the end this is a fairly simple fix as I can just disable the bedrock generator, however in the nether there is also no bedrock roof.
I could resolve this by just generating a flat roof, or trying to reverse engineer the vanilla bedrock generator, but that seems like a pretty ugly solution?
To Reproduce Steps to reproduce the behavior:
Screenshots