battagline wrote:Whenever there is any input from the gamepad I add the frame counter to the random pointer and AND it with #%01111111
It might be worth taking a close look at this sequence of indices and how it works.
No matter what index you start on, this sequence will have 128 values, and then the same sequence will repeat in reverse order before starting over. If you were looking at the output of this, you would be able to spot each reversal whenever a value is repeated twice in a row.
Here's the 3 bit equivalent for any given starting seed:
Code: Select all
00 > 0 1 3 6 2 7 5 4 4 5 7 2 6 3 1 0...
01 > 1 2 4 7 3 0 6 5 5 6 0 3 7 4 2 1...
02 > 2 3 5 0 4 1 7 6 6 7 1 4 0 5 3 2...
03 > 3 4 6 1 5 2 0 7 7 0 2 5 1 6 4 3...
04 > 4 5 7 2 6 3 1 0 0 1 3 6 2 7 5 4...
05 > 5 6 0 3 7 4 2 1 1 2 4 7 3 0 6 5...
06 > 6 7 1 4 0 5 3 2 2 3 5 0 4 1 7 6...
07 > 7 0 2 5 1 6 4 3 3 4 6 1 5 2 0 7...
Like I said, this pattern may not matter depending on the application, but generally the goal when designing a PRNG is to eliminate discernible patterns of output. All patterns like this have the potential to manifest as unwanted repetitive / exploitable behaviour when applied to a process like an interactive game.
There have been a lot of poor quality PRNGs in general use, and of course especially in games, and random scraps of code shared on the internet you'll find plenty.
A very popular but heavily flawed version of rand() made it into very many C compiler libraries, for example, so even pro solutions may have drawbacks. It's really common to see people write fast PRNG routines and end up with flawed distribution that seems fine for whatever the limited application they put it to, but might cause problems if you drop it into a different game.
For more generic purposes,
Long period LFSRs are good, statistically, as long as you tick the LFSR for each bit you need (not just each byte). After some review and tuning up,
cc65's rand seems quite good as well. "Cryptographically secure" PRNGs are of course very good, but overkill for games.