-
Bug
-
Resolution: Fixed
-
Minecraft 18w50a
-
None
-
Confirmed
How to reproduce
Run:
/tp 20000000 200 20000000
The cause
Inside class ServerChunkManager (up) in a method that handles updating itself for player movement, there is piece of code like this (decompiled and remapped code):
final int minX = Math.min(playerChunkX, lastPlayerChunkX) - this.viewDistance; final int minZ = Math.min(playerChunkZ, lastPlayerChunkZ) - this.viewDistance; final int maxX = Math.max(playerChunkX, lastPlayerChunkX) + this.viewDistance; final int maxZ = Math.max(playerChunkZ, lastPlayerChunkZ) + this.viewDistance; for (int x = minX; x <= maxX; ++x) { for (int z = minZ; z <= maxZ; ++z) { final ChunkPos chunkPos = new ChunkPos(x, z); final boolean oldLoaded = !flag1 && getWatchDistance(chunkPos, lastPlayerChunkX, lastPlayerChunkZ) <= this.viewDistance; final boolean newLoaded = !flag2 && getWatchDistance(chunkPos, playerChunkX, playerChunkZ) <= this.viewDistance; this.chunkLoader.sendChunkDataPacket(playerEntity, chunkPos, new Packet[2], oldLoaded, newLoaded); } }
This code iterates over ALL chunk coordinates in a box with one end at one end of player view distance before movement, and the other and the opposite end of player view area after movement. This obviously isn't going to work for far teleportation.
The way it was done in older Minecraft versions looks closer to this:
// dx and dz is player movement in chunks for (int x = newX -viewDistance; x <= newX + viewDistance; ++x) { for (int z = newZ - viewDistance; z <= newZ + viewDistance; ++z) { //is current position outside of the old render distance square? if (!isPointInSquare(oldX, oldZ, x, z, viewDistance)) { // newly loaded chunk } //if we moved the current point to where it would be previously, //would it be outside of current render distance square? if (!isPointInSquare(newX, newZ, x-dx, z-dz, viewDistance)) { // unloaded chunk } } }
Which uses just the render distance area to determine which chunks are loaded and which chunks are to be unloaded.