Getting a RNG state

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
bb010g
Prole
Posts: 3
Joined: Tue Dec 31, 2013 3:06 am

Getting a RNG state

Post 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?
User avatar
Plu
Inner party member
Posts: 722
Joined: Fri Mar 15, 2013 9:36 pm

Re: Getting a RNG state

Post 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.
User avatar
Ranguna259
Party member
Posts: 911
Joined: Tue Jun 18, 2013 10:58 pm
Location: I'm right next to you

Re: Getting a RNG state

Post by Ranguna259 »

What do you want ? do you want the seed or a list of outputs from the prng ?
LoveDebug- A library that will help you debug your game with an on-screen fully interactive lua console, you can even do code hotswapping :D

Check out my twitter.
User avatar
DaedalusYoung
Party member
Posts: 413
Joined: Sun Jul 14, 2013 8:04 pm

Re: Getting a RNG state

Post 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.
User avatar
Plu
Inner party member
Posts: 722
Joined: Fri Mar 15, 2013 9:36 pm

Re: Getting a RNG state

Post 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.)
User avatar
bb010g
Prole
Posts: 3
Joined: Tue Dec 31, 2013 3:06 am

Re: Getting a RNG state

Post 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.
User avatar
Plu
Inner party member
Posts: 722
Joined: Fri Mar 15, 2013 9:36 pm

Re: Getting a RNG state

Post 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.
User avatar
bb010g
Prole
Posts: 3
Joined: Tue Dec 31, 2013 3:06 am

Re: Getting a RNG state

Post 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.
User avatar
Plu
Inner party member
Posts: 722
Joined: Fri Mar 15, 2013 9:36 pm

Re: Getting a RNG state

Post 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.
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Google [Bot] and 8 guests