Compare commits

..

No commits in common. "7c6d58b7827e51a7645178e277eeaa734d70d0d8" and "5d15425fa4e4b8b7580511b9eea521ead45f1946" have entirely different histories.

View File

@ -5,25 +5,13 @@ import net.minecraft.world.level.Level
import net.neoforged.fml.ModList
interface IMatteryLevel {
/**
* OTM provided [RandomSource], which has better statistical parameters
*
* Original Minecraft use LCG, which may show bad behavior when repeatedly sampled *a lot*,
* which is what [Level]'s random is used for. OTM provided PRNG should behave better in this scenario.
*/
val otmRandom: RandomSource?
}
/**
* OTM provided [RandomSource], which has better statistical parameters
*
* Original Minecraft use LCG, which may show bad behavior when repeatedly sampled *a lot*,
* which is what [Level]'s random is used for. OTM provided PRNG should behave better in this scenario.
*
* The way OTM uses random generator in its code will quickly cause LCG used in Minecraft to show its bias
* because LCG in minecraft samples its highest 48 bits, which gives us at best 2^16 period in the lowest bit returned by LCG.
* Which it doesn't sound bad, it quickly causes RNG become biased the quicker/more it is sampled on each tick, especially considering
* some may use `level.random.nextInt(chance) == 0` to determine chance of something happening,
* which will get extremely biased on heavy RNG congested environment
* If we avoid sampling Level's generator this much, we won't suffer from bias in our own code, as well as avoid biasing other mods this much.
*
* The "2^16 period" problem is also might be the reason why Entities get their own instance of RandomSource,
* and Mob Goals use random exactly the way described above (`nextInt(chance)`), which can and will suffer
* from bias the moment mob exists in world for more than 2^16 ticks (but actual bias will happen sooner
* because RNG is not sampled only once per tick, obviously)
*/
val Level.otmRandom: RandomSource get() = (this as IMatteryLevel).otmRandom ?: random