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

+5
View File
@@ -304,6 +304,11 @@ random outcome using its effective one-in-seven grammar weight. Zero Length
freezes an Age at its generated phase without changing the global daylight
cycle, while nonzero Ages retain their independently scaled clocks.
Version 0.2.20.2 gives Zero Length Ages a stationary per-dimension clock rate
instead of advancing and correcting their time once per tick. This keeps the
integer day time fixed while preventing the client skybox from visually
bouncing between adjacent celestial positions.
Version 0.2.14.0 restores the legacy Linking and Descriptive Book artwork for
inventory items and gives each book its matching open-book texture when placed
on a Book Stand. Return Linking Books created inside another Age also retain and
+1 -1
View File
@@ -35,7 +35,7 @@ mod_name=Rivencraft
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
mod_license=LGPL-3.0-or-later
# The mod version. Rivencraft uses the x.y.z.b policy documented in README.md.
mod_version=0.2.20.1
mod_version=0.2.20.2
immersive_portals_version=6.0.7
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
# This should match the base package used for the mod sources.
@@ -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,