Overview
There are many ways to generate a random number based on how many bits you want and how random it has to be.
It is important to remember three things:
- Computers are not random; as such they can only generate pseudo-random numbers (numbers which seem random but eventually repeat or show a pattern).
- User input is pretty random, and is a very useful thing for making numbers more random.
- If you give a random number generator the same seed, you will get the same output. So use user input to seed the generator.
The r
register can be used too, since its value will be fairly random when observed infrequently, but many emulators don't emulate it and (if emulated correctly, or on hardware) it only provides 7 bits of data.
An easy and effective way to seed a generator is to simply increment (or otherwise modify) its seed once per frame, and/or increment/modify it based on user input. The important part is to then pass these seed data into an algorithm that produces pseudo-randomly-distributed results, which have little correlation to the input data.
Phantasy Star's random number generator
GetRandomNumber:
; Uses a 16-bit RAM variable called RandomNumberGeneratorWord
; Returns an 8-bit pseudo-random number in a
push hl
ld hl,(RandomNumberGeneratorWord)
ld a,h ; get high byte
rrca ; rotate right by 2
rrca
xor h ; xor with original
rrca ; rotate right by 1
xor l ; xor with low byte
rrca ; rotate right by 4
rrca
rrca
rrca
xor l ; xor again
rra ; rotate right by 1 through carry
adc hl,hl ; add RandomNumberGeneratorWord to itself
jr nz,+
ld hl,$733c ; if last xor resulted in zero then re-seed random number generator
+: ld a,r ; r = refresh register = semi-random number
xor l ; xor with l which is fairly random
ld (RandomNumberGeneratorWord),hl
pop hl
ret ; return random number in a