This repository has been archived by the owner on Mar 8, 2024. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
1. Optimise chunk sky generation. ChunkSections now store 2 extra bits per block, which let us define 3 important states: transparent, full opaque, and unknown. The bitset is first stored in increasing y, so we can detect the highest non-transparent block per column in constant time. We then use this bitset to create a heightmap during chunk lighting. Instead of creating a propagation per block along each column for sky sources, we use the heightmap to detect if we need to create one (i.e, if we're above the heightmap for the x/z neighbours), and what directions to check. For exampl,e if some x, y, z is above the heightmap for its +x, +z, -z neighbours, but below the heightmap for its -x neighbour, we only tell the source to try and propagate to -x. If we were above the -x neighbour, the source would not be queued (unless it's 1 block higher than the heightmap for its column). Some local testing showed that this brought generation from 0.66ms/chunk to 0.50ms/chunk, although this was not tested on the same terrain (so it could be worse or better, will have to check). Depending on how some benchmarks go, this system might be refactored or removed entirely - I'm a bit worried about the memory usage implications. 2. New system for managing skylight The old system was pretty bad, it never de-initialised nibbles, it had compatibility problems with vanilla & vanilla clients, and it over-initialised nibbles. The new system is structured very similar to vanilla, where all non-empty chunksections have their 1 radius neighbour nibbles initialised. So this will be compatible with vanilla clients. However, this system relies upon saving uninitialised nibbles to disk and has a different stratedgy in-place for de-initialising nibbles. We maintain vanilla save compatibility by storing chunks as lit = false, so when vanilla loads the world it will simply re-generate the light. De-initialising nibbles is done lazily, whereas the initialisation of nibbles is always done immediately. In order for a chunk to correctly determine if a nibble should be de-initialised, it must have its 1 radius neighbours loaded. So, once the 1 radius neighbours are loaded into the light engine, de-initialisation checks are performed on all of the nibbles on the chunk. The vanilla engine doesn't do this, so that's why I had to make vanilla re-generate light when loading starlight saves. However, de-initialising lazily allows us to make nibble initialisation rather simple, and not force the initialisation process also light chunks (which is what vanilla does, and it's why it struggles often when nibbles have to be initialised). Initialising nibbles, as previously stated, will not perform lighting logic, unlike vanilla. This is a really strong point about this light engine, as I personally noticed that when crossing chunksections while building on platforms at y=255 resulted in a terrible 100ms or so spike locally because of vanilla's initialisation logic. Obviously with starlight, this does not happen. In fact, when I was testing out the new nibble management the largest spike I noticed for block changes at extreme heights (y = 255) was 4.0ms (in starlight 0.0.1, this would have been around 10.0ms or so). This means that starlight 0.0.2 should be pretty indestructable when 1.17 hits and people start using worldheights of 1000 blocks. As a sidenote, I will be publishing snapshot builds in the coming weeks. Skylight propagation code had to be modified to account for the new management, and I think the solution I introduced is pretty solid. Nibbles are always initialised/de-initialised before block changes are processed (on a more technical note: vanilla queues section changes before block changes, so we are automatically guarded against block-change-before- section-change race conditions). When propagating skylight downwards (increase or decrease), we have to be mindful of null nibbles. In most cases, we can just skip over the null nibble. But, the null nibble can have initialised neighbour(s). In this case, we know that the neighbours are actually empty, which means the skylight we are propagating probably affects the light levels of the initialised neighbours. So we need to somehow deal with the null nibbles and propagate to the initialised neighbour(s). The solution I have is to transiently (initialise just for the propagation call, and afterwards discord) initialise all of the nibbles on the x/z plane in 1 radius. Since we know the neighbours are all empty, we can get avoid initialising the nibbles above and below (as we don't need to worry about propagation paths through those, as we know the paths on the horizontal plane will be shorter and therefore be the ones affecting the light levels). 3. Cleanup some of the mixins Introduce access wideners to get around visibility issues, use at-Unique in areas it should have been used. 4. Fix propagation & render issues Skylight generation was broken when blocks were on the y-border for the highest non-empty chunk section. This has since been fixed. Not queueing neighbour chunksections to be re-rendered in some edge cases has since been fixed. 5. Fix some mod compatibility issues Apparently some mods create instances of the lighting provider with a null world. Allow null worlds. Some problems still exist, as I think some mods are being naughty and calling setBlockState off of the main thread. Tuinity's changes will need to be ported to fix this. Fixes #8 Fixes #7 Fixes #2 Fixes #1 For those of you with lighting issues from any of the above issues, this new build will erase all light data and re-calculate.
- Loading branch information