diff --git a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/FastRNG.java b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/FastRNG.java index c51dd431..7f50aa92 100644 --- a/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/FastRNG.java +++ b/leaf-server/src/main/java/org/dreeam/leaf/config/modules/opt/FastRNG.java @@ -17,10 +17,12 @@ public class FastRNG extends ConfigModules { public static String randomGenerator = "Xoroshiro128PlusPlus"; public static boolean warnForSlimeChunk = true; public static boolean useLegacyForSlimeChunk = false; + @Deprecated public static boolean useDirectImpl = false; + public static boolean worldgen = false; public static boolean worldgenEnabled() { - return enabled && enableForWorldgen; + return worldgen; } // Helper function @Override @@ -88,5 +90,7 @@ public class FastRNG extends ConfigModules { LeafConfig.LOGGER.warn("Set performance.faster-random-generator.warn-for-slime-chunk to false to " + "disable this warning."); } + + worldgen = enableForWorldgen && enabled; } } diff --git a/leaf-server/src/main/java/org/dreeam/leaf/util/math/random/FasterRandomSource.java b/leaf-server/src/main/java/org/dreeam/leaf/util/math/random/FasterRandomSource.java index 301a66ee..38461fa6 100644 --- a/leaf-server/src/main/java/org/dreeam/leaf/util/math/random/FasterRandomSource.java +++ b/leaf-server/src/main/java/org/dreeam/leaf/util/math/random/FasterRandomSource.java @@ -5,61 +5,68 @@ import net.minecraft.util.Mth; import net.minecraft.util.RandomSource; import net.minecraft.world.level.levelgen.BitRandomSource; import net.minecraft.world.level.levelgen.PositionalRandomFactory; +import net.minecraft.world.level.levelgen.RandomSupport; import org.dreeam.leaf.config.modules.opt.FastRNG; +import org.jspecify.annotations.NullMarked; -import java.util.concurrent.ThreadLocalRandom; import java.util.random.RandomGenerator; import java.util.random.RandomGeneratorFactory; -public class FasterRandomSource implements BitRandomSource { +@NullMarked +public final class FasterRandomSource implements BitRandomSource { private static final int INT_BITS = 48; private static final long SEED_MASK = 0xFFFFFFFFFFFFL; private static final long MULTIPLIER = 25214903917L; private static final long INCREMENT = 11L; private static final RandomGeneratorFactory RANDOM_GENERATOR_FACTORY = RandomGeneratorFactory.of(FastRNG.randomGenerator); - private static final boolean isSplittableGenerator = RANDOM_GENERATOR_FACTORY.isSplittable(); + private RandomGenerator delegate; + @Deprecated private long seed; + public static final FasterRandomSource SHARED_INSTANCE = new FasterRandomSource(RandomSupport.generateUniqueSeed()); + @Deprecated private static final boolean useDirectImpl = FastRNG.useDirectImpl; - private RandomGenerator randomGenerator; - public static final FasterRandomSource SHARED_INSTANCE = new FasterRandomSource(ThreadLocalRandom.current().nextLong()); public FasterRandomSource(long seed) { this.seed = seed; - this.randomGenerator = RANDOM_GENERATOR_FACTORY.create(seed); + this.delegate = RANDOM_GENERATOR_FACTORY.create(seed); } - private FasterRandomSource(long seed, RandomGenerator.SplittableGenerator randomGenerator) { - this.seed = seed; - this.randomGenerator = randomGenerator; + private FasterRandomSource(RandomGenerator.SplittableGenerator randomGenerator) { + this.seed = randomGenerator.nextLong(); + this.delegate = randomGenerator; } @Override - public final RandomSource fork() { - if (isSplittableGenerator) { - return new FasterRandomSource(seed, ((RandomGenerator.SplittableGenerator) this.randomGenerator).split()); + public RandomSource fork() { + if (useDirectImpl) { + return new FasterRandomSource(this.nextLong()); } - - return new FasterRandomSource(this.nextLong()); + return RANDOM_GENERATOR_FACTORY.isSplittable() + ? new FasterRandomSource(((RandomGenerator.SplittableGenerator) this.delegate).split()) + : new FasterRandomSource(this.nextLong()); } @Override - public final PositionalRandomFactory forkPositional() { - return new FasterRandomSourcePositionalRandomFactory(this.seed); + public PositionalRandomFactory forkPositional() { + return new FasterRandomSourcePositionalRandomFactory(this.nextLong()); } @Override - public final void setSeed(long seed) { + public void setSeed(long seed) { this.seed = seed; - this.randomGenerator = RANDOM_GENERATOR_FACTORY.create(seed); + this.delegate = RANDOM_GENERATOR_FACTORY.create(seed); } @Override - public final int next(int bits) { - return (int) ((seed = seed * MULTIPLIER + INCREMENT & SEED_MASK) >>> (INT_BITS - bits)); + public int next(int bits) { + if (useDirectImpl) { + return (int) ((seed = seed * MULTIPLIER + INCREMENT & SEED_MASK) >>> (INT_BITS - bits)); + } + return (int) (nextLong() >>> (64 - bits)); } - public static class FasterRandomSourcePositionalRandomFactory implements PositionalRandomFactory { + private static final class FasterRandomSourcePositionalRandomFactory implements PositionalRandomFactory { private final long seed; public FasterRandomSourcePositionalRandomFactory(long seed) { @@ -68,9 +75,7 @@ public class FasterRandomSource implements BitRandomSource { @Override public RandomSource at(int x, int y, int z) { - long l = Mth.getSeed(x, y, z); - long m = l ^ this.seed; - return new FasterRandomSource(m); + return new FasterRandomSource(Mth.getSeed(x, y, z) ^ this.seed); } @Override @@ -92,17 +97,16 @@ public class FasterRandomSource implements BitRandomSource { } @Override - public final int nextInt() { + public int nextInt() { if (useDirectImpl) { return (int) (((seed = seed * MULTIPLIER + INCREMENT & SEED_MASK) >>> 16) ^ ((seed = seed * MULTIPLIER + INCREMENT & SEED_MASK) >>> 32)); } - - return randomGenerator.nextInt(); + return delegate.nextInt(); } @Override - public final int nextInt(int bound) { + public int nextInt(int bound) { if (useDirectImpl && bound > 0) { if ((bound & -bound) == bound) { return (int) ((bound * (long) next(31)) >> 31); @@ -114,50 +118,53 @@ public class FasterRandomSource implements BitRandomSource { } while (bits - val + (bound - 1) < 0); return val; } - - return randomGenerator.nextInt(bound); + return delegate.nextInt(bound); } @Override - public final long nextLong() { + public int nextInt(int origin, int bound) { + if (useDirectImpl && bound > 0) { + return origin + this.nextInt(bound - origin); + } + return delegate.nextInt(origin, bound); + } + + @Override + public long nextLong() { if (useDirectImpl) { return ((long) next(32) << 32) + next(32); } - - return randomGenerator.nextLong(); + return delegate.nextLong(); } @Override - public final boolean nextBoolean() { + public boolean nextBoolean() { if (useDirectImpl) { return next(1) != 0; } - - return randomGenerator.nextBoolean(); + return delegate.nextBoolean(); } @Override - public final float nextFloat() { + public float nextFloat() { if (useDirectImpl) { return next(24) / ((float) (1 << 24)); } - - return randomGenerator.nextFloat(); + return delegate.nextFloat(); } @Override - public final double nextDouble() { + public double nextDouble() { if (useDirectImpl) { return (((long) next(26) << 27) + next(27)) / (double) (1L << 53); } - - return randomGenerator.nextDouble(); + return delegate.nextDouble(); } @Override - public final double nextGaussian() { + public double nextGaussian() { // delegate Gaussian distribution to RandomGenerator // as direct implementation would be complex (i aint doin allat) - return randomGenerator.nextGaussian(); + return delegate.nextGaussian(); } }