On a world with a behavior pack that defines a custom height limit like -512 to 512, if the total height range is greater than 512, the Y coordinate in a POI entry can overflow in the POI region data in the LevelDB.
The POI region data I am referring to in the LevelDB is under LevelDB keys in the format poi.#.regions.#.#.
The data structure is a map with 4-byte keys containing the relative block location within the 512x512 region and 3-byte values consisting of 2 bytes representing the POI type and 1 byte storing the number of tickets.
The integer values of the keys are currently in the format <5 unused bits><9-bit Z coordinate><9-bit Y coordinate><9-bit X coordinate> and encoded in little-endian.
The problem comes from using 9 bits for the Y coordinate instead of 10, a 9-bit integer can only store 512 possible values, but the maximum possible total height range is 1024, a 10-bit integer would allow for storing all 1024 possible Y values.
Here is an example of the issue:
There is a lodestone at 1495 88 102327, its region relative X and Z coordinates are 471 and 439, it is in region 2, 199.
In a normal world the Y coordinate is stored as 010011000, which is 152, and since 88-(-64)=152 this is correct.
But in a world with a -512 to 512 height range, the Y coordinate is stored as 001011000, which is 88, but 88-(-512)=600, not 88, but it gets written as 88 because 600 overflows when trying to store it as a 9-bit integer and ends up as 88.
And if there was another lodestone at 1495 -424 102327, that lodestone would correctly have the Y coordinate stored as 88, but since the lodestone at Y=88 already used that key in the map due to overflowing, now there is a collision, and either the Y=88 or the Y=-424 lodestone gets discarded from the POI region data.
Any two POI entries that are 512 blocks apart on the Y axis currently will collide due to the higher one overflowing to end up with the same coordinate key as the lower one.
Steps to Reproduce:
Create a world and add a behavior pack that sets the overworld height limits to -512 to 512.
Place lodestones at 0, -424, 0 and the other at 0, 88, 0.
View the
poi.0.regions.0.0LevelDB key of the world.Notice that there is only one lodestone POI entry, when there should be 2.
Expected Result:
There should be 2 lodestone POI entries, both with different keys.
Actual Result:
There is only 1 lodestone POI entry, with the key of the Y=-424 lodestone.
Comments 0
No comments.