The Worst Attempt At Combatting Pseudo-RNG Patterns During Generation?

Discuss modding questions and implementation details.
Post Reply
User avatar
Magicono43
Posts: 1139
Joined: Tue Nov 06, 2018 7:06 am

The Worst Attempt At Combatting Pseudo-RNG Patterns During Generation?

Post by Magicono43 »

So I'm trying to reduce patterns that occur when my new modded chest objects are being generated during "OnTransitionInterior".

This is my best attempt at trying to do this, by populating the Unity random seed value with an amalgamation of semi-unique values pulled from parts of the scene and splice them together with the normally "DateTime.Now.Ticks" default seed value Unity supposedly uses.

The reason for this being (atleast from what I can tell), that since this random seed is based on the ticks I believe the system has currently tracked. That would have me believe that since these generation calculations are happening within a few system ticks most likely, this seed value is not changing much during this time, causing noticeable patterns in the end.

But I'd like to know if I'm just being dense here thinking this attempt of mine will be any better potentially, here is what it looks like in code so far:

Code: Select all

string unitySeed = DateTime.Now.Ticks.ToString();
                int xPos = (int)oldLootPileTransform.localPosition.x;
                int yPos = (int)oldLootPileTransform.localPosition.y;
                int zPos = (int)oldLootPileTransform.localPosition.z;
                string coordText = xPos.ToString() + yPos.ToString() + zPos.ToString();
                string loadIDText = llcObj.LoadID.ToString();

                string combinedText = unitySeed.Substring(0, 3) + coordText + loadIDText + unitySeed.Substring(4);
                string truncText = (combinedText.Length > 10) ? combinedText.Substring(10) : combinedText; // Might get index out of range, but will see.
                int seed = int.Parse(truncText);
                UnityEngine.Random.InitState(seed); // This is to attempt to combat patterns in generation due to this all happening in a small period of time with a similar system-time seed by default.
Here is a screenshot as well:
Capture.PNG
Capture.PNG (89.89 KiB) Viewed 1021 times
The idea is to populated this seed value for when the chest and lock materials are being "rolled", then when that is said and done for each individual chest, reset the seed value to the Unity default at the end, as to try and not influence other systems by using the seed I created in this case.

Any advice/critique on this method and random generation patterns in general would be appreciated, thanks.

User avatar
pango
Posts: 3347
Joined: Wed Jul 18, 2018 6:14 pm
Location: France
Contact:

Re: The Worst Attempt At Combatting Pseudo-RNG Patterns During Generation?

Post by pango »

DateTime.Now.Ticks() return value unit may be in 10 millionths of a second units, it doesn't mean it's refreshed that often; It's most likely only updated even millisecond or so.
In case of doubt, I'd say instanciate a System.Random object, and use it to get random values, that's it's job.
You can keep that object around to avoid instantiating it each time; But in any case performance will probably be fine.
Mastodon: @pango@fosstodon.org
When a measure becomes a target, it ceases to be a good measure.
-- Charles Goodhart

User avatar
DunnyOfPenwick
Posts: 275
Joined: Wed Apr 14, 2021 1:58 am
Location: Southeast US

Re: The Worst Attempt At Combatting Pseudo-RNG Patterns During Generation?

Post by DunnyOfPenwick »

I assume you're trying to keep chest values the same when saving/reloading in the same dungeon?

I think the simplest way is to create a seed value using the name of the dungeon:

Code: Select all

int seed = GameManager.Instance.PlayerGPS.CurrentLocation.Name.GetHashCode();
UnityEngine.Random.InitState(seed);
You should only have to seed the number generator once at the start of your code.

If you want to avoid interfering with Unity's random number generator, you will have to create your own number generator like Pango said. There's an example of that in the Tempered Interiors Utility class, though there might be better examples around as I just created that from scratch.

edit: I suspect the above code would stop working once players started opening chests followed by save/reload. Instead of using a random number generator, create a repeatable hash value using the loot coordinates. I use that method in Tempered Interiors as well to maintain consistency.

User avatar
Magicono43
Posts: 1139
Joined: Tue Nov 06, 2018 7:06 am

Re: The Worst Attempt At Combatting Pseudo-RNG Patterns During Generation?

Post by Magicono43 »

I think I worded my question poorly, or I just did not describe it properly.

What I'm trying to do is make the generation part as "random" as possible and reduce the occurrence of obvious patterns during the generation process. In terms of after the chests have already been generated, I plan to handle that part through save-data in the end.

But the reason I see this as an issue is that in my other mod "Jewelry Additions" I had some issue (still does) where when generation the jewelry items for gem-store shelves, there would frequently be "patterns" of certain jewelry types with the same gem-stones being generated right next to each other 2-3 times on the same shelf. I figure this is not much of an issue with the vanilla generation since it only rolls for each item that can be generated on a shelf once per type, and it's not possible to say have two pairs of gloves on one shelf, etc.

So what I want is when you enter a dungeon or building for the loot-piles that are replaced with the modded chest items to be different most of the time, especially the materials the attributes they are generated with.

When I was testing using the "default" UnityEngine.Random functions, I was already seeing patterns when looking through the chests that were created, such as in one dungeon having multiple chests that were made of wood with dwarven locks, or another time multiple that were wooden chests with wooden locks, that sort of thing. I know that sometimes that just happens with "randomness" but for me it seemed more like unintended patterns more than random chance that each time there would be multiple chests generating with the same material distributions, rather than being a more even distribution.

User avatar
DunnyOfPenwick
Posts: 275
Joined: Wed Apr 14, 2021 1:58 am
Location: Southeast US

Re: The Worst Attempt At Combatting Pseudo-RNG Patterns During Generation?

Post by DunnyOfPenwick »

So the problem is that the random number generator doesn't seem random enough?
I assume unity is using the windows (or whatever OS) random number generator, and that should be fine.
Occasionally you will probably get streaks of similar numbers, but that's normal.

If the player sees a bunch of similar chests, that just means they had a sale at the Chests-R-Us store...

User avatar
Magicono43
Posts: 1139
Joined: Tue Nov 06, 2018 7:06 am

Re: The Worst Attempt At Combatting Pseudo-RNG Patterns During Generation?

Post by Magicono43 »

DunnyOfPenwick wrote: Sun Oct 23, 2022 5:53 pm So the problem is that the random number generator doesn't seem random enough?
I assume unity is using the windows (or whatever OS) random number generator, and that should be fine.
Occasionally you will probably get streaks of similar numbers, but that's normal.

If the player sees a bunch of similar chests, that just means they had a sale at the Chests-R-Us store...
Yeah I know it's fairly normal to have these sort of Pseudo-random systems not feel random enough at points. I guess it works well with Daggerfall's loot system to some extent because of how it restricts certain things and thus sort of prevents the patterns from being as obvious.

Perhaps I'll just have to deal with that fact... But I'll have to see if my sort of dumb "solution" helps in anyway or not, have not tested it yet but figured I'd ask if anyone had any clearly better ways of trying to deal with this sort of thing.

User avatar
BadLuckBurt
Posts: 948
Joined: Sun Nov 05, 2017 8:30 pm

Re: The Worst Attempt At Combatting Pseudo-RNG Patterns During Generation?

Post by BadLuckBurt »

Magicono43 wrote: Sun Oct 23, 2022 6:08 pm Yeah I know it's fairly normal to have these sort of Pseudo-random systems not feel random enough at points. I guess it works well with Daggerfall's loot system to some extent because of how it restricts certain things and thus sort of prevents the patterns from being as obvious.

Perhaps I'll just have to deal with that fact... But I'll have to see if my sort of dumb "solution" helps in anyway or not, have not tested it yet but figured I'd ask if anyone had any clearly better ways of trying to deal with this sort of thing.
It all depends on the definition of random you're using. True randomness means you could in theory have the same value 5 times in a row, it also means you could have 5 different values if the universe feels like it. If what you're after is a more even distribution of your variations, you'll have to think of a way to put some rules in place, for example you only allow X number of lock types or chest types, X can be random too if you want. Once X is reached, you could force it to pick between the other lock / chest types. You can also consider 'weighting' certain variations that you want to appear more often.
DFU on UESP: https://en.uesp.net/w/index.php?title=T ... fall_Unity
DFU Nexus Mods: https://www.nexusmods.com/daggerfallunity
My github repositories with mostly DFU related stuff: https://github.com/BadLuckBurt

.

User avatar
Magicono43
Posts: 1139
Joined: Tue Nov 06, 2018 7:06 am

Re: The Worst Attempt At Combatting Pseudo-RNG Patterns During Generation?

Post by Magicono43 »

BadLuckBurt wrote: Sun Oct 23, 2022 6:58 pm It all depends on the definition of random you're using. True randomness means you could in theory have the same value 5 times in a row, it also means you could have 5 different values if the universe feels like it. If what you're after is a more even distribution of your variations, you'll have to think of a way to put some rules in place, for example you only allow X number of lock types or chest types, X can be random too if you want. Once X is reached, you could force it to pick between the other lock / chest types. You can also consider 'weighting' certain variations that you want to appear more often.
I was thinking of explaining exactly what is being done in this sense, but did not feel like adding more to the question and making it more confusing, but there is technically a weight system here, where less rare materials get more "tickets" in a hot to be chosen from, and less rare get less "tickets" etc, and even those amount of "tickets" are altered somewhat by the "estimated room value" of the loot-pile being replaced in question and such.

So there is a weight method going on here, even if it's not incredibly well designed. Perhaps what I should do is when one chest type generates with a certain parameter of materials or something, restrict the next one atleast from generating in the same way somehow, or changed the weights for that next one somehow, maybe that will increase the distribution somewhat and reduce the occurrence of patterns as much.

User avatar
Magicono43
Posts: 1139
Joined: Tue Nov 06, 2018 7:06 am

Re: The Worst Attempt At Combatting Pseudo-RNG Patterns During Generation?

Post by Magicono43 »

So I tried a bit more fiddling around and I think I'm mostly satisfied with the results for the time being atleast. Added more restrictions based on what values for other things were chosen previously, like making a lock less likely to be the same material as the chest it is attached to and some other stuff like that.

Also decided to just use the loadID for the loot-pile in question as the initial "seed" value and added on some other random value to that as well basically. It's not perfect, but I think at the very least the increased restrictions are making the distribution feel a bit more varied, making the same selection of materials less frequent.

Post Reply