Mojira Archive
MC-80966

Lightcalculation of ChunkSelection faulty implemented resulting in client bugs (empty chunks don’t show light/render dark)

The code in ChunkSelection.java that reports if a specific part of a chunk needs to be delivered to a client or not is faulty:

I'm not sure what the Class is named in the obfuscation. In the partially deobfuscated code it's ChunkSelection.java and the method's name is public boolean a().

I'm guessing it's public boolean hasBlockData() in the original code

ChunkSelection.java
public boolean a(){ 
    return this.nonEmptyBlockCount == 0; 
}

This method is called when a Chunk is placed in the OutgoingQueue to a client. It checks if a ChunkSelection should be delivered or not.
The code does not consider the fact that - even if there is no block in a chunkselection - there may still be light-information for that selection.

This results in light-Bugs on the client side if a Chunk hast light-information in a chunkselection that does not contain any blocks.

Video content:

  • Connecting to a Singleplayer World (same in Multiplayer)
  • Two chunks have obvious light-Information missing
  • Teleporting does not fix the problem
  • Placing a Block inside that specific chunkselection - thus working around the bug - does not fix the bug initially as the information only get updated on ChunkSending.
  • Teleporting post the workaround does fix the bug
  • Removing the Block - recreating the empty chunkselection and recreating the bug does work post teleport
  • F3 shows we are exactly at the edge of a chunkSelection (63/64)
  • The client-side light-updates in the area around a player does only fix the problem temporarily

This can be fixed by changing the code:

ChunkSelection.java
public boolean a(){ 
   // return this.nonEmptyBlockCount == 0; 
     return false; //kade fix, bukkit/mc reports wrongly if a part of a chunk is empty or not.
}

Performance and Gameplay implications of this bugfix

  • Performance
    The performance impact is negligible. The problem occurs in <5% of chunks. Specifically: It occurs in every Chunk that has Blocks at the top of one ChunkSelection and light-information in the one above that but no blocks.
  • Bandwidth
    The Bandwidth increases a small amount for the <5% Chunks. But as all that is being sent is the light-map we are talking about a compressed data of only some bytes more.
  • Gameplay
    There are absolutely no side-effects of this fix. I have been running this code-change on my servers for at least 1 1/2 years now (concurrent playercount > 300).

Conclusion
In essence the Idea behind the "nonEmptyBlockCount == 0"-Check is good. But its neglecting the fact that there might be light-information present. As ChunkSelections without any lightinformation are null anyways there is no need for that check.