Apply persisted Age celestial timing
Build / build (push) Canceled after 0s

This commit is contained in:
dnorberg committed 2026-09-22 16:37:33 -04:00
1 parent 04006ee36a
commit 8bb5e16720
5 files changed
+29 -3

No files matched your search

+8
View File
@@ -291,6 +291,14 @@ Always, Cloudy, Rain, and Snow maintain non-thundering precipitation; Storm
maintains rain and thunder. Minecraft still chooses rain versus snow from biome maintains rain and thunder. Minecraft still chooses rain versus snow from biome
temperature, so dedicated Snow/Rain biome overrides remain future work. temperature, so dedicated Snow/Rain biome overrides remain future work.
Version 0.2.20.0 applies persisted celestial timing to each Age. The saved
period controls NeoForge's per-dimension clock rate, with a period of 1 matching
a vanilla 20-minute day, 0.2 running five times faster, and 2 running at half
speed. The saved phase sets the clock only during first-spawn initialization;
later loads continue from saved world time. Celestial angle remains persisted
for a future custom sky renderer because vanilla dimension data cannot rotate
the sun's render plane.
Version 0.2.14.0 restores the legacy Linking and Descriptive Book artwork for 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 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 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. # 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 mod_license=LGPL-3.0-or-later
# The mod version. Rivencraft uses the x.y.z.b policy documented in README.md. # The mod version. Rivencraft uses the x.y.z.b policy documented in README.md.
mod_version=0.2.19.0 mod_version=0.2.20.0
immersive_portals_version=6.0.7 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. # 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. # This should match the base package used for the mod sources.
@@ -21,7 +21,7 @@ public record AgeDefinition(
public static final ResourceLocation RANDOM_VANILLA_PROFILE = ResourceLocation.fromNamespaceAndPath( public static final ResourceLocation RANDOM_VANILLA_PROFILE = ResourceLocation.fromNamespaceAndPath(
Rivencraft.MOD_ID, "random_vanilla" Rivencraft.MOD_ID, "random_vanilla"
); );
public static final int CURRENT_GENERATION_VERSION = 5; public static final int CURRENT_GENERATION_VERSION = 6;
public AgeDefinition { public AgeDefinition {
Objects.requireNonNull(id, "id"); Objects.requireNonNull(id, "id");
@@ -46,11 +46,14 @@ public final class AgeDimensionService {
DynamicDimensionLoadCallback.register((server, loader) -> { DynamicDimensionLoadCallback.register((server, loader) -> {
ServerLevel overworld = server.overworld(); ServerLevel overworld = server.overworld();
for (AgeDefinition age : AgeRegistrySavedData.get(overworld).definitions()) { for (AgeDefinition age : AgeRegistrySavedData.get(overworld).definitions()) {
loader.loadDynamicDimension( ServerLevel level = loader.loadDynamicDimension(
age.dimensionId(), age.dimensionId(),
createGenerator(server, age), createGenerator(server, age),
createDimensionType(age) createDimensionType(age)
); );
if (level != null) {
applyCelestialClock(level, age);
}
} }
synchronizeImmersivePortals(server); synchronizeImmersivePortals(server);
}); });
@@ -65,6 +68,7 @@ public final class AgeDimensionService {
BlockPos spawn = definition.spawn(); BlockPos spawn = definition.spawn();
if (spawn == null) { if (spawn == null) {
applyInitialCelestialPhase(level, definition);
spawn = createSafeSpawn(level, definition); spawn = createSafeSpawn(level, definition);
definition = AgeRegistrySavedData.get(level).setSpawn(definition.id(), spawn); definition = AgeRegistrySavedData.get(level).setSpawn(definition.id(), spawn);
} }
@@ -79,6 +83,7 @@ public final class AgeDimensionService {
ResourceKey<Level> key = dimensionKey(definition); ResourceKey<Level> key = dimensionKey(definition);
ServerLevel existing = server.getLevel(key); ServerLevel existing = server.getLevel(key);
if (existing != null) { if (existing != null) {
applyCelestialClock(existing, definition);
return existing; return existing;
} }
@@ -91,11 +96,21 @@ public final class AgeDimensionService {
if (loaded == null) { if (loaded == null) {
Rivencraft.LOGGER.error("Failed to load Age {} as {}", definition.id(), definition.dimensionId()); Rivencraft.LOGGER.error("Failed to load Age {} as {}", definition.id(), definition.dimensionId());
} else { } else {
applyCelestialClock(loaded, definition);
synchronizeImmersivePortals(server); synchronizeImmersivePortals(server);
} }
return loaded; return loaded;
} }
private static void applyCelestialClock(ServerLevel level, AgeDefinition age) {
level.setDayTimePerTick((float)(1.0D / age.traits().celestialPeriod()));
}
private static void applyInitialCelestialPhase(ServerLevel level, AgeDefinition age) {
long phaseTime = (long)(age.traits().celestialPhase() * Level.TICKS_PER_DAY);
level.setDayTime(phaseTime);
}
private static void synchronizeImmersivePortals(MinecraftServer server) { private static void synchronizeImmersivePortals(MinecraftServer server) {
if (ModList.get().isLoaded("immersive_portals_core")) { if (ModList.get().isLoaded("immersive_portals_core")) {
ImmersivePortalsChunkLoaders.dimensionsChanged(server); ImmersivePortalsChunkLoaders.dimensionsChanged(server);
@@ -186,6 +186,9 @@ public final class LinkingGameTests {
? 0.25F : 0.0F; ? 0.25F : 0.0F;
helper.assertTrue(Math.abs(level.dimensionType().ambientLight() - expectedAmbientLight) < 0.0001F, helper.assertTrue(Math.abs(level.dimensionType().ambientLight() - expectedAmbientLight) < 0.0001F,
"The runtime dimension must apply the persisted lighting trait"); "The runtime dimension must apply the persisted lighting trait");
float expectedDaySpeed = (float)(1.0D / definition.traits().celestialPeriod());
helper.assertTrue(Math.abs(level.getDayTimePerTick() - expectedDaySpeed) < 0.0001F,
"The runtime dimension must apply the persisted celestial period");
} }
helper.succeed(); helper.succeed();
} }