I'm working on a small, simple game (mostly to learn what's new in Java 8 and JavaFX). One of the features I have is the ability to seed the game's random number generator so you can play roughly the same game as a friend on a different system (think Minecraft Maps or The Binding of Isaac games).
I would like to add the ability to save the game to be resumed at a later time. After looking over the documentation for the java.util.Random
class, I can't find a way to get the current seed of the random number generator. The only ways I have come up with to restore the random number generator after saving the game is to either access the seed via reflection at save time and use that, or to seed the initial seed at load time and just call nextInt()
over and over again until we've rolled forward the random number generator enough to be where it was before the game was saved.
First of all, as @user2357112 points out, Random
implements Serializable
, and does so by writing the seed
field (along with the nextNextGaussian
and haveNextNextGaussian
fields). Have you tried simply serializing it? That should 'just work'™. Other serializers, like Gson, also work. gson.fromJson(gson.toJson(r), Random.class);
returns an identical object.
You don't necessarily need the same Random
instance, just a consistent one. You could simply call nextLong()
and write that value to your save file as random_seed
or whatever. Then just initialize a Random
instance with that seed, and now all runs loaded from that file will behave the same. If you wanted, you could even reset the Random
instance in your currently running game to the same seed too.
On the other hand if you're generating maps or other seemingly-constant content randomly and want it to persist between loads, I'd think you'd do better to simply seed your Random
at the start, and save that value like you describe. To save on computation you could do this in chunks smaller than a whole level. For example, split each level into 10ths, and use (and save) a different seed for each 10th. Then you just have to generate the portion the user's on now, and not the parts they've already crossed. If you were to only save the current state like you propose, the user couldn't go backwards in the map (which might not be a problem for your game in particular, but wouldn't be a great practice in general).
UX caveat: saving your game's randomness seems potentially over-engineered. As a user, I don't generally expect a save file to persist randomness. In fact, sometimes players take advantage of that, for instance if they die in a random encounter right after saving, reloading the game doesn't immediately drop them back into the same encounter. I would consider just leaving your game's Random
unseeded and let each game be slightly unique.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With