Issues

Issue #692 resolved

Lovely RandomGenerator method naming

hahawoo
created an issue

So currently in RandomGenerator objects and love.math there are:

randomnormal
randomseed

I'm aware this would make randomseed inconsistent with Lua, but perhaps these names are more consistent with the API?

randomNormal
setRandomSeed
getRandomSeed -- If it's stored, hehe.

Comments (10)

  1. rude repo owner

    +1 (Actually, I'm Rude, so +∞).

    I agree that LÖVE API consistency is more important than consistency with Lua's libraries.

  2. hahawoo reporter

    I'm thinking no actually, because the random method changes the state of the generator. Like, setRandomSeed just changes the state of the generator, and getRandomSeed would just return the state of the generator, whereas random kind of "does something" which returns something and also changes the state.

  3. Alex Szpakowski

    An alternative is a Java-ish approach (modified for Lua / LÖVE):

    rng:setSeed(seed)
    seed = rng:getSeed()
    
    r = rng:nextNumber(m, n)
    r = rng:nextNormal(stddev)
    
    
    love.math.setRandomSeed(seed)
    seed = love.math.getRandomseed()
    
    r = love.math.nextRandomNumber(m, n)
    r = love.math.nextRandomNormal(stddev)
    

    EDIT: getRandomSeed doesn't really make sense. getRandomState does, but then should setRandomSeed be renamed to setRandomState to match?

    EDIT 2: There is a problem with getRandomSeed / getRandomState: LÖVE's implementation of the RNG uses a 64 bit integer for the seed/state value, but Lua numbers are (double-precision) floating point. Currently when calling randomseed, LÖVE converts the argument to a 64 bit integer by treating its bits as a uint64, rather than casting from double to uint64. This means all 64 bits of the (float) argument can be used.

    When you call getRandomState it would return the same value passed into setRandomState, however tonumber(tostring(getRandomState())) does not equal getRandomState() for most values, because tostring cannot exactly represent floating point numbers in all situations.

    The default random seed is a large uint64. When getRandomState would be called, it could either be sent to Lua by converting to a double or by treating its bits as a double. In the former case, setRandomState(getRandomState()) would not work for the default random seed because doubles can only represent integral numbers up to 53 bits. In both cases, calling tostring on getRandomState would mess things up as well - for example, in the latter case with the default random seed, calling tostring(getRandomState()) returns 9.2058303155128e-303.

  4. hahawoo reporter

    Hmmmm, I'm not such a fan because

    • The function and method names are different, meaning there's slightly more to learn and keep in mind.
    • It's more verbose in some cases, especially love.math.nextRandomNumber compared to love.math.random.
    • I don't think "next" communicates something pertinent to using the functionality, it's like it communicates something about how the generator works internally and not something about the use of calling the function.
  5. hahawoo reporter

    I'm not 100% sure I know what's going on, and sorry if I'm saying all obvious stuff, but I assume that the only useful purpose of getRandomState is to pick up where the last random generator left off. (Why you'd want this exactly, I'm... unsure, but like, it seems like something plausible, maybe. :D)

    So basically setRandomState(getRandomState()) should work, and I don't think it really matters what it looks like as a string, or if getRandomState returns the same Lua number that was given to setRandomState. It would be something to note in the docs though, lest people get freaked out.

  6. Alex Szpakowski

    The nicest solution to the setRandomState / getRandomState problem I can think of is to make them like this:

    love.math.setRandomState(low, [high])
    low, high = love.math.getRandomState()
    

    Where low and high are 32 bit integers. If only one argument is given to setRandomState, it will be casted from a double to a 64 bit integer internally.

    This means that while the API is not quite what one would expect coming from Lua's math.random, it would be able to handle tostring just fine as well as all possible seeds, while at the same time having a simpler interface for those who don't need all 64 bits or don't need to save the random state.

  7. Alex Szpakowski

    getRandomState is useful for saving the current state of the RNG (for example in a game with procedurally generated content, if you want persistent save states.)

    It is kind of useless if it can't be represented as a string, since save files are usually strings. It would also be pretty weird if it didn't even return the same type of value that's normally passed to setRandomState.

  8. Log in to comment