real random vs pseudorandom

real random vs pseudorandom

Discuss Lua based Spring scripts (LuaUI widgets, mission scripts, gaia scripts, mod-rules scripts, scripted keybindings, etc...)

Moderator: Moderators

Post Reply
User avatar
Pithikos
Posts: 146
Joined: 26 Dec 2008, 14:26

real random vs pseudorandom

Post by Pithikos »

I want to use "randomize" in my mod so that in each game there is a different value. Thing is that with the math.random() function you get always the same value.

Googling gave me these ways to make a real random number:
  • using math.randomseed(os.time())
  • using external socket library
  • using a text file to write an integer in every game
The simpliest and most appealing to me seemed the third option but as not all people are going to have the same data in their file it's going to give different random values to each player as well thus not synced.
Is os.time possible to get used? As my guess is that it still is going to give different values for each player with the thought that not everyone runs the same os.
How the heck is random working in synced btw? As not all players have the same processors. Shouldn't people be getting different values? :?
User avatar
Pithikos
Posts: 146
Joined: 26 Dec 2008, 14:26

Re: real random vs pseudorandom

Post by Pithikos »

I playied a bit with the function and it seems that only the first number is always the same. Btw I use random like this:

Code: Select all

choice=math.random(0, 1)
Fixed it with:

Code: Select all

math.random(0, 1)
choice=math.random(0, 1)
So just calling it twice makes it work for some weird reason :S
User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7050
Joined: 16 Nov 2004, 13:08

Re: real random vs pseudorandom

Post by zwzsg »

Synced or unsynced?

The random of synced is already given a randomised seed, this it taken care of by the engine.

os.time(), reading a file, etc... would anyway not be allowed in synced.

I don't know if this has been fixed, but the random seed of unsynced on the other hand wasn't well randomly initialised when I tried it. I tried to use os.time(), but because of rounding errors (seconds since 1970 is a huge number!), it only change every 10s or so.

Here's my little random init function I use for unsynced

Code: Select all

-- Call once at the start of the widget
local function BetterizeRandom()
    local x,y=Spring.GetMouseState()
    local BetterRand=math.floor(99*(os.clock()%99999)+(99*(os.time())%99999))+Spring.GetDrawFrame()+math.random(0,999)
    for k=-5,BetterRand%100 do
        math.random(0,999)
    end
end
I don't know how much of it is useful, how much is wishful thinking, but it worked for me. The important bit is to use modulo, otherwise the small numbers get drowned in the rounding errors of the big ones.

I don't use randomseed, so that if random is already better randomised than my function can, then I won't lose such previous better randomisation. And if the previous random was super poor, then I at least would have randomised it amongst 100, which was good enough for my needs.

And again, this is for unsynced, don't worry about synced, the random seed of synced is already well randomised.
User avatar
Niobium
Posts: 456
Joined: 07 Dec 2008, 02:35

Re: real random vs pseudorandom

Post by Niobium »

Is there a reason why math.randomseed doesn't work? I tested it and it appears to do absolutely zero
User avatar
smoth
Posts: 22309
Joined: 13 Jan 2005, 00:46

Re: real random vs pseudorandom

Post by smoth »

"real random" lol must, fight, argument, on, whether, or, not, anything, is, random...
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: real random vs pseudorandom

Post by Argh »

Well, yes, but not in the context of Spring synced. I presume that's why randomseed isn't allowed, either, but IDK.

Anyhow, couple of things:

1. http://stackoverflow.com/questions/4619 ... rms-in-lua

2. Since this effects the first number, just discard it immediately. Use math.rand at the start of operations, and toss it. What you'll find, as a practical issue, is that when you have lots of Gadgets using math.rand, only the first one is going to have issues with this, IIRC, since subsequent calls to math.rand will grab the next value.
User avatar
SpliFF
Posts: 1224
Joined: 28 Jul 2008, 06:51

Re: real random vs pseudorandom

Post by SpliFF »

Spring has its own random and randomseed functions in synced lua. They exist for obvious reasons, to consistently provide the same value to all clients.

You either have 1 of 2 problems:

1.) You are always providing the same value to randomseed(), or you aren't setting it at all.

- or -

2.) math.randomseed() is broken.

If you eliminate the problem being 1. (which is the most likely reason), then file a bug on mantis. But first make sure you understand the issue:

For reasons that are obvious (if you understand what synced is) you can't use anything that changes between players. So that rules out every option mentioned so far - the time, the mouse position, or a value in a dynamic file (not all players will have the file). Randomseed is reset everytime spring starts so you need some kind of seed that isn't static, but by design everything in synced lua IS static!

When it comes down to it the only option you probably have is to have one machine (the host) broadcast a seed to all other players. That way the value is random but all players still get the same value.
User avatar
Cheesecan
Posts: 1571
Joined: 07 Feb 2005, 21:30

Re: real random vs pseudorandom

Post by Cheesecan »

If it doesn't work properly you can always just write your own pseudorandom generator, it's not very difficult, google linear congruential generator.
User avatar
SinbadEV
Posts: 6475
Joined: 02 May 2005, 03:56

Re: real random vs pseudorandom

Post by SinbadEV »

smoth wrote:"real random" lol must, fight, argument, on, whether, or, not, anything, is, random...
http://www.random.org/

(As a Moralistic, Free-Will-Supporting, Liberal/Conservative Hybrid, Meritocratic Socialist* who enjoys a good Philosophical discussion... especially with those who stand on the precarious fence that anyone who doesn't believe in free will and therefore is, presumably, of the opinion their opinion is not under their own control... I would like to point out that we have a great Off Topic Forum for just such discussions)

* Labels selected at "random" from my coffee addled, sleep deprived, Conservative Liberal Arts Educated mind and so I declaim no warranty of their accuracy or use for any purpose etc.



On Topic: It would be cool if we could use one of the tools offered by random.org to provide a "synchronized" random seed
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: real random vs pseudorandom

Post by Argh »

In regards to randomseed, yeah, I think it would be good to see a test- IIRC, I had weird issues with it, the one and only time I used it (for my music widget).
User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7050
Joined: 16 Nov 2004, 13:08

Re: real random vs pseudorandom

Post by zwzsg »

SinbadEV wrote:On Topic: It would be cool if we could use one of the tools offered by random.org to provide a "synchronized" random seed
You must have missed the point about how Spring already has a good "synchronized" random seed.

Plus I would hate Spring to connect to random internet site just to fetch a seed.
User avatar
CarRepairer
Cursed Zero-K Developer
Posts: 3359
Joined: 07 Nov 2007, 21:48

Re: real random vs pseudorandom

Post by CarRepairer »

My old randomizer from 2008 :regret:

Code: Select all

local function scrambleNumber(number, randhash)
	local numberReturn = number
	for i = 1, randhash:len() do			
		numberReturn = numberReturn * 33 + randhash:byte(i)
		numberReturn = numberReturn % 65535
	end
	return numberReturn 
end

local function makeSeed()
	local seed = 5381
	
	local allPlayers = Spring.GetPlayerList()
	for i,v in ipairs(allPlayers) do
		local name, _, _, teamID, allyTeamID, pingTime, cpuUsage, country, rank = Spring.GetPlayerInfo(v)
		local x, y, z = Spring.GetTeamStartPosition(teamID)

		local randhash = '' .. teamID .. allyTeamID .. pingTime .. cpuUsage .. country .. rank .. x .. y .. z

		seed = scrambleNumber(seed, randhash)
	end

	local allAllies = Spring.GetAllyTeamList()
	for i,v in ipairs(allAllies) do
		local xmin, zmin, xmax, zmax = Spring.GetAllyTeamStartBox(v)
		local randhash = ''
		if (xmin) then  -- ally start boxes are not always available
			randhash = '' .. xmin .. zmin .. xmax .. zmax
		end
		seed = scrambleNumber(seed, randhash)
	end

	return seed
end
User avatar
knorke
Posts: 7971
Joined: 22 Feb 2006, 01:02

Re: real random vs pseudorandom

Post by knorke »

so we put a random number in your random number so you can randomize while you randomize.

couldnt gameID be used as a seed? It is always different and stuff.
User avatar
Cheesecan
Posts: 1571
Joined: 07 Feb 2005, 21:30

Re: real random vs pseudorandom

Post by Cheesecan »

CarRepairer wrote:code goes here..
Some quick critique on your routine..

Normally your fields will look something like; teamID is 1-18, allyTeamId 1-2, ping maybe 50 to 600(bias toward 300ish), cpu maybe 0 to 80%(bias to lower portion, the longer spring exists, the faster machines we will have, so the closer to 0 this becomes unless devs keep making spring slower and slower), country codes 243 different ones where fi, uk, de, fr, rus are highly overrepresented.., rank 1-6 where there is a bias toward the higher ranks for sure. Team start positions almost the same every game if on the same map, and users tend to play the same maps unfortunately. Same thing with start boxes.

In a given game, I would wager that when you lump those things together for all players, the result you get will be quite similar(more similar than for just any given player probably) each time, approaching some kind of norm since many players will share approximately the same values for some of those variables.

16-bit hash function is what is most often used for pseudorandom functions but I'd like to see a PDF for it over say 5+ games because I actually think you will get a lot of collisions most of the time with the input you've chosen. Only requires outputting the data to hd and then plotting it.

In conclusion, your seed picking is not proven and probably isn't uniformly distributed. This of course means random numbers generated based on it won't be as good as possible.
User avatar
CarRepairer
Cursed Zero-K Developer
Posts: 3359
Joined: 07 Nov 2007, 21:48

Re: real random vs pseudorandom

Post by CarRepairer »

Cheesecan, those were the only values available in that version of Spring. It was a temporary measure until the engine was fixed to allow random numbers. It was either that or nothing.

And I think you must be bored because you're overthinking it. That code was using the Bernstein hash (see here) to generate a seed. I highly doubt any two Spring games could generate the same random numbers.

Since I'm bored too here are some response points...

Team start positions are not the same in each game, players often choose their start positions.

As machines are getting faster so too the games get more demanding.
User avatar
Cheesecan
Posts: 1571
Joined: 07 Feb 2005, 21:30

Re: real random vs pseudorandom

Post by Cheesecan »

CarRepairer wrote: And I think you must be bored because you're overthinking it.
I was. :) I get that your program/script wasn't a serious attempt. My post was just meant as some constructive criticism for the sake of debate/fun. I still would like to see PDF plot for it. :)
CarRepairer wrote: Since I'm bored too here are some response points...

Team start positions are not the same in each game, players often choose their start positions.

As machines are getting faster so too the games get more demanding.
The way I see it, start positions will be roughly the same each game, since everybody places themselves within a say 100 unit square of the metal patches(unless it is green fields maybe..).

I don't quite get that last part? I simply meant that CPU usage will begin to approach 0% the older Spring becomes(granted that no major engine changes are made that would make Spring more demanding on hardware). The faster machines we have, the less % of the PC resources Spring will use, so I just used that as an argument to show that your random function would actually become less good over time. That just struck me as quite fun. :)
Post Reply

Return to “Lua Scripts”