Prevent Zero Length skybox bouncing
Build / build (push) Canceled after 0s

This commit is contained in:
dnorberg committed 2026-09-22 16:50:15 -04:00
1 parent 2b18f776f2
commit 98ecc797fd
6 files changed
+13 -42

No files matched your search

@@ -13,7 +13,6 @@ import net.dnorberg.rivencraft.config.RivencraftConfig;
import net.dnorberg.rivencraft.config.RivencraftClientConfig;
import net.dnorberg.rivencraft.book.AgeDimensionService;
import net.dnorberg.rivencraft.book.AgeWeatherService;
import net.dnorberg.rivencraft.book.AgeCelestialService;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.fml.ModContainer;
import net.neoforged.fml.common.Mod;
@@ -39,7 +38,6 @@ public final class Rivencraft {
ModCreativeTabs.register(modEventBus);
NeoForge.EVENT_BUS.addListener(BookStandConversionHandler::onRightClickBlock);
NeoForge.EVENT_BUS.addListener(AgeWeatherService::onLevelTickPost);
NeoForge.EVENT_BUS.addListener(AgeCelestialService::onLevelTickPost);
LOGGER.info("Initializing Rivencraft");
}
}
@@ -1,31 +0,0 @@
package net.dnorberg.rivencraft.book;
import java.util.Map;
import java.util.WeakHashMap;
import net.minecraft.server.level.ServerLevel;
import net.neoforged.neoforge.event.tick.LevelTickEvent;
/** Holds Zero Length Age clocks without changing the server-wide daylight gamerule. */
public final class AgeCelestialService {
private static final Map<ServerLevel, Long> FROZEN_TIMES = new WeakHashMap<>();
private AgeCelestialService() {
}
public static void freezeAt(ServerLevel level, long dayTime) {
FROZEN_TIMES.put(level, dayTime);
}
public static void unfreeze(ServerLevel level) {
FROZEN_TIMES.remove(level);
}
public static void onLevelTickPost(LevelTickEvent.Post event) {
if (event.getLevel() instanceof ServerLevel level) {
Long frozenTime = FROZEN_TIMES.get(level);
if (frozenTime != null && level.getDayTime() != frozenTime) {
level.setDayTime(frozenTime);
}
}
}
}
@@ -104,10 +104,12 @@ public final class AgeDimensionService {
private static void applyCelestialClock(ServerLevel level, AgeDefinition age) {
if (age.traits().hasStoppedCelestialCycle()) {
level.setDayTimePerTick(-1.0F);
AgeCelestialService.freezeAt(level, level.getDayTime());
// NeoForge rejects an exact zero rate. The smallest positive float
// never advances the integer clock during a practical world
// lifetime and avoids a one-tick-forward/one-tick-back correction
// that makes the client sky visibly bounce.
level.setDayTimePerTick(Float.MIN_VALUE);
} else {
AgeCelestialService.unfreeze(level);
level.setDayTimePerTick((float)(1.0D / age.traits().celestialPeriod()));
}
}
@@ -115,9 +117,6 @@ public final class AgeDimensionService {
private static void applyInitialCelestialPhase(ServerLevel level, AgeDefinition age) {
long phaseTime = (long)(age.traits().celestialPhase() * Level.TICKS_PER_DAY);
level.setDayTime(phaseTime);
if (age.traits().hasStoppedCelestialCycle()) {
AgeCelestialService.freezeAt(level, phaseTime);
}
}
private static void synchronizeImmersivePortals(MinecraftServer server) {
@@ -188,8 +188,8 @@ public final class LinkingGameTests {
helper.assertTrue(Math.abs(level.dimensionType().ambientLight() - expectedAmbientLight) < 0.0001F,
"The runtime dimension must apply the persisted lighting trait");
if (definition.traits().hasStoppedCelestialCycle()) {
helper.assertTrue(level.getDayTimePerTick() < 0.0F,
"A Zero Length Age must leave vanilla clock advancement under the freeze controller");
helper.assertValueEqual(level.getDayTimePerTick(), Float.MIN_VALUE,
"A Zero Length Age must use the stationary nonzero clock rate");
} else {
float expectedDaySpeed = (float)(1.0D / definition.traits().celestialPeriod());
helper.assertTrue(Math.abs(level.getDayTimePerTick() - expectedDaySpeed) < 0.0001F,