Page 1 of 1
Getting a RNG state
Posted: Tue Dec 31, 2013 3:23 am
by bb010g
I want to be able to store the state of a RNG so I can go set forwards and backwards through a list of seeds. I thought I could just pull the seed from a generator, like this (which runs if you just stick it in a directory as main.lua and type "love ." from a prompt):
Code: Select all
function love.load()
rng = love.math.newRandomGenerator(42)
for i=1,10 do
print(rng:random(1,20))
print(rng:getSeed())
end
love.event.quit()
end
However, that returns:
Code: Select all
1
42 0
13
42 0
11
42 0
4
42 0
7
42 0
11
42 0
13
42 0
12
42 0
13
42 0
7
42 0
The generator's seed remains at 42. Is there a way I can get the current state of a generator that I can put back in later?
Re: Getting a RNG state
Posted: Tue Dec 31, 2013 8:19 am
by Plu
The seed is not the current state. Those are two different things.
What exactly are you trying to accomplish? It'll be easier to give suggestions if we know why you want to store the state of the RNG.
Re: Getting a RNG state
Posted: Tue Dec 31, 2013 2:20 pm
by Ranguna259
What do you want ? do you want the seed or a list of outputs from the prng ?
Re: Getting a RNG state
Posted: Tue Dec 31, 2013 2:39 pm
by DaedalusYoung
I can think of some reasons why you would want the state of the rng saved.
For example: you have a slot machine minigame. The player can save before playing the slots, then reload if he doesn't win and try again, until he wins a million points (I know I did this in GTA SA). But you don't want that to happen. You want to have the exact same outcome all the time whenever the player saves and reloads, so he can't use this 'cheat'. But you still want the slot machine to be random, so how do you know, after having generated an arbitrary number of previous random numbers, what the next random number is going to be? Only by knowing the rng's state at the time of the save.
Re: Getting a RNG state
Posted: Tue Dec 31, 2013 4:01 pm
by Plu
If you want to do that, you need to store the initial seed and the amount of numbers generated so far, and you can "rewind" the number generator to wherever, by simply setting the same seed and then calling the generator that many times. It'll end up in the same state it was in before.
(If you do this for really long games, considering occasionally resetting your RNG with a new seed so that you don't have to call it a million times when the game loads in order to reset it.)
Re: Getting a RNG state
Posted: Mon Jan 06, 2014 4:34 am
by bb010g
Sorry; I was away for a while for family stuff. I'm using this for a game where the levels are randomly generated. I want to be able to reverse the state throughout levels. I was able to hack this together, and it avoids generating tons of random numbers between state changes (unrelevant code cut out):
Code: Select all
function infiniteLevelTable()
local levelTable = ...
...
local initSeed, ... = 1, ...
local rngHistory
local newRng
local generateLevel = function ()
physicsClean(levelTable.levelBlocks); collectgarbage("collect"); levelTable.levelBlocks = {}
levelTable.levelBlocks, newRng = generateBlocks(rngHistory[#rngHistory],rndintrv,slope,minheight,maxheight,length) end
...
levelTable.gotoFirstLevel = function () levelTable.level = 1; rngHistory = {love.math.newRandomGenerator(initSeed)}; generateLevel() end
levelTable.gotoNextLevel = function () levelTable.level = levelTable.level + 1; table.insert(rngHistory, newRng); generateLevel(); return true end
levelTable.gotoPreviousLevel = function () if levelTable.level ~= 1
then levelTable.level = levelTable.level + 1; rngHistory[#rngHistory] = nil; generateLevel(); return true
else return false end
end
return levelTable
end
Thanks for your suggestions, however.
Re: Getting a RNG state
Posted: Mon Jan 06, 2014 8:18 am
by Plu
This is effectively what I mentioned about occasionally resetting your RNG, except in a more controlled fashion
It should work just fine.
Although your gotoPreviousLevel is currently removing the value for the current level, is this intentional? It'll generate a different level when you return to the level again.
Re: Getting a RNG state
Posted: Fri Jan 10, 2014 1:35 am
by bb010g
It shouldn't, as generateLevel relies upon the rngHistory[levelTable.level] for its use and would regen the same RNG from the same calls.
Re: Getting a RNG state
Posted: Fri Jan 10, 2014 8:46 am
by Plu
then levelTable.level = levelTable.level + 1; rngHistory[#rngHistory] = nil; generateLevel(); return true
Right now it seems to be deleting the seed from the rngHistory table though, if I'm reading this right. So if you go back to the next level again, there won't be a value there, and a new one will be generated.