[Blueprint Bug] Using a Random Stream passed to a function gives incorrect results

If I make a Blueprint function that takes a Random Stream as an input parameter, the values gotten from that stream inside the function are not correct. It acts like the random stream is reset each time is used in the function.

This has been recreated in a fresh project.

  1. Start a new project using any template (I used Blank), start content is not required
  2. Create a Blueprint Actor with any name
  3. In that Blueprint make three “Editable” variables: “Random : Random Stream”, “Count : Integer”, “Use Func: Boolean”
  4. Add a function to the Blueprint called “Get Random”. Add a Random Stream as input and an Integer as output.
  5. Create a construction script and function blueprint as shown in my pictures.
  6. Compile and save then place your blueprint actor in the scene
  7. Make sure the output log is visible and then set the count to something like 10, and toggle the “Use Func” option on and off. Note that when not using the function the values are as expected, but when using the function the values are all identical. I have also included a screenshot of my output from this.

55160-random_bug_output.png

Hi,

You need to update your seed value. If you aren’t changing the seed, the random stream output will be the same.

Look into “Set Random Stream Seed” if you want to have different random outputs.

Hope that helps!

Why would I change the seed value going into the function? Sorry but what you are saying isn’t making any sense to me.

I know all about seeds. You start with a seed then each call to the random stream gives you the next value in a series of numbers derived from a given seed. I know that and that works fine - unless you are in a function. In a function that number spit out from the stream is ALWAYS the first number in the sequence when it shouldn’t be.

Again my example above demonstrates it working properly in the main construction script and not working properly in the function.

Hello,

I was able to reproduce what you are seeing on our end. However, this is working as intended. The output will only change when the seed has been changed. For example, If the initial seed is set to zero and if gives you 22. Your answer from then on will be 22 if the seed is zero. I hope that this information helps.

Make it a great day

No that makes zero sense. The bug is that the random stream is being RESET back to the beginning of the sequence when used inside a function. There is no way this can be as design.

The entire purpose of a random stream, a seed based number series, is that you start with one seed and can then iterate through the sequence getting a repeatable series of random numbers. You change the seed if you desire to get a different series of numbers.

Again this works exactly as it should, except when passed into a function. When passed into a function, then the stream is reset back to its first number in the series - every time. So you can never get beyond the first number in the series.

edit: To clarify, what I mean is that the position of the stream in any given random sequence based on a given seed, should not change just because the stream is passed into a function. If you have a series, based on a seed (and this is made up) of:
[1,10,12,9,100] and your stream is currently pointing to index 2, or the value 12, then passing that stream into a function for use should when queried give the next value at index 3 of 9. Instead, passing it into a function is resetting the stream pointer back to index 0. It should not do that.

Hello,

I went back over your original post. I believe I may have set my blueprint up differently. I would like for you to try the setup that I have provided below and let me know what the results are that you get from the test. Could you also provide the engine version that you are using? After creating this blueprint in the construction script of an actor all you will need to do is add it to the scene and hit compile. You should see a set of “random” numbers.

Test:

Note: The function is set up the exact same way as the function that you provided a screen shot of in your original post.

Just tested this and using your Construction Script I am still getting the same incorrect results. The first loop where the random stream is used in the main construction script correctly returns a sequence of 10 random value, but then the next 10 entries generated in the second loop by passing the random stream into the function all produce the exact same value. I am using 4.8.2.

Hello,

There appears to be a difference in our results (I do not get the repeating number that you have reported). Could you try this same set up in a clean 4.8.3 (The exact version I am using) project?

I can but it will have to be done at home as updating the version here at the studio is a real pain since there is no outside of launcher way to update.

Hello,

Let me know how this goes when you get a chance to test it and I will assist you further.

I think I have this working now. Apparently what I needed to do was open up the details on the Function Inputs (Which I didn’t even know existed before) and set the Random Stream parameter to pass by reference. Which in hindsight makes sense, but like I said I didn’t even know that option was there.

Anyway now that I did that it appears to operate as expected. Where you doing this? Even on 4.8.3 it doesn’t work unless I do that.

Hello,

First off I am happy to hear that your issue has been resolved. As for weather I was passing by reference. I don’t recall making any changes, however it is possible that I did. I am going to convert your last comment to an answer.

Make it a great day

Thank you for this follow-up. I was having the exact same problem in 4.15, passing a random stream to a function made it repeat the same value. It seems the function automatically makes a new copy of the random stream unless setting the input to “pass-by-reference”. Which, as you said, makes sense but is pretty non-obvious. I don’t know if this is because the random stream is a struct? I believe the normal behaviour for objects is to pass by-reference automatically (ie you don’t expect to get a newly initialized player character when you pass a player character).

Just to clarify with an illustration.