Page 1 of 1

random number seeding issue

Posted: Tue Nov 24, 2015 9:20 am
by matteus
Everytime I run a Rom that generates 4 random numbers they are always the same. How do I get the function to seed properly?

Re: random number seeding issue

Posted: Tue Nov 24, 2015 9:33 am
by Stef
Did you try the random() method ? On emulator the seeder can contains the same value but on real hardware you should obtain real random sequence.

Re: random number seeding issue

Posted: Tue Nov 24, 2015 5:36 pm
by matteus
Stef wrote:Did you try the random() method ? On emulator the seeder can contains the same value but on real hardware you should obtain real random sequence.
Yes I'm using the random() method! So on emulators the seeder contains the same values? :D lol

Re: random number seeding issue

Posted: Tue Nov 24, 2015 5:44 pm
by Stef
Yeah because it relies on HV counter value at cold start, which is often the same value on emulator but not on real hardware ;-)

Re: random number seeding issue

Posted: Tue Nov 24, 2015 5:51 pm
by tryphon
It could be useful to determine whether you're running from real hw or an emu ?

Re: random number seeding issue

Posted: Tue Nov 24, 2015 6:22 pm
by matteus
always on emulator at the moment! :)

Re: random number seeding issue

Posted: Tue Sep 13, 2016 8:36 pm
by matteus
Is there a way around this? :D

Re: random number seeding issue

Posted: Wed Sep 14, 2016 7:52 am
by cero
This is common to all consoles and embedded environments with no RNG. You have to get entropy from the only place available, the user.

For most titles, this means calling random() once per frame on the title screen. The time before the user presses a key varies, so will your randomness.

Re: random number seeding issue

Posted: Wed Sep 14, 2016 1:43 pm
by Stef
I've changed the random() method in SGDK to generate the same random numbers sequence for a given seeder. If you want different value at each start then you should initialize the random seed (using setRandomSeed(..) method) with a random value at start (using HV counter on real hardware or first user controller event time).

Re: random number seeding issue

Posted: Fri Sep 16, 2016 11:06 am
by matteus
So does that basically mean my software will only work properly on proper hardware? :/

Re: random number seeding issue

Posted: Fri Sep 16, 2016 11:36 am
by Stef
I edited my previous reply, but generally yeah emulators won't produce reliable random() as o real hardware if you use the HV counter value to initialize the random seeder.

Re: random number seeding issue

Posted: Sat Sep 17, 2016 12:10 am
by Miquel
You may introduce button presses and frame counter to the formula, that should work on emus. Also using the full register, H and V counter, should make a difference.

Re: random number seeding issue

Posted: Mon Sep 19, 2016 5:14 pm
by matteus
okay I almost understand :) So do I call setRandomSeed after VDP_waitVSync? and if so what do I need to put into the Random Seed? What functions can I call to get the event time?

Re: random number seeding issue

Posted: Sun Jan 14, 2018 11:00 am
by matteus
I wanted to check my method for doing this was correct!

Code: Select all

u16 randomNumberGenerator(u16 startInt, u16 finishInt) {
    if (finishInt != 0)
    {
        u16 x = ( random() % (finishInt - startInt) ) + startInt;
        return x;
    }
    else
    {
        return 0;
    }
}

Re: random number seeding issue

Posted: Sun Jan 14, 2018 12:54 pm
by Miquel
Bringing in new knowledge:
A brilliant idea that konami games did is to use idle time to run the random number generator. When you are waiting for the vblank exception on the main loop, instead of just waiting, run the generator.
Since the idle time changes depending on everything else you got the better change for random numbers.

While your code is fine, if you can is better to use advantages of binary/hexadecimal numbers.

Code: Select all

u16 rNumber = random();

switch(rNumber & 3)
{
	case 0: move up; break;
	case 1: move down; break;
	case 2: move left; break;
	case 3: move right; break;
}
if(rNumber & 4)
{
	HitWithSword();
}
if(rNumber & 8)
{
	Jump();
}
if(rNumber & 16)
{
	Retreat();
}