1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-05 08:34:22 +03:00

Partially mitigate the flaw in Glulx interpreter RNGs

This commit is contained in:
Dannii Willis 2024-05-03 11:27:35 +10:00
parent dc839857d0
commit 71e5b394d2

View file

@ -102,14 +102,35 @@ of the current time of day, which is unlikely to repeat or show any pattern
in real-world use. However, early Z-machine interpreters often did this quite
badly, starting with poor seed values which meant that the first few random
numbers always had something in common (being fairly small in their range,
for instance). To obviate this we extract and throw away 100 random numbers
to get the generator going, shaking out more obvious early patterns, but
that cannot really help much if the VM interpreter's RNG is badly written.
for instance).
More recently, many Glulx interpreters also had
[a major flaw](https://intfiction.org/t/lack-of-randomness-sometimes-when-compiling-for-glulx/64533)
in which repeatedly calling `random(N)` when `N` was a power of 2 resulted in
there only being `N` distinct sequences. Even worse, the first number of each
sequence might be the same! This would mean that, for example, if a mystery
game randomly selected the murderer from five candidates the results might
appear random, but if there were only four candidates then the same one would
be chosen *every* playthrough.
To attempt to partially mitigate these problems, we extract and throw away a
number of random numbers to get the generator going, shaking out more obvious
early patterns. Because of the particular nature of the flaw in those Glulx
interpreters, we do this a random number of times.
Most interpreters have been updated recently to improve their random algorithms,
but if we're running in something really old, there's only so much we can do
to account for it. Story files which rely on quality randomness may need to
use an extension to use a new algorithm instead of the one provided by the
interpreter. Extensions are also needed if you want a random algorithm that is
consistent across interpreters (for example, to be able to share a seed that
generates the same dungeon in an procedurally-generated RPG.)
"Anyone who considers arithmetical methods of producing random digits is,
of course, in a state of sin" (von Neumann).
=
[ SEED_RANDOM_NUMBER_GENERATOR_R i;
[ SEED_RANDOM_NUMBER_GENERATOR_R i count;
if (BasicInformKit`FIX_RNG_CFGF) {
#Ifdef TARGET_GLULX;
@random 10000 i;
@ -122,6 +143,7 @@ of course, in a state of sin" (von Neumann).
#Endif;
}
if (RNG_SEED_AT_START_OF_PLAY) VM_Seed_RNG(RNG_SEED_AT_START_OF_PLAY);
for (i=1: i<=100: i++) random(i);
count = random(97);
for (i = 1: i <= count: i++) random(i);
rfalse;
];