On the server side, light is used for a variety of vanilla logic, including (but not limited to):
No idea. In theory, we don't need to calculate lighting for anything other than chunks currently in ticking areas (usually a few chunks' radius around the player where crops are expected to grow and so on).
We propose a 3-pass algorithm for relighting chunks, starting from zero light.
If an arbitrary chunk is replaced, its light must be invalidated, and also the light of the surrounding 8 chunks. This is because a chunk's lighting may have affected any of these adjacent chunks (due to propagation).
For sky light, this involves calculating the "height map" of the chunk. For each X/Z column in the chunk, the heightmap contains the Y coordinate of the highest block that doesn't affect light, NOT the highest block.
Blocks pointed to by the heightmap should be treated as light sources for sky light propagation. In addition, account for the difference between the current column and the highest immediately adjacent heightmap, to account for cases where sideways propagation is needed.
Block | Ignored by heightmap | Reason |
---|---|---|
Glass | Yes | Fully transparent |
Air | Yes | Fully transparent |
Leaves | No | Diffuses sky light (doesn't reduce light propagation, but triggers heightmap) |
Cobweb | No | Diffuses sky light (doesn't reduce light propagation, but triggers heightmap) |
Water | No | Light is reduced by 3 levels when propagating through (instead of usual 1) |
Stone | No | Fully opaque |
For block light, you just need to scan the whole chunk and look for blocks with a non-zero light emission. These blocks are your source nodes.
Tip: You can optimise these kinds of scans using the block palette. If a subchunk's block palette doesn't contain any light-emitting blockstates, you can avoid scanning the entire 4096 blocks of that subchunk.
This pass must not influence any other chunks except the source chunk. It's possible, probably practical, to do pass 0 and 1 directly in series.
For this pass, we take square groups of 4 chunks, and propagate light across their shared borders. No chunk is special; all 4 chunks in each group are treated the same way.
Each chunk belongs to 4 groups of 4 chunks:
Once a chunk has been involved in a pass 2 calculation in all of these positions, it is then fully light-populated.
Groups of 4, while harder to explain, are significantly more parallel-friendly, easier to code, and in the case of PocketMine-MP, require significantly fewer chunk copies (4 instead of 9), due to the fact that a pass2 using groups of 4 only needs to lock a chunk 4 times.