Implementations for ChunkStatuses below FULL are supposed to always
return ProtoChunk instances. However, since we used the last completed
status, it could return LevelChunk.
To resolve this, follow Vanilla behavior of tracking chunk
completions by status and replace old ProtoChunk statuses with
ImposterProtoChunk when the chunk generates to FULL.
Additionally, implement an optimisation for retrieving full chunks
by storing a map of pos -> LevelChunk. This requires only a simple
map lookup to occur for full chunks which are loaded.
This allows us to have safe off-thread reads, as we can guarantee
that the palette is associated with the data (which is why
a Data container is used in the first place).
This allows us to use them for chunk rendering, which
should reduce competition between the background executor pool
and the chunk system for cpu resources.
Palette has 4 implementations: global, hash, linear, and single.
When only one implementation is being used (i.e all chunks
loaded have sections with linear palette) the JIT can optimise
the call to #valueFor quite well. When there are two implementations
(i.e hash, linear) the JIT can still optimise the call but at a
slight cost.
However, when there are three or more in use
(i.e linear, hash, single/global) the JIT cannot
optimise the call and must revert to an interface invoke - which
is terribly slow.
In order to optimise this, we can extract an array for
the hash, linear, and single palette implementations and
perform lookups on the array directly instead of invoking
The light tasks may allocate a light engine themselves, and as a
result increase memory usage. We can avoid these allocations
by only allocating the instances for block changes and releasing
immediately after.
The collision shape of the border is determined by flooring the min values and ceiling the max values, so the isCollidingWithBorder() function should mirror such behavior.
The epsilon used was in the opposite direction, which would cause
the getCollisions method to incorrectly return it for when players
were exactly on the border but not colliding. To bring it in-line
with the rest of the collision code, the collision must be into
the border by +EPSILON.
Additionally, move the setReadTimeoutHook in the server list
ping patch to a client-side mixin so it does not load in the
dedicated server causing a crash.
Change all interfaces used in mixins to have methods prefixed
with "moonrise" or "starlight", to remove risk of conflicting
with Vanilla or other mods methods
Add new patch for optimising ticking block entity removal
- Similar to Paper's patch for this but uses an in-place removal
method
Remove most of the fluid mixins:
- May not be effective, but are a big maintenance problem
Change the read timeout and connection timeout both to 5s. This
is to decrease the time to label servers as offline.
Additionally, increase the worker count for pinging servers to 128
from 5. This allows many more server pings to occur at the same time,
which allows users to scroll their serverlist.
When ChunkAccess was converted to an abstract class some versions
ago, the code to initialise nibble arrays should have been moved.
However, the code was not moved and so now mods constructing their
own implementations of ChunkAccess would not have the nibble arrays
initialised.
Fixes https://github.com/PaperMC/Starlight/issues/186
During feature generation, light data is not initialised and
will always return 15 in Starlight. Vanilla can possibly return
0 if partially initialised, which allows some mushroom blocks to
generate.
In general, the brightness value from the light engine should not
be used until the chunk is ready. To emulate Vanilla behavior better,
we return 0 as the brightness during world gen unless the target
chunk is finished lighting.
The regular light retrieval outside of WorldGenRegion remains
the same, as behaviorally chunks not lit should be at max
skylight and zero block light.
Fixes https://github.com/PaperMC/Starlight/issues/193
There is no point in initialising the sources in Starlight,
as we do not use them. Additionally, they are not saved to
disk so we do not need them.
Maintaining and initialising them is not a negligible cost,
which is why they are being removed.
The correct logic to implement NOT_SAME with Shapes#block()
is to test whether any shape data exists outside of [0.0, 1.0]
and to test whether the shape is completely filled from 0.0 to 1.0
on all axis. This can be implemented by checking whether the
bounds represent the full block and whether everything within
the bounds is filled.
The mixin targetted the getSourceContainer invocation, which failed
when the method was overwritten. Move the optimisations to use
one redirect and one inject, which don't appear to affect the
performance.