Skip to content

Random Function

Copy-paste from Lexicon
Controversial Bug Report

The following statement is now thought to be incorrect:

The random number sequence is always the same for single player, but is usually different for multiplayer (assuming there is more than a single player playing in multiplayer mode).

The random number seed is reset when you enter a new area. This is true for single and multiplayer.
This seed is always the same for each area. The sequence for each area will be identical every time.
This seed is some combination of bits taken from basic area information. If you create "identical" areas they will have the same seed, and therefore the same sequence. Obviously this is also true of copied areas.
Bits are definitely pulled from the area height and width (in tiles) and the indoor/outdoor and natural/artifical flags. Changing any of these can change the sequence.
Bits are not pulled from the areas tag, name, or resref. Changing these will not change the sequence.
Bits might be pulled from the tileset field (not sure).
There is a delay between the resetting of the seed and the calling of the OnAreaEnter script. During this period other scripts (heartbeats, perceptions, etc.) and maybe some hard-coded stuff can call the random number function, "consuming" the start of the sequence.
If the module has nothing in it but the player character the sequence will therefore be identical everytime.
If there is other stuff in the module the sequence will start at some point further down the list (as the first numbers have already been used). Since there is some variation in area load time etc.. this will be a random offset into the sequence. This is why it often looks like you have several sequences turning up, but really they are just different parts of the same sequence.
The random seed works exactly the same in single player and multiplayer - at least when the multiplayer game only has one PC.

Confirmation that function is truly random

See http://highergroundpoa.proboards.com/thread/11063/random?page=2

Acaos "the reseed is based on the server timestamp. Nothing else".


There was a bug in NWN1 that reseeded the RNG with static data when an area was loaded... this would cause the same sequence of numbers to show up everytime you played the same area.
Any solution for this problem?

tnx, Ali

Comments

  • SherincallSherincall Member Posts: 387
    This was fixed in one of the NWN patches. Random _is_ seeded with static area data when loaded, so that the "random" grass placement is always the same (and same for all players), but is then re-seeded with a monotonic high precision clock, which will be different every time.
  • sippelmcsippelmc Member Posts: 45
    edited June 2018
    I still have this problem where I randomize layout of creatures on module load, and it is always the same layout every diff module load, and the bug is reported here. https://support.baldursgate.com/issues/36782

    Anyone have any idea on what the workaround in reseeding the submitter used? ("In order to get around this bug, a script portion was added to the OnModuleLoad script, at the start, to use a number saved to a campaign database as a random number seed (short explanation - the long version would be too complex to explain here." )

    I don't have anything else other than he puts it in OnAreaEnter.
  • sippelmcsippelmc Member Posts: 45
    edited June 2018
    OK I slept on it and for those who also have this issue for a PW server, here was the fix. It calls the Random function before anything else, and doing it a random number of times between 1-1000, introducing that many different possible sequences on load.

    Coincidentally, it closes out that user's bug report as well since it appears OnModLoad is again now firing before OnAreaEnter properly.

    In ModLoad I put:

    // Reset the random seed for the server reboot
    int iSeedTimesToRandom;
    int iSeed;
    int iCount = 0;
    iSeedTimesToRandom = GetCampaignInt(MOD_RNG_SEED, MOD_RNG_SEED);
    while (iCount <= iSeedTimesToRandom)
    {
    iSeed = Random(1);
    iCount = iCount + 1 ;
    }

    On HeartBeat:

    //Reset the module's random seed generator continuously; there are now 1000 permutations for the initial pseudo random cycle
    SetCampaignInt(MOD_RNG_SEED, MOD_RNG_SEED, Random(1000)+1);
  • meaglynmeaglyn Member Posts: 149
    I think work around you are talking about is something like this on area enter:

    void ReSeedRandom() {
    // Random seed is set each time a PC enters an area, but it's seeded
    // the same on each area. This advanced the sequence to a hopefully
    // different place.
    int i;
    for (i = 0 ; i < GetTimeMillisecond() ; i ++ ) {
    Random(100);
    }
    }
  • sippelmcsippelmc Member Posts: 45
    Thank you that worked great (and in module load).
Sign In or Register to comment.