Resolution: Awaiting Response
Affects Version/s: Minecraft 1.12, Minecraft 1.12.1, Minecraft 1.13-pre8, Minecraft 1.13.1
Fix Version/s: None
Environment:Unrelated. Tested on a few different computers, with both windows a linux, and different hardware.
First I want to explain why it shouldn't be marked as duplicate of
MC-90602: MC-90602 is an issue so generic and vague that it captures a lot of completely different unrelated issues. People keep reporting them over and over again, with many variants that for people who don't know the internals are indistinguishable. In the current state that issue can't really be reasonably "fixed" because it's many different vague issues, and only fixing all of them would be enough to close it. This one can be reliably reproduced, and I know exactly what is needed to fix it.
When joining a server where the area around the player has already been loaded at the moment the player joined, and it's not too close to chunk (0, 0), some spot won't render until a block update happens there or render distance is changed. It's consistently the same spot but it's location is affected by render distance. This issue doesn't affect singleplayer.
Steps to reproduce:
- Start a dedicated server with default settings
- Join the server and op yourself
- `/tp 536 120 280`
- set your render distance to 8
- rejoin the server
At this point you could see some invisible chunks right below you, even when everything around is visible.
What causes is?
Note: this explanation references decompiled Minecraft code, all names are using MCP mappings
I encountered this issue when working on my mod several times, and early testers complained about it, turns out it was vanilla issue.
When player joins the server, one of the first thing it does is call addPlayer on PlayerChunkMap. This creates all the necessary PlayerChunkMapEntry instances, attempts to load their chunks, and send then to the player.
When client receives the chunk, it schedules render update, which is done by eventually reaching ViewFrustum#markBlocksForUpdate, which marks RenderChunk instances for update. Then on the next frame the last loop in RenderGlobal#setupTerrain will walk over all the chunks that need update and if it's close to player - update immediately, otherwise - schedule an update.
The problem is that the server is sending those chunks before sending player position, which means that until then client will assume it's 8, 64, 8. This means that markBlocksForUpdate will mark the right RenderChunk instances, but they have the wrong position set. And then the loop in setupTerrain will go over those chunks, taking the still wrong position from RenderChunk. And if the chunk is close to the currently assumed player position, 8, 64, 8 it will update it immediately and mark it as updated. But it ends up doing it for the wrong position, which means nothing will render there until new block updates are scheduled there.
Note that this means that if all chunk packets and the player position update are all processed in the same frame, the issue won't happen. If server doesn't send the chunks so early - the issue won't happen. So this is a timing related issue. Use breakpoints when debugging it and it will go away. There is a potential for it to disappear on different hardware.
This also clearly shows a few possible fixes:
- Clientside fix: make the loop in setupterrain use the coordinates it expects instead of taking them from RenderChunk
- Serverside fix 1: don't send any chunks in PlayerChunkMap#addPlayer
- Send player position to the client before adding the player to chunk map.
Each of those should fix the issue. Forge also allows to woraround the issue by fircing threaded chunk updates, which skips the immediate update in RenderGlobal#setupTerrain and always queues an update.