Random:GetState() and Random:SetState()

As a developer I may need to get a Random’s state in the form of a basic data type (string/number). This is useful for displaying debug data or for serializing it for storage in datastores, for example.

string Random:GetState()
void Random:SetState(string State)

An instance shouldn’t have an inaccessible state that exists in the ether and can’t be replicated. I should be able to deconstruct an instance into basic data types, and then use that data to reconstruct a copy. Enabling developers to do this enables them to do anything they could possibly want to do with the instance and its state.

16 Likes

Use Cases:

  • When generating rivers in a smooth terrain map, sometimes there’s a hole in a river. I save the state of the RNG before I begin generating water, and then when I want to test fixes to the issue, I just have to generate the water instead of the whole map since I can resume from the state post-map generation
  • When generating random appearances for characters in my game, occasionally I’ll get an error. To make this easier to debug, I’d keep a reference to the state and then on error I could use that state to instantly trigger the error for further testing rather than waiting through 50 or 100 appearance generations
4 Likes

State is actually a number, not a string.

The Random API is intentionally agnostic to the implementation details of the RNG algorithm and state size/format.

The use cases I’ve seen so far (serialization, debugging) can be met by storing the initial seed along with a count of how many times NextNumber and NextInteger have been called.

1 Like

I’d love to have this API created. It’d be easier than manually having to store the information I put into the instance beforehand, making it harder to cross reference against multiple other instances of ‘random’ while debugging.

I don’t want to have to write a wrapper around Random just to store the state it’s already storing.

If Random stored a count and seed that we could access, we wouldn’t need to write a wrapper, and could use the count and seed to store the state. Maybe this data is already available, but I can’t find any API documentation to check yet.

5 Likes

It would be useful to expose the seed and number of times it has been called then. Additionally, a fast forward method would also be nice that took a number of iterations. This would solve OP’s use case in a somewhat usable way and allow the API to be agnostic to implementation details.

2 Likes

As a Roblox developer, making the Random object’s state intentionally hidden means you’re forced to:

  • A) Make a wrapper, i.e. keep track of the seed and of how many times you’ve called Next, then spam-calling Next every time you’d like to restore state (which is extremely goofy and inefficient), or
  • B) Reinvent the wheel and make your own based on Luau’s RNG algorithm

In both cases, performance will suffer greatly.

Instead, give developers a simple API to get/set the Random’s state, akin to:

string Random.State
void Random:SetState(string newState)
Sidenote - internally, the state is stored as uint64_t. Casting this to double (Luau’s number datatype) would lose integer precision at values past 2⁵³. Instead, it’s converted to a string.

Use cases:

  • Syncing an RNG between the client and server, allowing client-sided prediction of random events (i.e. shotgun spread), as well as the ability to roll back if the server rejects a request
    • Useful for keeping a bajillion RNG calls from being redundantly sent across the network, freeing up server resources for other things (like hitreg), and decreasing minimum network requirements
  • Easier debuggability; being able to retrieve/log/restore the state of an RNG without having to force potentially hundreds of thousands of useless Next calls
  • The abilitity to serialize/deserialize an RNG without, again, forcing a bajillion Next calls to restore the state
  • Most importantly, reducing the current black-box behaviour of Random objects.
    • It’s pragmatic to hide as little as possible from developers, for the most part. Making interfaces robust and reducing hidden behaviour allows them to be much more useful.

It’s been 6 years, I think this would be a well-appreciated change if it were implemented.

3 Likes

This would be useful for debugging, I don’t want to wrap Random.