-
Notifications
You must be signed in to change notification settings - Fork 106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Small inaccuracies in biome generation at 1:4 scale #61
Comments
Oh I know, this is caused by MC-241546 and I don't think it is possible (or at least practical) to simulate the biome that gets stored in the save files by the current version, in particular since different parts of the Minecraft code disagree anyway. |
Wait, so it's non-deterministic? |
Well there is not the one biome mapping it 1.18-rc3. If you want get the biome generation that ends up in the save file, you can try to use |
I have added a function |
Thank you! I implemented a seed -4100855569562546563 However I only see 2 pixel errors in the generated image, and with the old code there were about 25. So it's an improvement. Also I tried to generate the same world 4 times and the biomes seem to match, so I guess that the biomes that are stored in the level file are deterministic, but not 100% sure yet because generating worlds takes very long. So I will try to gather more data. |
The biomes for the chunk are generated all in one go, so the previous sampling positions are (almost) deterministic. To get an even better results you can try to also generate the chunk section below the one you are after to make sure the sampler is in the correct state. The chunk sections are generated from the bottom of the world upwards. The prime candidate for non-deterministic biomes in the level storage is just the first (0,-16,0) biome coordinate in each chunk, since this will depend on whichever chunk was generated before it. The issue with this bug is more that other parts, such as the population do their own biome generation which can disagree with the level storage. |
So maybe something like this (completely untested): int chunk_biomes[4][4][4];
for (int cz = (r.z) >> 2; cz < (r.z + r.sz) >> 2; cz++) {
for (int cx = (r.x) >> 2; cx < (r.x + r.sx) >> 2; cx++) {
uint64_t dat = 0;
int cy = (r.y) >> 2;
if (cy-1 >= -4) {
// Get a hopefully accurate biome sampler state for 'dat'
genBiomeNoiseChunkSection(&g->bn, chunk_biomes, cx, cy-1, cz, &dat);
} // else { non-deterministic start of chunk }
// Iterate over the chunk sections in vertically ascending order
for (; cy < (r.y + r.sy) >> 2; cy++) {
// Generate accurate biomes for this chunk section
genBiomeNoiseChunkSection(&g->bn, chunk_biomes, cx, cy, cz, &dat);
// Copy biomes to output buffer
for (int by = 0; by < 4; by++) {
for (int bz = 0; bz < 4; bz++) {
for (int bx = 0; bx < 4; bx++) {
int bb = chunk_biomes[bx][by][bz];
int x = (cx << 2) + bx;
int y = (cy << 2) + by;
int z = (cz << 2) + bz;
size_t idx = (x - r.x) + ((z - r.z) * r.sx) + ((y - r.y) * r.sx * r.sz);
cache[idx] = bb;
}
}
}
}
}
} |
You seem to be right! I checked the world with seed -4100855569562546563 again, with the same code, and if I skip the y-level=-16 all the other biomes match. So I can simply skip that level and check the rest. And thanks for the code example! TODO list for myself:
|
So quick update, I generated 4 worlds more, in 3 of them all the biomes match, but the last one has small differences. I used the final 1.18 release this time. Seed -7088473816240932309 I also tried to generate the world with seed -7088473816240932309 4 times and the biomes in the level files were always the same, I can't seem to find a clear example of non-determinism. Some images, at y-level=-5. Cubiomes World files Diff |
Thanks for the effort. I will have a look if I find something, but it might take a little. These types of issues are a pain to track down in the debugger.. |
After much testing and thought I have come to the conclusion that the biomes for the anvil storage will indeed be deterministic, since the last sampling result from any previous chunk will always be a bad initial state for the first sampling in the new chunk and thus will effectively reset. The remaining discrepancies seem to be caused by floating point precision. Minecraft uses floats for the most part, but switches to doubles occasionally. my implementation does not mimic these switches exactly. |
So can that be emulated as a special I have also been doing some research, trying to understand the However you just said that this non-determinism does not apply to biomes from the world files, so the remaining errors must be because the distance is incorrectly calculated, right? Like there is a tie in biome distance but that tie does not exist in the official implementation. The causes could be rounding errors or floating point shenanigans such as So I don't know to which extent could the floating point issues be fixed, but if they cannot, then you could get a performance boost by compiling with |
Pretty much. The noise biome generation can be separated into two steps: First a bunch of noise generators are used to yield a set of integers which are meant to represent the 'climate'. This is the part where floating point inaccuracies can manifest. Floating point arithmetic does use the IEEE-754 standard, which dictates exactly how rounding is dealt with so you won't find any changes between JVMs or CPUs (however ( However, this tree search was still a performance bottleneck, so Mojang decided to save the previously closest node (i.e. fixed noise parameter) and abort the tree traversal if the saved result seems to be a closer or equal distance to any node in the tree. Unfortunately, since the tree does not always yield the true closest node, if the saved result is better or equal to the tree result then it may be different. This part is not a just a rounding issue and I expect there to be situations where the tree does not even find the second or third closest point. |
Oh, and regarding the deterministic 'reset' from chunk to chunk; almost all the fixed noise points have two copies for the |
Hi, I have a repo where I compare the biomes generated by cubiomes with the biomes that are stored in the region files of a generated world:
https://github.com/badel2/cubiomes-test-generation
I tried it with a world generated using snapshot 1.18-rc3, and there are some small differences at some biome borders, usually only 1 block. Is there some option to enable high accuracy? My code is here.
Test cases: coordinates are at 1:4 scale, expected is the one read from the world files, got is the one from cubiomes:
Seed 1234
Biome mismatch at (-95, -16, -56), expected 4 got 7
Biome mismatch at (-79, -16, -53), expected 7 got 0
Biome mismatch at (-136, -16, 13), expected 4 got 1
Some images, the incomplete image is the one from the world files:
Diff, basically the 4 pixels that stand out:
The text was updated successfully, but these errors were encountered: