Start implementing sky light

This commit is contained in:
techno-sam
2025-08-23 00:36:46 -07:00
parent d8d540f820
commit 312b6739fc
18 changed files with 435 additions and 75 deletions
+6
View File
@@ -4,6 +4,10 @@ indent_style = tab
tab_width = 4
insert_final_newline = true
[{*.py,*.ipynb}]
indent_size = 4
indent_style = space
[*.yml]
indent_size = 2
indent_style = space
@@ -22,3 +26,5 @@ ij_groovy_method_brace_style = end_of_line
[{*.har,*.json,*.png.mcmeta,mcmod.info,pack.mcmeta}]
ij_json_array_wrapping = split_into_lines
indent_size = 2
indent_style = space
+49 -1
View File
@@ -6,18 +6,53 @@ plugins {
alias libs.plugins.minotaur
}
boolean inCI = System.getenv("GITHUB_RUN_NUMBER") != null
version = "$modVersion+$branchName"
base.archivesName = project.slug
repositories {
exclusiveContent {
forRepository {
//noinspection ForeignDelegate
maven {
name 'Modrinth'
url "https://api.modrinth.com/maven"
}
}
filter {
includeGroup "maven.modrinth"
}
}
exclusiveContent {
forRepository {
//noinspection ForeignDelegate
maven {
name 'Terraformers'
url "https://maven.terraformersmc.com/"
}
}
filter {
includeGroup "com.terraformersmc"
}
}
}
dependencies {
minecraft libs.mc
mappings variantOf(libs.yarn) { classifier "v2" }
mappings loom.layered {
it.mappings variantOf(libs.yarn) { classifier "v2" }
it.mappings file("custom_mappings.tiny")
}
modImplementation libs.fl
modImplementation libs.fapi
if (!inCI) {
modRuntimeOnly libs.mm
}
include(implementation(annotationProcessor(libs.mixinextras.get())))
}
processResources {
@@ -40,6 +75,18 @@ processResources {
inputs.properties meta
filesMatching("*.mod.json") { expand(meta) }
filesMatching("META-INF/*mods.toml") { expand(meta) }
// don't add development or to-do files into built jar
exclude("**/*.bbmodel", "**/*.lnk", "**/*.xcf", "**/*.blend", "**/*.blend1")
}
loom {
runs.configureEach {
vmArg("-XX:+AllowEnhancedClassRedefinition")
vmArg("-XX:+IgnoreUnrecognizedVMOptions")
vmArg("-Dmixin.debug.export=true")
vmArg("-Dfabric-tag-conventions-v2.missingTagTranslationWarning=VERBOSE")
}
}
tasks.withType(JavaCompile).configureEach {
@@ -68,6 +115,7 @@ modrinth {
token = "$System.env.MODRINTH_TOKEN"
projectId = slug
versionNumber = project.version
versionType = System.getenv().getOrDefault("RELEASE_TYPE", "release")
uploadFile = remapJar
gameVersions = compatibleVersions.split(", ").toList()
loaders = compatibleLoaders.split(", ").toList()
+81
View File
@@ -0,0 +1,81 @@
tiny 2 0 official intermediary named
c fac net/minecraft/class_3558 net/minecraft/world/chunk/light/ChunkLightProvider
f I a field_44729 MAX_LEVEL
f I b field_44730 MIN_OPACITY
f J c field_44731 PULL_LIGHT_IN_ENTRY
f I g field_44732 MIN_QUEUE_SIZE
f Lit/unimi/dsi/fastutil/longs/LongArrayFIFOQueue; i field_44734 decreaseQueue
f Lit/unimi/dsi/fastutil/longs/LongArrayFIFOQueue; j field_44735 increaseQueue
f I k field_31709 CACHE_SIZE
m (J)V a method_51529 checkNode
m (JJ)V a method_51530 propagateDecrease
m (JJI)V a method_51531 propagateIncrease
m (JJ)V b method_51565 enqueueDecrease
m (JJ)V c method_51566 enqueueIncrease
m ()I d method_51567 propagateIncreases
m ()I e method_51570 propagateDecreases
c fac$a net/minecraft/class_3558$class_8531 net/minecraft/world/chunk/light/ChunkLightProvider$QueueEntry
m (IZ)J a method_51573 increaseLightFromEmission
m (ZZZZZ)J a method_51578 increaseSkySourceInDirections
m (IZLjh;)J b method_51579 increaseOnlyOneDirection
m (J)Z c method_51582 isIncreaseFromEmission
c fae net/minecraft/class_3572 net/minecraft/world/chunk/light/ChunkSkyLightProvider
f J g field_44743 REMOVE_TOP_SKY_SOURCE_ENTRY
f J h field_44744 REMOVE_SKY_SOURCE_ENTRY
f J i field_44745 ADD_SKY_SOURCE_ENTRY
f Ljb$a; j field_44746 scratchPos
m (IIII)V a method_51586 removeSourcesBelow
m (JLjh;IZI)V a method_51587 propagateFromEmptySections
p 0 blockPos
p 1 direction
p 2 lightLevel
p 3 shouldIncrease
p 4 emptySections
m (III)V b method_51590 updateSourcesInColumn
m (IIII)V b method_51591 addSourcesAbove
m (J)V a method_51529 checkNode
v 3 5 -1 _ _ x
v 4 11 -1 _ _ y
v 5 17 -1 _ _ z
v 6 23 -1 _ _ sectionPos
v 8 54 -1 _ _ lowestSourceY
v 9 100 -1 _ _ aboveLowest
v 10 137 -1 _ _ storedLightLevel
m (JJI)V a method_51531 propagateIncrease
v 6 3 -1 _ _ blockState
v 7 10 -1 _ _ emptySectionsBelow
v 11 37 -1 _ _ direction
v 12 57 -1 _ _ targetPos
v 14 92 -1 _ _ storedLightLevel
v 15 98 -1 _ _ baseLevelToPropagate
v 16 128 -1 _ _ targetState
v 17 139 -1 _ _ trueLevelToPropagate
m (Ldlz;)V b method_51471 propagateLight
v 2 12 -1 _ _ packedZeroPos
v 4 48 -1 _ _ sourcesO
v 5 74 -1 _ _ sourcesZN
v 6 100 -1 _ _ sourcesZP
v 7 126 -1 _ _ sourcesXN
v 8 152 -1 _ _ sourcesXP
v 9 165 -1 _ _ topSectionY
v 10 177 -1 _ _ bottomSectionY
v 11 186 -1 _ _ baseX
v 12 195 -1 _ _ baseZ
v 13 201 -1 _ _ sectionY
v 14 223 -1 _ _ packedSectionPos
v 16 237 -1 _ _ chunkNibbleArray
v 17 252 -1 _ _ sectionMinY
v 18 259 -1 _ _ sectionMaxY
v 19 262 -1 _ _ isMinBelowCurrent
v 20 265 -1 _ _ localZ
v 21 275 -1 _ _ localX
v 22 293 -1 _ _ minSourceY_O
v 23 333 -1 _ _ minSourceY_ZN
v 24 364 -1 _ _ minSourceY_ZP
v 25 394 -1 _ _ minSourceY_XN
v 26 425 -1 _ _ minSourceY_XP
v 27 444 -1 _ _ minSourceY_max
v 28 448 -1 _ _ it_y
v 29 507 -1 _ _ it_pos
+9 -9
View File
@@ -6,15 +6,15 @@ org.gradle.configuration-cache=true
# Loom
fabric.loom.multiProjectOptimisation=true
# Mod Metadata
group=io.github.username
user=username
slug=mod-id
modId=mod_id
modName=Mod ID
modDescription=Sal doesn't have editing software so he has to make memes through minecraft mod descriptions, making him tonight's big loser.
authors=Anonymous
contributors=all this mod's adoring fans!
license=MIT
group=io.github.slimeistdev
user=techno-sam
slug=crystalline-sky
modId=crystalline_sky
modName=Crystalline Sky
modDescription= Crystallizes the heavens into block form. For all your sky-in-a-cave needs.
authors=Slimeist
contributors=
license=EUPL 1.2 or later
# Mod Version
modVersion=0.1.0
# Branch Metadata
+4
View File
@@ -6,6 +6,8 @@ mc = "1.21.8"
fl = "0.16.14"
yarn = "1.21.8+build.1"
fapi = "0.130.0+1.21.8"
mixinextras = "0.5.0"
mm = "15.0.0-beta.3"
[plugins]
loom = { id = "fabric-loom", version.ref = "loom" }
@@ -16,3 +18,5 @@ mc = { group = "mojang", name = "minecraft", version.ref = "mc" }
fl = { group = "net.fabricmc", name = "fabric-loader", version.ref = "fl" }
yarn = { group = "net.fabricmc", name = "yarn", version.ref = "yarn" }
fapi = { group = "net.fabricmc.fabric-api", name = "fabric-api", version.ref = "fapi" }
mixinextras = { group = "io.github.llamalad7", name = "mixinextras-fabric", version.ref = "mixinextras" }
mm = { group = "com.terraformersmc", name = "modmenu", version.ref = "mm" }
@@ -0,0 +1,26 @@
package io.github.slimeistdev.crystalline_sky;
import net.fabricmc.api.ModInitializer;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKey;
import net.minecraft.util.Identifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CrystallineSky implements ModInitializer {
public static final String ID = "crystalline_sky";
public static final Logger LOG = LoggerFactory.getLogger(ID);
@Override
public void onInitialize() {
ModSetup.init();
}
public static Identifier id(String path) {
return Identifier.of(ID, path);
}
public static <T> RegistryKey<T> key(RegistryKey<? extends Registry<T>> registryKey, String path) {
return RegistryKey.of(registryKey, id(path));
}
}
@@ -0,0 +1,11 @@
package io.github.slimeistdev.crystalline_sky;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineItems;
public class ModSetup {
public static void init() {
CrystallineBlocks.init();
CrystallineItems.init();
}
}
@@ -0,0 +1,16 @@
package io.github.slimeistdev.crystalline_sky.mixin;
import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks;
import net.minecraft.block.BlockState;
import net.minecraft.world.chunk.light.ChunkLightProvider;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(ChunkLightProvider.class)
public class ChunkLightProviderMixin {
@WrapMethod(method = "needsLightUpdate")
private static boolean updateSky(BlockState oldState, BlockState newState, Operation<Boolean> original) {
return original.call(oldState, newState) || (oldState.isOf(CrystallineBlocks.SKY) != newState.isOf(CrystallineBlocks.SKY));
}
}
@@ -0,0 +1,123 @@
package io.github.slimeistdev.crystalline_sky.mixin;
import com.llamalad7.mixinextras.expression.Definition;
import com.llamalad7.mixinextras.expression.Expression;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.llamalad7.mixinextras.sugar.Local;
import com.llamalad7.mixinextras.sugar.Share;
import com.llamalad7.mixinextras.sugar.ref.LocalBooleanRef;
import com.llamalad7.mixinextras.sugar.ref.LocalIntRef;
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks;
import net.minecraft.block.BlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkSectionPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.chunk.ChunkProvider;
import net.minecraft.world.chunk.ChunkToNibbleArrayMap;
import net.minecraft.world.chunk.light.ChunkLightProvider;
import net.minecraft.world.chunk.light.ChunkSkyLightProvider;
import net.minecraft.world.chunk.light.LightStorage;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Slice;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ChunkSkyLightProvider.class)
public abstract class ChunkSkyLightProviderMixin<M extends ChunkToNibbleArrayMap<M>, S extends LightStorage<M>> extends ChunkLightProvider<M, S> {
@Shadow
@Final
private BlockPos.Mutable scratchPos;
@Unique
private static final int crystalline_sky$EMISSION_FROM_SKY_BLOCK = 1 << 22; // used to allow 15-level light to go down without reduction
protected ChunkSkyLightProviderMixin(ChunkProvider chunkProvider, S lightStorage) {
super(chunkProvider, lightStorage);
}
@Inject(method = "checkNode", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/chunk/light/SkyLightStorage;get(J)I"))
private void emitFromSky(long blockPos, CallbackInfo ci) {
BlockState state = getStateForLighting(scratchPos.set(blockPos));
if (state.isOf(CrystallineBlocks.SKY) && ((LightStorageAccessor) lightStorage).crystalline_sky$callIsSectionInEnabledColumn(ChunkSectionPos.fromBlockPos(blockPos))) {
enqueueIncrease(blockPos, QueueEntry.increaseLightFromEmission(15, isTrivialForLighting(state)) | crystalline_sky$EMISSION_FROM_SKY_BLOCK);
}
}
@Definition(id = "lightLevel", local = @Local(type = int.class, argsOnly = true, ordinal = 0))
@Expression("lightLevel - 1")
@ModifyExpressionValue(
method = "propagateIncrease",
at = @At("MIXINEXTRAS:EXPRESSION"),
slice = @Slice(
from = @At(value = "INVOKE", target = "Lnet/minecraft/world/chunk/light/SkyLightStorage;get(J)I"),
to = @At(value = "INVOKE", target = "Lnet/minecraft/world/chunk/light/ChunkSkyLightProvider;getStateForLighting(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/block/BlockState;", ordinal = 0)
)
)
private int unreducedDown1(int original, long blockPos, long packed, int lightLevel, @SuppressWarnings("LocalMayBeArgsOnly") @Local(ordinal = 0) LocalRef<Direction> direction, @Share("unreduced") LocalBooleanRef unreduced) {
if (lightLevel == 15 && (packed & crystalline_sky$EMISSION_FROM_SKY_BLOCK) != 0 && direction.get() == Direction.DOWN) {
unreduced.set(true);
return lightLevel;
} else {
unreduced.set(false);
return original;
}
}
@WrapOperation(
method = "propagateIncrease",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/chunk/light/ChunkSkyLightProvider;getOpacity(Lnet/minecraft/block/BlockState;)I",
ordinal = 0
),
slice = @Slice(
from = @At(value = "INVOKE", target = "Lnet/minecraft/world/chunk/light/ChunkSkyLightProvider;getStateForLighting(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/block/BlockState;", ordinal = 0)
)
)
private int unreducedDown2(ChunkSkyLightProvider instance, BlockState blockState, Operation<Integer> original, @Share("unreduced") LocalBooleanRef unreduced) {
if (unreduced.get()) {
return blockState.getOpacity();
}
return original.call(instance, blockState);
}
@WrapOperation(
method = "propagateIncrease",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/chunk/light/ChunkSkyLightProvider;enqueueIncrease(JJ)V"
),
slice = @Slice(
from = @At(value = "INVOKE", target = "Lnet/minecraft/world/chunk/light/ChunkSkyLightProvider;getStateForLighting(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/block/BlockState;", ordinal = 0)
)
)
private void passFlagOn(ChunkSkyLightProvider instance, long pos, long flags, Operation<Void> original, @Share("unreduced") LocalBooleanRef unreduced) {
if (unreduced.get()) {
flags |= crystalline_sky$EMISSION_FROM_SKY_BLOCK;
}
original.call(instance, pos, flags);
}
@Definition(id = "k", local = @Local(type = int.class, ordinal = 4))
@Definition(id = "j", local = @Local(type = int.class, ordinal = 1))
@Expression("k <= j - 1")
@ModifyExpressionValue(
method = "propagateDecrease",
at = @At("MIXINEXTRAS:EXPRESSION"),
slice = @Slice(
from = @At(value = "INVOKE", target = "Lnet/minecraft/world/chunk/light/SkyLightStorage;get(J)I"),
to = @At(value = "INVOKE", target = "Lnet/minecraft/world/chunk/light/SkyLightStorage;set(JI)V")
)
)
private boolean cleanBelowSkyLight(boolean original, @Local(ordinal = 1) LocalIntRef j, @Local(ordinal = 4) LocalIntRef k, @SuppressWarnings("LocalMayBeArgsOnly") @Local LocalRef<Direction> direction) {
return original || direction.get() == Direction.DOWN && j.get() == 15 && k.get() == 15;
}
}
@@ -0,0 +1,11 @@
package io.github.slimeistdev.crystalline_sky.mixin;
import net.minecraft.world.chunk.light.LightStorage;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(LightStorage.class)
public interface LightStorageAccessor {
@Invoker("isSectionInEnabledColumn")
boolean crystalline_sky$callIsSectionInEnabledColumn(long sectionPos);
}
@@ -0,0 +1,33 @@
package io.github.slimeistdev.crystalline_sky.registry;
import io.github.slimeistdev.crystalline_sky.CrystallineSky;
import net.minecraft.block.AbstractBlock.Settings;
import net.minecraft.block.Block;
import net.minecraft.block.Blocks;
import net.minecraft.block.TransparentBlock;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.sound.BlockSoundGroup;
import java.util.function.Function;
@SuppressWarnings("SameParameterValue")
public class CrystallineBlocks {
public static final Block SKY = register("sky", TransparentBlock::new, Settings.create()
.strength(0.3f)
.sounds(BlockSoundGroup.GLASS)
.nonOpaque()
.allowsSpawning(Blocks::never)
.solidBlock(Blocks::never)
.suffocates(Blocks::never)
.blockVision(Blocks::never));
public static void init() {}
private static <T extends Block> T register(String id, Function<Settings, T> factory, Settings settings) {
RegistryKey<Block> key = CrystallineSky.key(RegistryKeys.BLOCK, id);
return Registry.register(Registries.BLOCK, key, factory.apply(settings.registryKey(key)));
}
}
@@ -0,0 +1,10 @@
package io.github.slimeistdev.crystalline_sky.registry;
import net.minecraft.item.Item;
import net.minecraft.item.Items;
public class CrystallineItems {
public static final Item SKY = Items.register(CrystallineBlocks.SKY);
public static void init() {}
}
@@ -1,15 +0,0 @@
package io.github.username.modid;
import net.fabricmc.api.ModInitializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ModId implements ModInitializer {
public static final String ID = "mod_id";
public static final Logger LOGGER = LoggerFactory.getLogger(ID);
@Override
public void onInitialize() {
//LOGGER.info("[Mod ID] pretty pink princess ponies prancing perpendicular");
}
}

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

@@ -0,0 +1,21 @@
{
"required": true,
"minVersion": "0.8",
"mixinextras": {
"minVersion": "0.5.0"
},
"package": "io.github.slimeistdev.crystalline_sky.mixin",
"compatibilityLevel": "JAVA_21",
"mixins": [
"ChunkLightProviderMixin",
"ChunkSkyLightProviderMixin",
"LightStorageAccessor"
],
"client": [
],
"server": [
],
"injectors": {
"defaultRequire": 1
}
}
+1 -1
View File
@@ -29,7 +29,7 @@
},
"entrypoints": {
"main": [
"io.github.username.modid.ModId"
"io.github.slimeistdev.crystalline_sky.CrystallineSky"
],
"client": [
]
-15
View File
@@ -1,15 +0,0 @@
{
"required": true,
"minVersion": "0.8",
"package": "io.github.username.modid.mixin",
"compatibilityLevel": "JAVA_21",
"mixins": [
],
"client": [
],
"server": [
],
"injectors": {
"defaultRequire": 1
}
}