Programming involves giving specific instructions but sometimes you want the ability to introduce random behavior. Maybe you want to simulate how a human character sometimes does things in a different order or takes a different path. Or maybe you want the computer to select various items from a collection. Or maybe you want to simulate the randomness of rolling dice. This episode explains how to do this.
Your programming language likely gives you classes or methods to generate random values but while the sequence of values might look random, they’re actually pseudo-random. If you use the same seed value to start the sequence in two different random number generators that are each using the same techniques to generate random numbers, then you’re going to get the same sequence.
This could lead to your customer playing a great first game but then getting bored because the same things happen each time. You really want to use different seeds when using random numbers to determine the computer’s responses to the player’s actions.
But if you’re also using random numbers to generate your world details, then you might actually want the same seed to be used so that the world is the same when the player restarts the same game.
Listen to the full episode about random numbers, or you can also read the full transcript below.
The first thing to understand is that a computer processor cannot by itself produce anything random. That’s just not how it works. It follows specific instructions that some programmer has written. Even the code that produces random numbers is subject to these conditions. If you ask for a random number from zero through nine, you’ll get a number, let’s say eight. There’s not much you can conclude about the randomness of a single number. If you had received zero instead of eight, would that mean your random number generating code is any more or less random? No. The only thing you can judge is how well the numbers are distributed across many calls asking for a random number.
For a uniform distribution of one thousand requests for a random number, you should expect to get about 100 results of each digit. You may get only 90 twos and that could be okay. At least it’s close to 100. If you got exactly 100 of each digit, then that would be suspicious, but again, it may be okay. If you did this same test and always get exactly 100 results of each digit, then there’s probably something wrong. And the same thing goes for low results. If you ask for one thousand results and get only 10 threes, then there’s probably something wrong.
How does the computer create what looks like a series of random numbers when it’s really just following exact instructions? It uses what’s called a seed which the random number generator code expects you to provide. If you give it a seed that’s unique, then you’ll get good results. This doesn’t mean that any particular seed value is bad or that there are some seed values you should avoid. They’re all good. What you don’t want to do is provide the same seed. Here’s why.
Let’s say that you roll a six sided dice and get one. So you think that’s a good random number and use it for your seed. And let’s say that the first five random numbers generated are 9, 2, 5, 1, and 0. At some later point, you need some more random numbers so you roll a dice again and this time get six. You create a new random number generator and get five different value. Everything’s good so far. Then you need some more random numbers and end up using the value one for the seed. Your random numbers are again 9, 2, 5, 1, and 0. This is when you realize that what looked like a perfectly good sequence of random numbers will be duplicated if you use the same seed. It’s the seed that determines the order that the numbers will be returned. Give two random number generators that are using the same code the same seed, and they’ll return to you the same sequence. This is why random number generators are sometimes called pseudo-random number generators. The sequence might look random, but it’s actually very predictable if the seed is known.
This means that you need a good source for your seed that’s not likely to be repeated. A common seed is to your system clock ticks. This is normally how many milliseconds have passed since a certain time in the past. This could be a fixed date and time or maybe could be the amount of time since the computer was turned on. Now, milliseconds might seem like a very small period of time but modern computers can do a lot of work in just a single millisecond. If your program needs multiple random number generators, then be careful that you don’t create them so close to one another that they end up using the same seed.
You might have access to a truly random device that can reliably generate random values. If so, it’s possible that you only need to use this device to generate the initial seeds and then rely on the normal random number generator to take it from there. If a computer can’t generate random numbers in the first place, then how can it generate truly random seeds? It could have outside help. Something not under direct control of the instructions it’s running. This could be a temperature gauge that measures tiny fluctuations in temperature due to natural changes in air flow. It needs to be very sensitive or you end up with the problem earlier of only having six possible seed values from a six-sided dice. If you have too few seed values to choose from, then you’ll be more likely to repeat values.
So far, I’ve explained how to avoid duplicating random number sequences. But have you considered that maybe there are times when you want duplicate value sequences? I’ll explain this right after this message from our sponsor.
( Message from Sponsor )
Now here’s why you might actually want duplicate sequences.
Let’s say that you’re building a game with a huge world map. There are trees, roads, rivers, towns, etc. placed all over the map. And things like the rivers tend to turn and flow in different directions. To make the world look real, these things must look natural and that means they should avoid any specific patterns such as straight lines. You could draw all this out on paper first and then add specific coordinate points but what do you do when the game zooms in on a specific section of a road. Do you really have the ability to place each individual bush and swirl in the tree bark? Maybe you’ll just make these things random, right? So you compromise and place big things like the cities, mountains, and general road directions by hand and let random numbers give the world the smaller differences. This is fine until a player notices that every time they pass by a shop, the bush out front is in a slightly different location and sometimes it’s not a bush at all but a bucket. You can achieve your goals of adding randomness and consistency by making sure to use the same seed each time. This give the appearance of random placement with the consistency of manual placement. It allows you to write code that can take care of the details so they look natural and then be able to duplicate that result each time.