-
Notifications
You must be signed in to change notification settings - Fork 109
Random numbers
This short guide explains you how to obtain random numbers useful for random game logic / AI.
As a starting point, C's rand()
generates a number between 0 and RAND_MAX
which on N64 is 2^31-1 (0x7fffffff). The sequence generated by rand()
is deterministic, that is, it is always the same. To randomize the whole sequence, you can use srand()
. This is how you would do:
// Put this code in `main()`, during the initialization phase.
// On preview branch, use getentropy() to generate a seed.
#include <unistd.h>
uint32_t seed;
getentropy(&seed, 4);
srand(seed);
// On stable branch, use get_ticks() as seed
srand(get_ticks());
After this call, rand()
will return a new random number sequence, that is different after each boot.
NOTE: online resources will advise to use srand(time(NULL))
. Do not do that on N64. On N64, time(NULL)
is not implemented because N64 by default does not have a RTC so it is not possible to return the current time.
The above will work as expected on real hardware, but not on emulators. The reasons are multiple and in general we could attribute this to imperfect emulation, but emulator authors will in general value consistency and reproducibility.
What we can do on emulators is instead trying to extract some randomness from user interaction. That is, we need to rely on the fact that the user will not press the start button (for instance) at exactly the same time; this difference in user interaction can be easily exploited by simply calling rand()
every frame, with the expectation that when the game will truly need a random number (eg: to decide which enemy to spawn), a non deterministic number of frames will have been drawn.
// Put this code in `main()`, during the initialization phase, in addition to the srand call
// Call rand() at each vertical blank, ignore the result.
register_VI_handler((void(*)(void))rand);