Larian Banner: Baldur's Gate Patch 9
Previous Thread
Next Thread
Print Thread
#641292 27/01/18 01:28 AM
Joined: Dec 2013
old hand
OP Offline
old hand
Joined: Dec 2013
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
Joined: Sep 2017
veteran
Offline
veteran
Joined: Sep 2017
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
...

Joined: Dec 2013
old hand
OP Offline
old hand
Joined: Dec 2013
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
Joined: Sep 2017
veteran
Offline
veteran
Joined: Sep 2017
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");



Joined: Dec 2013
old hand
OP Offline
old hand
Joined: Dec 2013
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
Joined: Jan 2018
Location: Brazil
B
stranger
Offline
stranger
B
Joined: Jan 2018
Location: 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

Joined: Dec 2013
old hand
OP Offline
old hand
Joined: Dec 2013
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
Joined: Nov 2017
Location: Ukraine
apprentice
Offline
apprentice
Joined: Nov 2017
Location: 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.

Joined: Mar 2016
Location: Belgium
T
addict
Offline
addict
T
Joined: Mar 2016
Location: 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.

Joined: Dec 2013
old hand
OP Offline
old hand
Joined: Dec 2013
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

Link Copied to Clipboard
Powered by UBB.threads™ PHP Forum Software 7.7.5