Random number generator

Just out of pure curiosity, does anyone know how the random number generator in ChoiceScript works? How truly random is it?

I was testing some code a few weeks ago, and created a simple coin flip using a random number generator in cs between 1 and 2.

At the time, i had an actual coin in real life, and flipped it alongside it.

It did seem to be roughly 50/50, wheras irl it changed based on what it started on, how high i threw it, etc…

But in my experience, it is generally pretty random. Most of my code in my WIP involves the random number generator to some extent, to calculate dodge rates, (Your dodge percentage is pitted against the enemy’s hit rate,) and the result does seem to be truly random.

For example if you had a random number generator between 1 and 10, i believe each number would have an equal 10% chance of veing picked.

But don’t quote me on this, random is in the name so it may have given me an impossibly unpossible outcome, while others may get more common results.

1 Like

It did? How so?

I use a ton of rands in my current wip, mostly simulated d6 rolls. Done a lot of playtesting, and it seems to be returning the kind of results I’d expect when tossing dice, which suggests genuine randomness.

In a previous (now published) project, I included a casino scene which also used many rands, and I even used rand to simulate AI, by randomly selecting what the opponent would do in a game of blackjack, but tweaking the odds to make some moves more or less likely based on the current state of the game (i.e. making the opponent more likely to stick than twist the closer they got to 21). That seems to work too.

I don’t know the precise mechanics of how rand is configured, but everything I’ve seen suggests that it gives a very good facsimile of genuine randomness.

5 Likes

I mean, that after a few throws of practice, I had figured out how hard/high to toss the coin to achieve an intended result with around 75% certainty, this would not be possible in the cs version.

1 Like

My understanding is *rand is basically using JavaScript’s Math.random() function.

scene.js[source]
// *rand varname min max
// Set varname to a random number from min to max
//
// Example:
// *rand foo 1 6
//   roll a cube die
// *rand foo 1.0 6.0
//   compute a decimal from [1.0,6.0)
Scene.prototype.rand = function rand(data) {
    var stack = this.tokenizeExpr(data);
    if (!stack.length) throw new Error(this.lineMsg() + "Invalid rand statement, expected three args: varname min max");
    var variable = this.evaluateReference(stack);
    if ("undefined" === typeof this.temps[variable] && "undefined" === typeof this.stats[variable]) {
      throw new Error(this.lineMsg() + "Non-existent variable '"+variable+"'");
    }

    if (!stack.length) throw new Error(this.lineMsg() + "Invalid rand statement, expected three args: varname min max");
    var minimum = this.evaluateValueToken(stack.shift(), stack);
    if (!stack.length) throw new Error(this.lineMsg() + "Invalid rand statement, expected three args: varname min max");
    var maximum = this.evaluateValueToken(stack.shift(), stack);
    if (stack.length) throw new Error(this.lineMsg() + "Invalid rand statement, expected three args: varname min max");
    var diff;

    diff = maximum - minimum;
    if (isNaN(diff)) {
        throw new Error(this.lineMsg() + "Invalid rand statement, min and max must be numbers");
    }
    if (diff < 0) {
        throw new Error(this.lineMsg() + "Invalid rand statement, min must be less than max: " + minimum + " > " + maximum);
    }
    if (diff === 0) {
      this.setVar(variable, minimum);
      return;
    }
    function isInt(x) {
       var y=parseInt(x,10);
       if (isNaN(y)) return false;
       return x==y && x.toString()==y.toString();
    }
    var result;
    var random = Math.random();
    if (isInt(minimum) && isInt(maximum)) {
        // int random
        result = 1*minimum + Math.floor(random*(diff+1));
    } else {
        result = 1*minimum + random*diff;
    }
    this.setVar(variable, result);
    if (this.randomLog) {
      this.randomLog("*rand " + variable + " " + result);
    }
    if (this.nav) this.nav.bugLog.push("*rand " + variable + " " + result);
};

As for how good it is — don’t use it to encrypt anything, but it’s more than random enough for ChoiceScript games. It’s not truly random; it uses a pseudorandom number generator (PRNG) algorithm chosen by your browser.

I think most browsers are using xorshift128+, but I’m not 100% positive on that.

7 Likes

Just came here to say this. There’s no true randomness in computer science. You can use pseudo-random algorithms. ChoiceScript’s *rand just uses JavaScript Math.random, which is more than enough, not only for ChoiceScript games but for all Web applications out there.

7 Likes

Okay, so it does use an algorithm, but it works very well to simulate genuine randomness. Better than some PRNG out there, depending on the algorithm I suppose.

I would like to know how those algorithms work, but that’s probably beyond my current level of understanding.

Just keep in mind the flaw in Choicescript, which involves the stat page refreshing and changing the roll at the reader’s will.

3 Likes

Yes, this is what I came here to say. Random number generation is a deep rabbit hole in computer science.

ChoiceScript’s deeper functions are broadly a convenience wrapper for JavaScript. If you need to know more about how it works “under the hood”, learning a bit of basic JS will go a long way.

(JavaScript’s RNG is certainly more reliable than the one I had to use in school, that only worked when I ran it through the debugger.)

2 Likes

I actually assumed it was pseudo, and I wondered how it still managed to be so random. I remember that the fan community of one of my favorite computer games had a lot of complaints about how a certain thing that involved multiple random generations would happen the same way every time after starting the game, and I was pleasantly surprised that ChoiceScript, which is a monumentally simpler engine, actually does a really good job of it.

2 Likes

Basically, every pseudo-random algorithm uses a seed, that is, a starting number. Then applies a series of operations to get a result. If ou use the same seed as input you will always get the same result. One trick used by these algorithms is to use a source of “real” entropy from one of the device’s sensors, for exemple, CPU’s voltage, mouse movement, environmental noise captured through the microphone, etc.

JavaScript’s Math.random allows you to set the seed, so you can force it to always yield the same number. But ChoiceScript’s *rand doesn’t allow you to set the seed.

3 Likes

That’s a bit similar to how random.org works, isn’t it?

2 Likes

It appears to be so. They say they use atmospheric noise.

JavaScript’s Math.random usually uses the current timestamp (which includes milliseconds). But it depends on the browser. So, by extension, that’s how ChoiceScript works too.

2 Likes

Dude! This thread i fascinating! The first time I depared with the idea of writing randomness in CS was when I tried to wrote a Tic-Tac-Toe game… And it blows my mind! :smiley:

I fell in love with the concept, and often I write little toy programs to try to convert such a thing in game mechanics like weather, inflation rates, prices fluctuations and what-not. Its so fun!

Ok this was way cooler than anything I ever made in ChoiceScript! You’re a true code artist!

You call it a flaw? I call it a Feature! (YES I am a cheater. Call me shameless) tongue in cheek

1 Like

can you share your games? I also learn JS at and try everything new)
also I recommend check this MVP Development Services for Startups | IT Craft

1 Like

He has a couple published under the Hosted Games. I don’t know how many uses RND though.

Well other than the blackjack one…

Edit: “Welcome to the Forums dude!”

nice, I’ll check)