Skip to content
This repository has been archived by the owner on Mar 8, 2024. It is now read-only.

Commit

Permalink
Starlight 0.0.2-RC2
Browse files Browse the repository at this point in the history
1. Finish mixin cleanup
 No longer screw around with serverside scheduling, should
 improve compatibility with mods that like to do that.

 Add at-reason to at-Overwrites

 Move client mixins to own package

2. Re-schedule block changes to the main thread
 Fixes #6

3. Fix typo for serialized data (versiom -> version)

4. Clean up skylight propagation code
 Delaying the block sets is now a parameter in the general
 propagate method, and move the delay logic to no longer use a flag
 but to rather call a method later.

So far 0.0.2 looks good, will probably go on CF in the coming
weeks.
  • Loading branch information
Spottedleaf committed Dec 24, 2020
1 parent 7815e2d commit 1da2560
Show file tree
Hide file tree
Showing 19 changed files with 369 additions and 241 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ minecraft_version=1.16.4
yarn_mappings=1.16.4+build.7
loader_version=0.10.8
# Mod Properties
mod_version=0.0.2-RC1
mod_version=0.0.2-RC2
maven_group=ca.spottedleaf.starlight
archives_base_name=starlight
# Dependencies
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import ca.spottedleaf.starlight.common.blockstate.ExtendedAbstractBlockState;
import ca.spottedleaf.starlight.common.chunk.ExtendedChunk;
import ca.spottedleaf.starlight.common.chunk.ExtendedChunkSection;
import it.unimi.dsi.fastutil.shorts.ShortCollection;
import net.minecraft.block.BlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
Expand Down Expand Up @@ -280,7 +281,7 @@ protected final void initNibbleForLitChunk(final SWMRNibbleArray currNibble, fin
protected final void rewriteNibbleCacheForSkylight(final Chunk chunk) {
for (int index = 0, max = this.nibbleCache.length; index < max; ++index) {
final SWMRNibbleArray nibble = this.nibbleCache[index];
if (nibble == null || nibble.isNullNibbleUpdating()) {
if (nibble != null && nibble.isNullNibbleUpdating()) {
// stop propagation in these areas
this.nibbleCache[index] = null;
}
Expand Down Expand Up @@ -372,6 +373,19 @@ protected boolean canUseChunk(final Chunk chunk) {
&& (this.isClientSide ? ((ExtendedChunk)chunk).getEmptinessMap()[ExtendedChunk.getEmptinessMapIndex(0, 0)] != null : chunk.isLightOn());
}

@Override
protected void checkChunkEdges(final ChunkProvider lightAccess, final Chunk chunk, final int fromSection,
final int toSection) {
this.rewriteNibbleCacheForSkylight(chunk);
super.checkChunkEdges(lightAccess, chunk, fromSection, toSection);
}

@Override
protected void checkChunkEdges(ChunkProvider lightAccess, Chunk chunk, ShortCollection sections) {
this.rewriteNibbleCacheForSkylight(chunk);
super.checkChunkEdges(lightAccess, chunk, sections);
}

@Override
protected void checkBlock(final int worldX, final int worldY, final int worldZ) {
// blocks can change opacity
Expand All @@ -389,8 +403,7 @@ protected void checkBlock(final int worldX, final int worldY, final int worldZ)
((worldX + (worldZ << 6) + (worldY << (6 + 6)) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1))
| (currentLevel & 0xFL) << (6 + 6 + 16)
| (((long)ALL_DIRECTIONS_BITSET) << (6 + 6 + 16 + 4))
| FLAG_HAS_SIDED_TRANSPARENT_BLOCKS // don't know if the block is conditionally transparent
| (FLAG_RECHECK_LEVEL); // this source might be set up to decrease
| FLAG_HAS_SIDED_TRANSPARENT_BLOCKS; // don't know if the block is conditionally transparent
} else {
this.setLightLevel(worldX, worldY, worldZ, 0);
}
Expand Down Expand Up @@ -429,6 +442,10 @@ protected void propagateBlockChanges(final ChunkProvider lightAccess, final Chun
}
}

// note: light sets are delayed while processing skylight source changes due to how
// nibbles are initialised, as we want to avoid clobbering nibble values so what when
// below nibbles are initialised they aren't reading from partially modified nibbles

// now we can recalculate the sources for the changed columns
for (int index = 0; index < (16 * 16); ++index) {
final int maxY = this.heightMapBlockChange[index];
Expand All @@ -442,7 +459,8 @@ protected void propagateBlockChanges(final ChunkProvider lightAccess, final Chun
final int columnZ = (index >>> 4) | (chunkZ << 4);

// try and propagate from the above y
final int maxPropagationY = this.tryPropagateSkylight(world, columnX, maxY, columnZ, true);
// delay light set until after processing all sources to setup
final int maxPropagationY = this.tryPropagateSkylight(world, columnX, maxY, columnZ, true, true);

// maxPropagationY is now the highest block that could not be propagated to

Expand Down Expand Up @@ -474,16 +492,21 @@ protected void propagateBlockChanges(final ChunkProvider lightAccess, final Chun
break;
}

// delay light set until after processing all sources to setup
this.decreaseQueue[this.decreaseQueueInitialLength++] =
((columnX + (columnZ << 6) + (currY << (6 + 6)) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1))
| (15L << (6 + 6 + 16))
| (propagateDirection << (6 + 6 + 16 + 4))
| FLAG_FORCE_WRITE; // overwriting the nibble value affects init of dummy nibbles
| (propagateDirection << (6 + 6 + 16 + 4));
// do not set transparent blocks for the same reason we don't in the checkBlock method
}
}
}

// delayed light sets are processed here, and must be processed before checkBlock as checkBlock reads
// immediate light value
this.processDelayedIncreases();
this.processDelayedDecreases();

for (final BlockPos pos : positions) {
this.checkBlock(pos.getX(), pos.getY(), pos.getZ());
}
Expand Down Expand Up @@ -693,7 +716,7 @@ protected void lightChunk(final ChunkProvider lightAccess, final Chunk chunk, fi

this.increaseQueueInitialLength = queueLength;
// Just in case there's a conditionally transparent block at the top.
this.tryPropagateSkylight(world, worldX, heightMapC, worldZ, false);
this.tryPropagateSkylight(world, worldX, heightMapC, worldZ, false, false);
}
}
} // else: apparently the chunk is empty
Expand All @@ -716,8 +739,48 @@ protected void lightChunk(final ChunkProvider lightAccess, final Chunk chunk, fi
}
}

protected final void processDelayedIncreases() {
// copied from performLightIncrease
final long[] queue = this.increaseQueue;
final int decodeOffsetX = -this.encodeOffsetX;
final int decodeOffsetY = -this.encodeOffsetY;
final int decodeOffsetZ = -this.encodeOffsetZ;

for (int i = 0, len = this.increaseQueueInitialLength; i < len; ++i) {
final long queueValue = queue[i];

final int posX = ((int)queueValue & 63) + decodeOffsetX;
final int posZ = (((int)queueValue >>> 6) & 63) + decodeOffsetZ;
final int posY = (((int)queueValue >>> 12) & ((1 << 16) - 1)) + decodeOffsetY;
final int propagatedLightLevel = (int)((queueValue >>> (6 + 6 + 16)) & 0xF);

this.setLightLevel(posX, posY, posZ, propagatedLightLevel);
}
}

protected final void processDelayedDecreases() {
// copied from performLightDecrease
final long[] queue = this.decreaseQueue;
final int decodeOffsetX = -this.encodeOffsetX;
final int decodeOffsetY = -this.encodeOffsetY;
final int decodeOffsetZ = -this.encodeOffsetZ;

for (int i = 0, len = this.decreaseQueueInitialLength; i < len; ++i) {
final long queueValue = queue[i];

final int posX = ((int)queueValue & 63) + decodeOffsetX;
final int posZ = (((int)queueValue >>> 6) & 63) + decodeOffsetZ;
final int posY = (((int)queueValue >>> 12) & ((1 << 16) - 1)) + decodeOffsetY;

this.setLightLevel(posX, posY, posZ, 0);
}
}

// delaying the light set is useful for block changes since they need to worry about initialising nibblearrays
// while also queueing light at the same time (initialising nibblearrays might depend on nibbles above, so
// clobbering the light values will result in broken propagation)
protected final int tryPropagateSkylight(final BlockView world, final int worldX, int startY, final int worldZ,
final boolean extrudeInitialised) {
final boolean extrudeInitialised, final boolean delayLightSet) {
final BlockPos.Mutable mutablePos = this.mutablePos3;
final int encodeOffset = this.coordinateOffset;
final long propagateDirection = AxisDirection.POSITIVE_Y.everythingButThisDirection; // just don't check upwards.
Expand Down Expand Up @@ -765,14 +828,14 @@ protected final int tryPropagateSkylight(final BlockView world, final int worldX
}
// most of the time it falls here.
// add to propagate
// light set delayed until we determine if this nibble section is null
this.increaseQueue[this.increaseQueueInitialLength++] =
((worldX + (worldZ << 6) + (startY << (6 + 6)) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1))
| (15L << (6 + 6 + 16)) // we know we're at full lit here
| (propagateDirection << (6 + 6 + 16 + 4))
| FLAG_FORCE_WRITE; // overwriting the nibble value affects init of dummy nibbles
| (propagateDirection << (6 + 6 + 16 + 4));
} else {
mutablePos.set(worldX, startY, worldZ);
long flags = FLAG_FORCE_WRITE; // overwriting the nibble value affects init of dummy nibbles
long flags = 0L;
if (((ExtendedAbstractBlockState)current).isConditionallyFullOpaque()) {
final VoxelShape cullingFace = current.getCullingFace(world, mutablePos, AxisDirection.POSITIVE_Y.nms);

Expand All @@ -789,6 +852,7 @@ protected final int tryPropagateSkylight(final BlockView world, final int worldX
break;
}

// light set delayed until we determine if this nibble section is null
this.increaseQueue[this.increaseQueueInitialLength++] =
((worldX + (worldZ << 6) + (startY << (6 + 6)) + encodeOffset) & ((1L << (6 + 6 + 16)) - 1))
| (15L << (6 + 6 + 16)) // we know we're at full lit here
Expand All @@ -812,6 +876,8 @@ protected final int tryPropagateSkylight(final BlockView world, final int worldX

// make sure this is marked as AIR
above = AIR_BLOCK_STATE;
} else if (!delayLightSet) {
this.setLightLevel(worldX, startY, worldZ, 15);
}
}

Expand Down
Loading

0 comments on commit 1da2560

Please sign in to comment.