This takes advantage of two key behaviours of PHP:
1. Assigning a string does not copy the string
2. Changing an offset in a string causes the string to be copied.
These two factors combined, along with the fact that blocklight and skylight arrays are usually all-zeros, allow us to produce a significant memory usage reduction of loaded chunks.
A freshly generated PM world with 3,332 chunks loaded drops from 310MB to 200MB memory usage with these changes applied.
this process of fast-serialization, fast-deserialize, network-serialize is an order of magnitude slower than just doing the network encode directly on the main thread, and also copies more useless data.
For the main thread, the figures were something like 3x more expensive, and then an extra 7x for deserialization on the worker thread. This is a ridiculously large overhead.
This supersedes addChunkPacket() in most cases, and has a more clear name. It broadcasts the given packet to every player who has the target position within their chunk load radius.
This can happen when a light source is removed and later encountering another light source to fill the gap. A higher light level may get set and then not propagated. This bug is difficult to explain, but fairly easy to reproduce.
Grass can cause issues here by requesting blocks randomly offset away from itself, which can cause silent chunk loading on chunk ticking. It also causes crashes if chunk autoloading is taken away, which is obviously undesired.
It was also noticed that player chunkloaders cause chunks to start getting ticked as soon as they load their first chunk, which is before the entity is visible to everyone else on the server. This is probably undesired behaviour.
This has the triple bonus effect of a) making a lot of code easier to read, b) reducing Server::getInstance() usages, and c) removing a whole bunch of Server dependencies.
The network and block namespaces are untouched by this commit due to potential for merge conflicts. These should be dealt with separately on master.
This assumes that the region is properly garbage-collected and packed, but if the file contains uncollected garbage this may not be the case, resulting in a region larger than a gigabyte.
This is needed for batched lighting updates to work. It also reduces the overhead involved with simply preparing a lighting update and moves the pain to the execute() instead.