Larian Banner
Previous Thread
Next Thread
Print Thread
Random() is not very random #641292
27/01/18 01:28 AM
27/01/18 01:28 AM
Joined: Dec 2013
Posts: 872
Windemere Offline OP

old hand
Windemere  Offline OP

old hand

Joined: Dec 2013
Posts: 872
I'm wondering if Larian or anyone else can answer how the call to Random() in Osiris gets seeded. Whenever I invoke this call in the editor, I seem to get the same result back test after test after test until suddenly it will finally change, and then stick again for a while. I just finished testing some story script where I use a modulo of 14 and out of about a dozen tests I got 0 for the result back the first 6 or 7 times and then it changed to 1 for the next 6 or 7. Is there any way to make this call generate more random results when testing in the editor? Even re-opening the project every time doesn't seem to help much.

Thanks.


DOS2 Mods: Happily Emmie After and The Noisy Crypt

Steam Workshop
Nexus Mods
Re: Random() is not very random [Re: Windemere] #641293
27/01/18 01:34 AM
27/01/18 01:34 AM
Joined: Sep 2017
Posts: 497
Norway
The Composer Offline
addict
The Composer  Offline
addict

Joined: Sep 2017
Posts: 497
Norway
I don't know what in particular you're set out to do, but something that works well for me is the following. It decides one out of 14 different outcomes and it's quite random and fluid for me.

INIT

DB_DC_FTJIRandom(1);


KB

...
AND
DB_DC_FTJIRandom(_Chance)
AND
Random(14, _Ran)
AND
_Ran >= _Chance
...

Re: Random() is not very random [Re: Windemere] #641295
27/01/18 01:45 AM
27/01/18 01:45 AM
Joined: Dec 2013
Posts: 872
Windemere Offline OP

old hand
Windemere  Offline OP

old hand

Joined: Dec 2013
Posts: 872
I'm doing something similar but like I said, the output value from Random repeats itself from one playtest to another multiple times in a row.


DOS2 Mods: Happily Emmie After and The Noisy Crypt

Steam Workshop
Nexus Mods
Re: Random() is not very random [Re: Windemere] #641298
27/01/18 01:59 AM
27/01/18 01:59 AM
Joined: Sep 2017
Posts: 497
Norway
The Composer Offline
addict
The Composer  Offline
addict

Joined: Sep 2017
Posts: 497
Norway
Odd... Though I do remember having some sort of issue too. It's quite a while ago so the details are fuzzy at best, but I had some success when changing the output to strings. Absolutely no idea why, but it solved all my headaches at the time. Mysteries of the engine, right?



IF
TimerFinished("DCDouseBraziers")
AND
DB_DC_FTJIRandom(_Chance)
AND
Random(14, _Ran)
AND
_Ran >= _Chance
AND
IntegertoString(_Ran, _RanDisp)
THEN
NOT DB_DC_FTJIPunishment(_RanDisp);
DB_DC_FTJIPunishment(_RanDisp);
Proc_FTJI_Secret_Punishment();


(The fifth variant here as an example, since it's short)

PROC
Proc_FTJI_Secret_Punishment()
AND
DB_IsPlayer(_Player)
AND
DB_DC_FTJIPunishment("5")
AND
DB_DC_FTJI_ShroomsPuzzle(_FTJIShroom)
THEN
PlayEffect(_FTJIShroom, "RS3_FX_GP_Impacts_Arrow_PoisonCloud_01");
CreatePuddle(_FTJIShroom, "SurfacePoisonCloud", 80, 130, 60, 60, 0.5);
NOT DB_DC_FTJIPunishment("5");



Re: Random() is not very random [Re: Windemere] #641299
27/01/18 02:16 AM
27/01/18 02:16 AM
Joined: Dec 2013
Posts: 872
Windemere Offline OP

old hand
Windemere  Offline OP

old hand

Joined: Dec 2013
Posts: 872
Here is the code in question, which just applies a random preset on the dummy character when testing in editor mode. I'll wrap some lines of interest in double asterisks to make them easier to find.

Code:
INIT
DB_EditorMode_Presets(0, "Battlemage");
DB_EditorMode_Presets(1, "Cleric");
DB_EditorMode_Presets(2, "Conjurer");
DB_EditorMode_Presets(3, "Enchanter");
DB_EditorMode_Presets(4, "Fighter");
DB_EditorMode_Presets(5, "Inquisitor");
DB_EditorMode_Presets(6, "Knight");
DB_EditorMode_Presets(7, "Metamorph");
DB_EditorMode_Presets(8, "Ranger");
DB_EditorMode_Presets(9, "Rogue");
DB_EditorMode_Presets(10, "Shadowblade");
DB_EditorMode_Presets(11, "Wayfarer");
DB_EditorMode_Presets(12, "Witch");
DB_EditorMode_Presets(13, "Wizard");

IF
GameModeStarted("Campaign",1)
AND
DB_GLO_FirstLevelAfterCharacterCreation(_Level)
AND
DB_CharacterCreationTransitionInfo(_Level,_Trigger)
AND
**Random(14, (INTEGER)_Random)**
THEN
SetOnStage(S_GLO_CharacterCreationDummy_001_da072fe7-fdd5-42ae-9139-8bd4b9fca406,1);
CharacterMakePlayer(S_GLO_CharacterCreationDummy_001_da072fe7-fdd5-42ae-9139-8bd4b9fca406);
MakePlayerActive(S_GLO_CharacterCreationDummy_001_da072fe7-fdd5-42ae-9139-8bd4b9fca406);
DB_IsPlayer(S_GLO_CharacterCreationDummy_001_da072fe7-fdd5-42ae-9139-8bd4b9fca406);
SetFaction(S_GLO_CharacterCreationDummy_001_da072fe7-fdd5-42ae-9139-8bd4b9fca406, "Hero");
**ProcApplyEditorPreset(S_GLO_CharacterCreationDummy_001_da072fe7-fdd5-42ae-9139-8bd4b9fca406, _Random);**
ProcMovePartyToStart(S_GLO_CharacterCreationDummy_001_da072fe7-fdd5-42ae-9139-8bd4b9fca406,_Trigger);

PROC
ProcApplyEditorPreset((CHARACTERGUID)_Player, (INTEGER)_Index)
AND
DB_EditorMode_Presets(_Index, _Preset)
THEN
CharacterApplyPreset(_Player, _Preset);


And here are the test results. Between each run I completely re-open the project and starting level from scratch and have some additional actions noted on some of the other runs.

1st run
exec [DIV query] Random( 14, [out] (INTEGER)(undef value) )
Query returns: Random( 14, 4 )

2nd run same as before
exec [DIV query] Random( 14, [out] (INTEGER)(undef value) )
Query returns: Random( 14, 4 )

3rd run same as before
exec [DIV query] Random( 14, [out] (INTEGER)(undef value) )
Query returns: Random( 14, 4 )

4th run same as before
exec [DIV query] Random( 14, [out] (INTEGER)(undef value) )
Query returns: Random( 14, 4 )

**EXIT EDITOR and RESTART**

5th run same as before
exec [DIV query] Random( 14, [out] (INTEGER)(undef value) )
Query returns: Random( 14, 4 )

6th run same as before
exec [DIV query] Random( 14, [out] (INTEGER)(undef value) )
Query returns: Random( 14, 4 )

** Move some code order around and re-build the story **

7th run same as before
exec [DIV query] Random( 14, [out] (INTEGER)(undef value) )
Query returns: Random( 14, 4 )

** Open a different project and test it for a while **
** Open this project back up and test (no code changes) **

8th run finally changes!
exec [DIV query] Random( 14, [out] (INTEGER)(undef value) )
Query returns: Random( 14, 5 )

** Reload Project and Start **

9th run same as before
exec [DIV query] Random( 14, [out] (INTEGER)(undef value) )
Query returns: Random( 14, 5 )

** Open a different project and test it for a while **
** Open this project back up and test (no code changes) **

10th run same as before
exec [DIV query] Random( 14, [out] (INTEGER)(undef value) )
Query returns: Random( 14, 5 )

and so on ... ouch


DOS2 Mods: Happily Emmie After and The Noisy Crypt

Steam Workshop
Nexus Mods
Re: Random() is not very random [Re: Windemere] #641378
28/01/18 08:47 PM
28/01/18 08:47 PM
Joined: Jan 2018
Posts: 23
Brazil
B
BloodyWorth Offline
stranger
BloodyWorth  Offline
stranger
B

Joined: Jan 2018
Posts: 23
Brazil
One thing you can do to increase randomness is adding random simulated layers (I'm guessing this is what it is called in english, don't know the offical name sorry) like so:

Code:
PROC
Rand_OneLayer((INTEGER)_maximum,(INTEGER)_rand)
AND
Random(_maximum,_rand1)
AND
DB_RandomShit1(_rand1,1)
AND
Random(_maximum,_rand2)
AND
DB_RandomShit1(_rand2,2)
AND
Random(_maximum,_rand3)
AND
DB_RandomShit1(_rand3,3)
AND
Random(_maximum,_rand4)
AND
DB_RandomShit1(_rand4,4)
AND
Random(4,_sel)
THEN
DB_RandomShit1(_rand,_sel);


This is just an exemple, you can make it "more random" by either increasing its "range" ex.: go all the way to DB_RandomShit(_rand100,100), or increasing its depth, where instead of calling the random function to get the random number, you call a proc just like this one, this way you'd be adding a "layer" to it, something like:

Code:
PROC
Rand_TwoLayer((INTEGER)_maximum,_rand)
AND
Rand_OneLayer(_maximum,_rand1)
AND
DB_RandomShit2(_rand1,1)
AND
Rand_OneLayer(_maximum,_rand2)
AND
DB_RandomShit2(_rand2,2)
AND
Rand_OneLayer(_maximum,_rand3)
AND
DB_RandomShit2(_rand3,3)
AND
Rand_OneLayer(_maximum,_rand4)
AND
DB_RandomShit2(_rand4,4)
AND
Random(4,_sel)
THEN
DB_RandomShit2(_rand,_sel);


There are some other ways, but i'm not sure how real and integer conversions work on osiris, i do know that generating random numbers between 0 - 1 will have a better random value, i remember my teacher explained this in linear algebrae but i can't remember so take it with a grain of salt.

Hope it helps laugh

Re: Random() is not very random [Re: Windemere] #641381
28/01/18 10:03 PM
28/01/18 10:03 PM
Joined: Dec 2013
Posts: 872
Windemere Offline OP

old hand
Windemere  Offline OP

old hand

Joined: Dec 2013
Posts: 872
Thanks, I understand how to make workarounds but I'd like some insight into the behavior as it is now. There aren't a bunch of unholy workarounds in Origins to make Random actually behave randomly, so I'm looking to see if there is something unique about running in editor mode with cached data hanging around somewhere, or if there is something else I'm not accounting for.


DOS2 Mods: Happily Emmie After and The Noisy Crypt

Steam Workshop
Nexus Mods
Re: Random() is not very random [Re: Windemere] #641415
29/01/18 10:56 PM
29/01/18 10:56 PM
Joined: Nov 2017
Posts: 48
Ukraine
Module 003 Offline
apprentice
Module 003  Offline
apprentice

Joined: Nov 2017
Posts: 48
Ukraine
I found Random() to behave strange as well.
Used it in a class mod, to get %chance to apply custom scripted status, and was always unhappy with result.

Sometimes it just returns same values for like 20 times in a row, and only after that start working.
Had to add some "controled RNG" to prevent it from returning same values (using DB_Counters) and make some additional treshods.
Was working with flat Integer numbers 1-100.

Donno why it is so buggy, but think that is just smth we have to deal with.

Re: Random() is not very random [Re: Windemere] #641530
01/02/18 01:14 PM
01/02/18 01:14 PM
Joined: Mar 2016
Posts: 504
Belgium
T
Tinkerer Offline

addict
Tinkerer  Offline

addict
T

Joined: Mar 2016
Posts: 504
Belgium
The Osiris Random() call uses the standard C(++) library's "rand()" function. However, there are a few places in the engine where the random seed gets reset, and maybe some external libraries also do this. I'll look into changing it into something that is independent of external influences.

Re: Random() is not very random [Re: Windemere] #641539
01/02/18 03:37 PM
01/02/18 03:37 PM
Joined: Dec 2013
Posts: 872
Windemere Offline OP

old hand
Windemere  Offline OP

old hand

Joined: Dec 2013
Posts: 872
Ah ha, that would make sense. Thanks for the reply Tinkerer, much appreciated. smile


DOS2 Mods: Happily Emmie After and The Noisy Crypt

Steam Workshop
Nexus Mods

Moderated by  Dom_Larian, Larian_Koala 

Powered by UBB.threads™ PHP Forum Software 7.6.2