Don't forget lookup tables. Those were used long before "true" pseudo-random number generators, and usually worked well enough. The simplest is just copying, say, 256 numbers from your random number codebook (a physical book, yes) to your program, and indexing into this memory with a successively incremented index.
Now, this is obviously nothing even close to randomness required in cryptography, or anything where correctness depends on good randomness (e.g. genetic algorithms, Monte Carlo approximation, ...). But it's good enough for games. As a reasonably recent example, the original Doom used a "random" number generator exactly like thisthe original Doom used a "random" number generator exactly like this - 256 pre-defined numbers taken in a loop. This had some visible side-effects (the BFG weapon could "theoretically" inflict much more (or less) damage than it could in practice, thanks to the random generator not being random enough). This was a very common approach in games, since it's extremely cheap (just a single shared "pseudoRandomIndex++" and a memory read from something that's always in CPU cache), and true randomness is seldom required - the main sources of entropy in a typical game are from mostly random ordering of events. BFG in Doom became so heavily biased mainly because it took a lot of those pseudo-random numbers in a sequence.