9
0
mirror of https://github.com/Winds-Studio/Leaf.git synced 2025-12-19 15:09:25 +00:00

faster-random-generator fix world gen forkPositional seed (#539)

* fix random seed

* re

* move nextInt

* remove impl
This commit is contained in:
hayanesuru
2025-12-11 06:46:30 +09:00
committed by GitHub
parent 6144a9ae91
commit 1144cbce27
2 changed files with 56 additions and 45 deletions

View File

@@ -17,10 +17,12 @@ public class FastRNG extends ConfigModules {
public static String randomGenerator = "Xoroshiro128PlusPlus"; public static String randomGenerator = "Xoroshiro128PlusPlus";
public static boolean warnForSlimeChunk = true; public static boolean warnForSlimeChunk = true;
public static boolean useLegacyForSlimeChunk = false; public static boolean useLegacyForSlimeChunk = false;
@Deprecated
public static boolean useDirectImpl = false; public static boolean useDirectImpl = false;
public static boolean worldgen = false;
public static boolean worldgenEnabled() { public static boolean worldgenEnabled() {
return enabled && enableForWorldgen; return worldgen;
} // Helper function } // Helper function
@Override @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 " + LeafConfig.LOGGER.warn("Set performance.faster-random-generator.warn-for-slime-chunk to false to " +
"disable this warning."); "disable this warning.");
} }
worldgen = enableForWorldgen && enabled;
} }
} }

View File

@@ -5,61 +5,68 @@ import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource; import net.minecraft.util.RandomSource;
import net.minecraft.world.level.levelgen.BitRandomSource; import net.minecraft.world.level.levelgen.BitRandomSource;
import net.minecraft.world.level.levelgen.PositionalRandomFactory; import net.minecraft.world.level.levelgen.PositionalRandomFactory;
import net.minecraft.world.level.levelgen.RandomSupport;
import org.dreeam.leaf.config.modules.opt.FastRNG; 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.RandomGenerator;
import java.util.random.RandomGeneratorFactory; 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 int INT_BITS = 48;
private static final long SEED_MASK = 0xFFFFFFFFFFFFL; private static final long SEED_MASK = 0xFFFFFFFFFFFFL;
private static final long MULTIPLIER = 25214903917L; private static final long MULTIPLIER = 25214903917L;
private static final long INCREMENT = 11L; private static final long INCREMENT = 11L;
private static final RandomGeneratorFactory<RandomGenerator> RANDOM_GENERATOR_FACTORY = RandomGeneratorFactory.of(FastRNG.randomGenerator); private static final RandomGeneratorFactory<RandomGenerator> RANDOM_GENERATOR_FACTORY = RandomGeneratorFactory.of(FastRNG.randomGenerator);
private static final boolean isSplittableGenerator = RANDOM_GENERATOR_FACTORY.isSplittable(); private RandomGenerator delegate;
@Deprecated
private long seed; private long seed;
public static final FasterRandomSource SHARED_INSTANCE = new FasterRandomSource(RandomSupport.generateUniqueSeed());
@Deprecated
private static final boolean useDirectImpl = FastRNG.useDirectImpl; 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) { public FasterRandomSource(long seed) {
this.seed = 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) { private FasterRandomSource(RandomGenerator.SplittableGenerator randomGenerator) {
this.seed = seed; this.seed = randomGenerator.nextLong();
this.randomGenerator = randomGenerator; this.delegate = randomGenerator;
} }
@Override @Override
public final RandomSource fork() { public RandomSource fork() {
if (isSplittableGenerator) { if (useDirectImpl) {
return new FasterRandomSource(seed, ((RandomGenerator.SplittableGenerator) this.randomGenerator).split()); return new FasterRandomSource(this.nextLong());
} }
return RANDOM_GENERATOR_FACTORY.isSplittable()
return new FasterRandomSource(this.nextLong()); ? new FasterRandomSource(((RandomGenerator.SplittableGenerator) this.delegate).split())
: new FasterRandomSource(this.nextLong());
} }
@Override @Override
public final PositionalRandomFactory forkPositional() { public PositionalRandomFactory forkPositional() {
return new FasterRandomSourcePositionalRandomFactory(this.seed); return new FasterRandomSourcePositionalRandomFactory(this.nextLong());
} }
@Override @Override
public final void setSeed(long seed) { public void setSeed(long seed) {
this.seed = seed; this.seed = seed;
this.randomGenerator = RANDOM_GENERATOR_FACTORY.create(seed); this.delegate = RANDOM_GENERATOR_FACTORY.create(seed);
} }
@Override @Override
public final int next(int bits) { public int next(int bits) {
return (int) ((seed = seed * MULTIPLIER + INCREMENT & SEED_MASK) >>> (INT_BITS - 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; private final long seed;
public FasterRandomSourcePositionalRandomFactory(long seed) { public FasterRandomSourcePositionalRandomFactory(long seed) {
@@ -68,9 +75,7 @@ public class FasterRandomSource implements BitRandomSource {
@Override @Override
public RandomSource at(int x, int y, int z) { public RandomSource at(int x, int y, int z) {
long l = Mth.getSeed(x, y, z); return new FasterRandomSource(Mth.getSeed(x, y, z) ^ this.seed);
long m = l ^ this.seed;
return new FasterRandomSource(m);
} }
@Override @Override
@@ -92,17 +97,16 @@ public class FasterRandomSource implements BitRandomSource {
} }
@Override @Override
public final int nextInt() { public int nextInt() {
if (useDirectImpl) { if (useDirectImpl) {
return (int) (((seed = seed * MULTIPLIER + INCREMENT & SEED_MASK) >>> 16) ^ return (int) (((seed = seed * MULTIPLIER + INCREMENT & SEED_MASK) >>> 16) ^
((seed = seed * MULTIPLIER + INCREMENT & SEED_MASK) >>> 32)); ((seed = seed * MULTIPLIER + INCREMENT & SEED_MASK) >>> 32));
} }
return delegate.nextInt();
return randomGenerator.nextInt();
} }
@Override @Override
public final int nextInt(int bound) { public int nextInt(int bound) {
if (useDirectImpl && bound > 0) { if (useDirectImpl && bound > 0) {
if ((bound & -bound) == bound) { if ((bound & -bound) == bound) {
return (int) ((bound * (long) next(31)) >> 31); return (int) ((bound * (long) next(31)) >> 31);
@@ -114,50 +118,53 @@ public class FasterRandomSource implements BitRandomSource {
} while (bits - val + (bound - 1) < 0); } while (bits - val + (bound - 1) < 0);
return val; return val;
} }
return delegate.nextInt(bound);
return randomGenerator.nextInt(bound);
} }
@Override @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) { if (useDirectImpl) {
return ((long) next(32) << 32) + next(32); return ((long) next(32) << 32) + next(32);
} }
return delegate.nextLong();
return randomGenerator.nextLong();
} }
@Override @Override
public final boolean nextBoolean() { public boolean nextBoolean() {
if (useDirectImpl) { if (useDirectImpl) {
return next(1) != 0; return next(1) != 0;
} }
return delegate.nextBoolean();
return randomGenerator.nextBoolean();
} }
@Override @Override
public final float nextFloat() { public float nextFloat() {
if (useDirectImpl) { if (useDirectImpl) {
return next(24) / ((float) (1 << 24)); return next(24) / ((float) (1 << 24));
} }
return delegate.nextFloat();
return randomGenerator.nextFloat();
} }
@Override @Override
public final double nextDouble() { public double nextDouble() {
if (useDirectImpl) { if (useDirectImpl) {
return (((long) next(26) << 27) + next(27)) / (double) (1L << 53); return (((long) next(26) << 27) + next(27)) / (double) (1L << 53);
} }
return delegate.nextDouble();
return randomGenerator.nextDouble();
} }
@Override @Override
public final double nextGaussian() { public double nextGaussian() {
// delegate Gaussian distribution to RandomGenerator // delegate Gaussian distribution to RandomGenerator
// as direct implementation would be complex (i aint doin allat) // as direct implementation would be complex (i aint doin allat)
return randomGenerator.nextGaussian(); return delegate.nextGaussian();
} }
} }