Page 2 of 3

Re: How to go about daily random numbers

Posted: Sat Jan 08, 2022 10:29 pm
by Gunroar:Cannon()
Wait, so I should use 13 instead of 16 :?

Re: How to go about daily random numbers

Posted: Sat Jan 08, 2022 11:10 pm
by idbrii
What about this:

Code: Select all

local d = os.date("!*t") -- utc date
local rng = love.math.newRandomGenerator(d.yday, d.year)
-- call rng for each random number when building a level:
local num = rng:random(1, 1000)
grump wrote: Sat Jan 08, 2022 5:15 pm It's not really random, because you easily generate numbers for any date in advance.
Why try to randomize your seed? It's love, so people can read all your code, right? Or change their system clock.
Gunroar:Cannon() wrote: Sat Jan 08, 2022 6:51 pm Hmmm... I guess I'll use the first method then. Just thought they might make similar maps :P ... for ... some reason :ehem:
If you put your date number into a random number generator like grump's second suggestion (or mine), then it won't generate similar maps. A good random number generator should create different sequences of numbers for different seeds. You could multiply yday by 100 to ensure very different seeds to the rng each day, but I found my levels very different each day.
pgimeno wrote: Sat Jan 08, 2022 6:25 pm ... The sha1 method does not have this problem, but it's a bit harder to handle, as you don't have functions to yield a range etc.
If building a level, I'd expect you need to make many random decisions. To generate multiple random numbers with the sha version without producing the same sequence at a later date, you'd have to concatenate a sequence number too as well as pad the numbers with 0 like grump said.

Re: How to go about daily random numbers

Posted: Sun Jan 09, 2022 9:53 am
by Gunroar:Cannon()
Oh, that also looks good. Though the problem of people being able change their system clock to get old levels :?

Re: How to go about daily random numbers

Posted: Sun Jan 09, 2022 11:07 am
by grump
Gunroar:Cannon() wrote: Sun Jan 09, 2022 9:53 am Though the problem of people being able change their system clock to get old levels :?
Future levels, too. Is that really a problem? Or could you just not care? I can assure you: you will regret to have opened that can of worms.

Re: How to go about daily random numbers

Posted: Sun Jan 09, 2022 11:41 am
by MrFariator
Going back to new/old levels is kind of a moot point if you don't have online leaderboards or things where people will directly compare their results against one another. And if you go down that road to implement leaderboards, you might as well implement a central authoritative server that the game queries for the given daily seed - where you could do any number of things to make the seed generation harder to track or predict in advance.

Of course, with any kind of online leaderboard, the bigger concern is always going to be more traditional type of cheating (infinite health, lives, maxed out points, etc).

Re: How to go about daily random numbers

Posted: Sun Jan 09, 2022 11:49 am
by pgimeno
Gunroar:Cannon() wrote: Sat Jan 08, 2022 10:29 pm Wait, so I should use 13 instead of 16 :?
Yes, inside hash:sub() only; the other 16 stays. It will then produce a number between 0 and 0xFFFFFFFFFFFFF (that's 13 F's) and then you can get a number in a certain range by using modulo (%). If you use 16, using modulo will produce zeros in the lowest bits > 99.9% of the time.

To leave no doubt, you need to change from this:

Code: Select all

local rand = tonumber(hash:sub(1, 16), 16)
to this:

Code: Select all

local rand = tonumber(hash:sub(1, 13), 16)

Re: How to go about daily random numbers

Posted: Sun Jan 09, 2022 11:58 am
by Gunroar:Cannon()
Thanks for the fix.

I guess it's not to much of problem. Just need a simple system for now, I don't even know anything about online leaderboards :?

Re: How to go about daily random numbers

Posted: Sun Jan 09, 2022 1:11 pm
by grump
It makes no sense to use the convoluted hash method to generate a number just because the RNG algorithm might change in the future, if you use that number to seed love's RNG anyway. It is only good for one high-quality number and would require work to generate more (look up sponge functions if you're interested). It is also very slow.

Re: How to go about daily random numbers

Posted: Sun Jan 09, 2022 2:04 pm
by slime
If you're going to be using love's RandomGenerator, its code applies a hash to the seed before generating the first random number already, so applying another hash to the seed before giving it to love shouldn't be needed.

Re: How to go about daily random numbers

Posted: Sun Jan 09, 2022 2:07 pm
by pgimeno
grump wrote: Sun Jan 09, 2022 1:11 pm It makes no sense to use the convoluted hash method to generate a number just because the RNG algorithm might change in the future, if you use that number to seed love's RNG anyway. It is only good for one high-quality number and would require work to generate more (look up sponge functions if you're interested). It is also very slow.
Yes it's slow, but you don't need to set up something as complex as a sponge function. You can hash a counter.

Code: Select all

local rand
do
  local prefix
  do
    local d = os.date('!*t')
    prefix = ("%d:%d:%d:"):format(d.year, d.month, d.day)
  end

  local ctr = 0
  local pool = love.data.hash('sha512', prefix .. tostring(ctr))
  local idx = 1

  function rand(lo, hi)
    assert(hi - lo >= 0 and hi - lo <= 0xFFFFFFFF, "rand: Invalid range for low and high values")
    if idx > #pool then
      ctr = ctr + 1
      pool = love.data.hash('sha512', prefix .. tostring(ctr))
    end
    idx = idx + 4
    return love.data.unpack("<i4", pool, idx - 4) % (hi - lo + 1) + lo
  end
end
For example, the output of the first 10 numbers between 1 and 5 on January 9 2022 is:
5
3
1
2
3
5
4
1
1
4