Compare commits
2 Commits
5d15425fa4
...
7c6d58b782
Author | SHA1 | Date | |
---|---|---|---|
7c6d58b782 | |||
42386e1fbe |
@ -5,13 +5,25 @@ 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
|
||||
|
Loading…
Reference in New Issue
Block a user