How was randomness achieved in older video games?

In some older video games, the behavior of enemies or the results of given actions appear to be randomly decided and unpredictable.

How was this achieved on a technical level? These old video game consoles (1980s and before) didn’t have internal system clocks, which I believe is how ‘random’ numbers and such are generated with code these days.

How is it that a video game from the 1980s, on a system with no internal clock and given the same inputs, could achieve a random result?

The “easy” way was just to capture the milliseconds from the clock.

Then and now, random numbers are generated with pseudorandom number generators – i.e. recursive numeric functions that produce output values that look random even through they’re deterministic.

Often the pseudorandom number generator is “seeded” with a value from the system clock to prevent it running through the same sequence every time you start the game. But you can use any sort of noise as the seed, including player inputs.

Here’s an article from 1989 about Atari RNGs

Apparently:

This is actually the way Linux’s /dev/random works. Interestingly, this is a true RNG and not a pseudo-random generator like clock-based systems (which use the current system time as a seed).

The downside to this method is that if you’re requesting too many bits of randomness, there may not be enough information to provide a number, however, this is unlikely to be an issue given the relatively low complexity of Atari games. If it is an issue, you can always use a single random number from the system noise to seed a pseudo-random generator.

Well, until the speedrunners get a hold of your game. :wink:

And very often behavior of the game that appeared random was not random at all. Lots of old games were “beat” when people discovered that if they always took exactly the same actions, the enemies would always do exactly the same thing, and that the only randomness was that introduced by the player.

Oh, and keep in mind that “clock” doesn’t necessarily mean “clock” as you know it. RNG seeds aren’t looking for a “clock” that says right now it’s December 21, 2015 at 12:52 PST, they’re generally looking at the system clock which measures things like how many CPU cycles have passed, how long the system has been booted up, and stuff like that.

A good source of randomness is the measure the time from boot to first user input.
This will only very rarely be the same from boot to boot.

A lot of 8 bit systems had a clock tick that was tied to the video vertical refresh rate (which varied slightly between PAL and NTSC systems). The Commodore 64 called theirs a “jiffy clock” and you could measure time by counting “jiffies”.

Since these clocks tended to be down in the millisecond range, you could generate a fairly random 8 bit number fairly easily just by measuring how long it took someone to press the start button for the game. That gives you a fairly random number to use as a seed value, which you can then shove into a pseudorandom sequence generator to create your “random” numbers.

The Commodore 64 also had a hardware random number generator, similar to the previously mentioned Atari. The Commodore had a sound chip that they called SID (for Sound Interface Device) that was a fairly primitive sound synthesizer. It had four modes of operation: sine wave, square wave, sawtooth wave, and noise. SID had a built-in A/D converter that could convert the noise signal into a digital random number.

The Commodore 64 also had a pseudorandom sequence generator built into its ROM. You started with your seed value, and every call to that particular ROM subroutine would return the next number in the pseudorandom sequence. You could use the jiffy count method to generate your seed, or you could use the SID hardware method to generate your seed, or you could put in a known integer value as your seed so that you got the same sequence every time (useful for debugging).

Most 8 bit machines did not have a hardware random number generator built into them and instead relied on things like clock tick counting to generate their random seeds.

How did they “measure random noise in an electronic circuit” in the Atari? Was this dedicated hardware?

Thank you for this very interesting information!

I’ve written video games as a hobby (since the early 90s) and I’ve used both system clock and player input as RNG seeds.

Both methods work pretty well, well enough that even though I wrote the code I couldn’t “trick” the system. I imagine it would be even more difficult to extrapolate the seed method through observation and then manipulate it.

I’m not sure I follow. Do you mean that there wouldn’t have been sufficient time to generate the next random number?

Atari had a chip called POKEY, which stood for Potentiometer/Keyboard interface. It also had sound capabilities. So yes, it was a dedicated hardware chip.

I didn’t know how POKEY actually did its thing as far as the random number generator was concerned, and I was curious, so I went poking (heh, sorry) around on the net. I was expecting maybe a reverse biased zener diode with the breakdown noise amplified and fed into an A/D converter, or something like that. I was rather surprised to find out that internally, POKEY used a linear feedback shift register to generate a pseudorandom sequence. So someone was lying. It wasn’t actually measuring random noise. It takes a long time for POKEY’s sequence to repeat, but it’s just a repeating pseudorandom sequence, not a true hardware random number.

The pseudorandom sequence generated by POKEY isn’t sync’d to the CPU chip, so you will get some randomness out of it.

No, what he means is that the digitizer (or synthesizer) isn’t very accurate.
So, if you have an analog signal that varies continuously over a range of zero - 1 volts, but you only have an 8-bit Analog to Digital converter, you can never end up with better than 256 values (although, if you take extra time you can oversample and get additional precision).

Since the randomness is just a measurement of noise, it’s plausible that not enough samples have occurred between readings.

This is a known problem with /dev/random in Unix, which is why you usually use /dev/urandom in time-sensitive or real-time applications (/dev/urandom reads from dev random, and, if there’s no info, will seed a PRNG with the last reading from /dev/random and return that).

It’s like if I was getting my randomness from you flipping coins. You can only flip so quickly, so if I need a bunch of numbers, it’s possible you haven’t flipped enough coins yet and I need to wait for you.

I don’t know if this is a problem with Atari’s implementation, which may sample on-demand, but in /dev/random, it basically just measures noise from a ton of sources and stores them in a file which can be depleted if sampled from too frequently.

Gotcha! (both) Thanks.

My dad would bring home from work every weekend the very first Compaq suitcase-sized “portable” computer (twin 5.25" drives, baby! and either green or amber 10" monochrome display). And some of the games would ask for a seed# on startup. I don’t remember the names of the games at all, however.

I just came to the same realization after a bit of digging. POKEY has a hardware implementation of a pseudorandom bit-shifting algorithm.

Where does POKEY get its seed?

Article on the matter here: