Pseudorandom Numbers


Randomness is a funny thing. Is everything predefined? Does Randomness even exists? Is everything the result of an complicated simulation?

Anyway, Pseudorandom Number Generators exist and can be used to generate sometimes more, sometimes less random numbers. I needed such an Generator to make the Levels for Scrapped Robot. Since the game is written in Javascript, the first thought would be to use Math.random. And the Jam version did exactly that. But there is a big downside. You can't define the seed of Math.random. So each Level is random, but I can't recreate an individual Level. While the thought of the Level existing only for the time you are playing the game is quite lovely, I wanted to be able to share the same random generated Level with other people. The funny thing about Pseudorandom Number Generators is that they are not random. Hence the pseudo before the random. But most people, including me, use them to get random Numbers. The »truly« random part in an PRNG is the seed. It's defined by the current time, heat or what ever the language implementor thought would be random. Everything after the seed is predictably if you know what PRNG is used. Since i'm only writing an game, i'm in no need of »true« randomness like some cryptographer. So i can keep it simple.

I use an simple Xorshift, which I got from somewhere I don't remember:

var Xorshift = function( seed ) {  var x = (seed | 0) ||  var y = 362436069  var z = 521288629  var w = 88675123  return function() {    var t = x ^ (x << 11)    x = y    y = z    z = w    w ^= (w >> 19) ^ t ^ (t >> 8)    return w * 4.656612873e-10  }}

And the usage:

var r = new Xorshift( 1024 )console.log( r() ) // 0.042273475787831104console.log( r() ) // 0.48130794380922876r = new Xorshift( 1024 )console.log( r() ) // 0.042273475787831104

The same seed gives me the same list of numbers. Thats great. Now I can generate a level and just have to give the seed to another person and he can generate the same level.

The whole reason i'm writing this is a little bit deeper into the whole randomness game. I ran into cross platform problems between chrome and safari. The first level looked almost the same, but the second one was completely different. My first guess was some floating point rounding problems. But the Xorshift alone like written above worked perfectly. After a little debugging I found the culprit. I had an array with directions that needed to be shuffled. And I shuffled like this:

dir.sort( function() {  return random() * 2 - 1})

Thats not the whole and actual code, but illustrates the problem. While the above gives me an shuffled array, it gave me different shuffled arrays on different platforms. The browser vendors all have their own preferred sorting algorithm, so the call of above random function varied. With my own shuffle function everything was working like expected on the different platforms.

Yeah, sometimes you have to take randomness away to get the randomness you want.