From 32fe6e754cfc60add7fcda7e0e503a83276ea550 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Sun, 9 Mar 2025 21:26:44 +0700 Subject: [PATCH 1/4] Provide GJRAND64RandomSource --- gradle.properties | 2 +- .../mc/otm/core/util/GJRAND64RandomSource.kt | 55 +++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/core/util/GJRAND64RandomSource.kt diff --git a/gradle.properties b/gradle.properties index e0c63b221..face01890 100644 --- a/gradle.properties +++ b/gradle.properties @@ -22,7 +22,7 @@ mixin_version=0.8.5 neogradle.subsystems.parchment.minecraftVersion=1.21.1 neogradle.subsystems.parchment.mappingsVersion=2024.11.17 -kommons_version=3.3.2 +kommons_version=3.5.2 caffeine_cache_version=3.1.5 jei_version=19.16.4.171 diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/GJRAND64RandomSource.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/GJRAND64RandomSource.kt new file mode 100644 index 000000000..0f8ac64c8 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/GJRAND64RandomSource.kt @@ -0,0 +1,55 @@ +package ru.dbotthepony.mc.otm.core.util + +import net.minecraft.util.Mth +import net.minecraft.util.RandomSource +import net.minecraft.world.level.levelgen.MarsagliaPolarGaussian +import net.minecraft.world.level.levelgen.PositionalRandomFactory +import ru.dbotthepony.kommons.random.GJRAND64Random +import java.lang.StringBuilder + +class GJRAND64RandomSource : GJRAND64Random, IRandomSourceGenerator { + private val gaussian = MarsagliaPolarGaussian(this) + + constructor(seed: Long) : super(seed) + constructor(seed0: Long, seed1: Long) : super(seed0, seed1) + + override fun nextInt(): Int { + return nextLong().ushr(32).toInt() + } + + override fun nextGaussian(): Double { + return gaussian.nextGaussian() + } + + override fun fork(): RandomSource { + return GJRAND64RandomSource(nextLong(), nextLong()) + } + + override fun forkPositional(): PositionalRandomFactory { + return Positional(nextLong(), nextLong()) + } + + override fun setSeed(seed: Long) { + reinitialize(seed) + gaussian.reset() + } + + class Positional(private val seed0: Long, private val seed1: Long) : PositionalRandomFactory { + override fun at(x: Int, y: Int, z: Int): RandomSource { + val seed = Mth.getSeed(x, y, z) + return GJRAND64RandomSource(seed0.xor(seed.rotateLeft(32)), seed1.xor(seed)) + } + + override fun fromHashOf(name: String): RandomSource { + return GJRAND64RandomSource(name.hashCode().toLong().xor(seed0), seed1) + } + + override fun fromSeed(seed: Long): RandomSource { + return GJRAND64RandomSource(seed) + } + + override fun parityConfigString(builder: StringBuilder) { + throw UnsupportedOperationException() + } + } +} From 3a08552345236bf6fe9db69323f552fca1348af4 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Sun, 9 Mar 2025 21:29:43 +0700 Subject: [PATCH 2/4] private the internal state of positional random --- .../kotlin/ru/dbotthepony/mc/otm/core/util/CMWCRandom.kt | 6 +++--- .../ru/dbotthepony/mc/otm/core/util/LCG64RandomSource.kt | 2 +- .../ru/dbotthepony/mc/otm/core/util/PCG32RandomSource.kt | 2 +- .../ru/dbotthepony/mc/otm/core/util/Xoshiro256Random.kt | 8 ++++---- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/CMWCRandom.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/CMWCRandom.kt index c2891df03..16225f78f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/CMWCRandom.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/CMWCRandom.kt @@ -5,7 +5,7 @@ import net.minecraft.util.RandomSource import net.minecraft.world.level.levelgen.MarsagliaPolarGaussian import net.minecraft.world.level.levelgen.PositionalRandomFactory import net.minecraft.world.level.levelgen.RandomSupport -import ru.dbotthepony.kommons.random.LCG64Random +import ru.dbotthepony.kommons.random.PCG32Random import java.lang.StringBuilder import java.util.random.RandomGenerator @@ -23,7 +23,7 @@ class CMWCRandom(seed: Long = RandomSupport.generateUniqueSeed()) : RandomGenera } override fun setSeed(seed: Long) { - val rng = LCG64Random(seed) + val rng = PCG32Random(seed) // init state with regular LCG produced values for (i in 1 until state.size) { @@ -92,7 +92,7 @@ class CMWCRandom(seed: Long = RandomSupport.generateUniqueSeed()) : RandomGenera return Positional(nextLong()) } - class Positional(val seed: Long) : PositionalRandomFactory { + class Positional(private val seed: Long) : PositionalRandomFactory { override fun at(x: Int, y: Int, z: Int): RandomSource { return CMWCRandom(Mth.getSeed(x, y, z).xor(seed)) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/LCG64RandomSource.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/LCG64RandomSource.kt index 60f07343c..849e38e87 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/LCG64RandomSource.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/LCG64RandomSource.kt @@ -39,7 +39,7 @@ class LCG64RandomSource(seed: Long = RandomSupport.generateUniqueSeed()) : LCG64 return Positional(nextLong()) } - class Positional(val seed: Long) : PositionalRandomFactory { + class Positional(private val seed: Long) : PositionalRandomFactory { override fun at(x: Int, y: Int, z: Int): RandomSource { return LCG64RandomSource(Mth.getSeed(x, y, z).xor(seed)) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/PCG32RandomSource.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/PCG32RandomSource.kt index 7b721c195..ae2f74205 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/PCG32RandomSource.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/PCG32RandomSource.kt @@ -31,7 +31,7 @@ class PCG32RandomSource(seed: Long = RandomSupport.generateUniqueSeed()) : PCG32 return Positional(nextLong()) } - class Positional(val seed: Long) : PositionalRandomFactory { + class Positional(private val seed: Long) : PositionalRandomFactory { override fun at(x: Int, y: Int, z: Int): RandomSource { return PCG32RandomSource(Mth.getSeed(x, y, z).xor(seed)) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/Xoshiro256Random.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/Xoshiro256Random.kt index 5d1e2ee28..133762f55 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/Xoshiro256Random.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/Xoshiro256Random.kt @@ -55,10 +55,10 @@ class Xoshiro256Random : Xoshiro256StarStarRandom, IRandomSourceGenerator { } class Positional( - val s0: Long, - val s1: Long, - val s2: Long, - val s3: Long, + private val s0: Long, + private val s1: Long, + private val s2: Long, + private val s3: Long, ) : PositionalRandomFactory { override fun at(x: Int, y: Int, z: Int): RandomSource { val rng = LCG64RandomSource(Mth.getSeed(x, y, z)) From 9ffee79687f30c2f10173f60fd1e0208c17b2375 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Sun, 9 Mar 2025 21:49:49 +0700 Subject: [PATCH 3/4] Provide "no seed" initialization for GJRAND64 --- .../ru/dbotthepony/mc/otm/core/util/GJRAND64RandomSource.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/GJRAND64RandomSource.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/GJRAND64RandomSource.kt index 0f8ac64c8..c8adbfa13 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/GJRAND64RandomSource.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/GJRAND64RandomSource.kt @@ -4,12 +4,14 @@ import net.minecraft.util.Mth import net.minecraft.util.RandomSource import net.minecraft.world.level.levelgen.MarsagliaPolarGaussian import net.minecraft.world.level.levelgen.PositionalRandomFactory +import net.minecraft.world.level.levelgen.RandomSupport import ru.dbotthepony.kommons.random.GJRAND64Random import java.lang.StringBuilder class GJRAND64RandomSource : GJRAND64Random, IRandomSourceGenerator { private val gaussian = MarsagliaPolarGaussian(this) + constructor() : super(RandomSupport.generateUniqueSeed(), RandomSupport.generateUniqueSeed()) constructor(seed: Long) : super(seed) constructor(seed0: Long, seed1: Long) : super(seed0, seed1) From 755d15fc0b540aa4abd2e4d2564c0e7e1a236ddb Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Sun, 9 Mar 2025 21:52:21 +0700 Subject: [PATCH 4/4] Replace PCG32 with GJRAND64 --- src/data/kotlin/ru/dbotthepony/mc/otm/datagen/DataGen.kt | 4 ++-- src/main/java/ru/dbotthepony/mc/otm/mixin/LevelMixin.java | 4 ++-- src/main/kotlin/ru/dbotthepony/mc/otm/GlobalEventHandler.kt | 4 ++-- .../kotlin/ru/dbotthepony/mc/otm/item/QuantumBatteryItem.kt | 1 - 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/DataGen.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/DataGen.kt index 8ce8671ac..396d3f04d 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/DataGen.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/DataGen.kt @@ -34,7 +34,7 @@ import ru.dbotthepony.mc.otm.datagen.items.MatteryItemModelProvider import ru.dbotthepony.mc.otm.datagen.lang.AddEnglishLanguage import ru.dbotthepony.mc.otm.datagen.models.MatteryBlockModelProvider import ru.dbotthepony.mc.otm.core.registryName -import ru.dbotthepony.mc.otm.core.util.PCG32RandomSource +import ru.dbotthepony.mc.otm.core.util.GJRAND64RandomSource import ru.dbotthepony.mc.otm.data.FlywheelMaterialDataProvider import ru.dbotthepony.mc.otm.datagen.advancements.addAdvancements import ru.dbotthepony.mc.otm.datagen.advancements.addAndroidAdvancements @@ -71,7 +71,7 @@ object DataGen { // for things which need to be random (e.g. UUIDs), // so builds continue to be reproducible - val random = PCG32RandomSource(822393994030754753L) + val random = GJRAND64RandomSource(822393940230754753L, -2728812999467395658L) var blockModelProvider: MatteryBlockModelProvider by WriteOnce() private set diff --git a/src/main/java/ru/dbotthepony/mc/otm/mixin/LevelMixin.java b/src/main/java/ru/dbotthepony/mc/otm/mixin/LevelMixin.java index 30172b5cb..ac4d4e141 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/mixin/LevelMixin.java +++ b/src/main/java/ru/dbotthepony/mc/otm/mixin/LevelMixin.java @@ -5,11 +5,11 @@ import net.minecraft.world.level.Level; import org.jetbrains.annotations.NotNull; import org.spongepowered.asm.mixin.Mixin; import ru.dbotthepony.mc.otm.core.IMatteryLevel; -import ru.dbotthepony.mc.otm.core.util.PCG32RandomSource; +import ru.dbotthepony.mc.otm.core.util.GJRAND64RandomSource; @Mixin(Level.class) public abstract class LevelMixin implements IMatteryLevel { - public final RandomSource otm_random = new PCG32RandomSource(); + public final RandomSource otm_random = new GJRAND64RandomSource(); @Override public @NotNull RandomSource getOtmRandom() { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/GlobalEventHandler.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/GlobalEventHandler.kt index 5f49c00f4..7225eb4a8 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/GlobalEventHandler.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/GlobalEventHandler.kt @@ -21,16 +21,16 @@ import ru.dbotthepony.mc.otm.capability.AbstractProfiledStorage import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.core.collect.WeakHashSet import ru.dbotthepony.mc.otm.core.util.AtomicallyInvalidatedLazy +import ru.dbotthepony.mc.otm.core.util.GJRAND64RandomSource import ru.dbotthepony.mc.otm.core.util.IConditionalTickable import ru.dbotthepony.mc.otm.core.util.ITickable -import ru.dbotthepony.mc.otm.core.util.PCG32RandomSource import ru.dbotthepony.mc.otm.core.util.TickList import ru.dbotthepony.mc.otm.graph.GraphNodeList import java.lang.ref.Cleaner import java.util.* import java.util.concurrent.atomic.AtomicInteger -private val threadLocalRandom = ThreadLocal.withInitial { PCG32RandomSource() } +private val threadLocalRandom = ThreadLocal.withInitial { GJRAND64RandomSource() } internal val THREAD_LOCAL_RANDOM: RandomSource get() = threadLocalRandom.get() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/QuantumBatteryItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/QuantumBatteryItem.kt index 76098d215..9219a8248 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/QuantumBatteryItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/QuantumBatteryItem.kt @@ -44,7 +44,6 @@ import ru.dbotthepony.mc.otm.core.math.set import ru.dbotthepony.mc.otm.core.math.writeDecimal import ru.dbotthepony.mc.otm.core.nbt.set import ru.dbotthepony.mc.otm.core.nextUUID -import ru.dbotthepony.mc.otm.core.util.PCG32RandomSource import ru.dbotthepony.mc.otm.core.util.formatPower import ru.dbotthepony.mc.otm.isClientThread import ru.dbotthepony.mc.otm.isServerThread