tmedwards / sugarcube-2

SugarCube is a free (gratis and libre) story format for Twine/Twee.
https://www.motoslave.net/sugarcube/2/
BSD 2-Clause "Simplified" License
177 stars 41 forks source link

Randomization is not consistent between sessions #49

Closed Glinkis closed 4 years ago

Glinkis commented 4 years ago

Initializing the prng state with the same seed in different browser tabs yields different results.

// Using setTimeout to wait for all scripts to finish initializing.
setTimeout(() => {
  console.log(State.prng.isEnabled())
  console.log(State.prng.seed)
  console.log(State.prng.pull)
  console.log(State.random())
})

Tab 1:

true
wavyorangeneonrainbowfish
5350
0.6990063451940978

Tab 2:

true
wavyorangeneonrainbowfish
5336
0.20215290072679626

Refreshing the same tab multiple times seems to be consistent, but if I clear the session state and refresh I get a different pull/float again.

tmedwards commented 4 years ago

Are you enabling extra entropy? If so, the specified seed is only part of the actual seed used, extra random entropy is added to it to create the final seed. Thus, you wouldn't be using the same effective seed.

Beyond that, the pull count in your two examples is different, which means that the internal states of the two seedable PRNGs are at different points—i.e., you're comparing apples to oranges, so of course they aren't going to be the same. Try getting the pull count to the same value and, if you're not adding extra entropy, you should see that the results are indeed the same.

The seedable PRNG works across completely different browser JavaScript engines, let alone different instances of the same JavaScript engine in the same browser.

Glinkis commented 4 years ago

You're absolutely correct. It turns out our issue was that we had data structures that were generated with some randomization before we actually set the seed. So when we used those after setting the seed, of course the results would vary, even though the pull count showed the same.