This was the cause of many inconsistency and broken world bugs. In the future (once we switch to paletted chunks) this won't be possible anyway. For now, some temporary API is provided to allow modifying chunkdata directly, but it is required that **both** must be provided.
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.
It was still possible to produce undefined behaviour by creating a db folder in a region-based world, or adding regions to a leveldb world. This now solves the problem completely by refusing to load the world if multiple formats match the world.
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.
Seed is immutable information about the world, like its generator type, generator options, name, etc. We don't allow changing any of those things, so why the fuck would we allow changing the seed? This makes no sense at all.
I'm removing this because a) its existence makes no sense, and b) it will not produce the behaviour expected from such a function (what even is the expected behaviour???)
It checks for the existence of (and creates) the world directory if it doesn't exist. But what sense does this make when the world obviously doesn't exist in this case and must be generated first?
This is problematic because child level providers can forget to override the provider name of their parents, and then override them by error. Instead, they should be used in a mapping fashion to make sure they are unique and not inherited.
Also, the old method did not permit registering multiple aliases for the same provider. This now makes that possible.
In the future, McRegion and PMAnvil will become deprecated legacy formats which we won't support for writing anymore. However, this brings complications because Anvil (which would not be deprecated) would be sandwiched between its deprecated base (McRegion) and its deprecated child (PMAnvil), complicating the implementation (particularly for PMAnvil).
This abstracts away the generic Region-based world functionality into a separate class, making McRegion, Anvil and PMAnvil all inherit from it directly. Since only the chunk formats are different, they are more accurately siblings rather than parent-child (although Anvil and PMAnvil are cousins, ish).