How could I make a main server?

So im making a roster which basically resets every hour, but its random so I wanna use messaging service so its the same in each server. I think I know how to do this (though some code sample of how to transfer dictionaries would be helpful) but I wanna make a main server which would be the oldest. How can I make it so only the oldest server is the one that resets the roster? (or any one server)

I already have the resetting part I just wanna make a main server for messaging service so every server will have the same roster and no disrepancies.

I don’t think that’s necessarily the best solution to the problem. Random numbers on computers are pseudo random usually and have some useful properties. One of these is that the same seed will generate the same sequence of numbers. You can just ensure that every server is using the date and time (to the hour) to create a seed that should line up. With the same seed, all servers should pick the same roster as long as if you only use the random object for roster selection.

If however you would prefer a main server route, basically you’ll have to have every server publish its age unless it’s already received an age that beat it. The oldest non challenged age publish within your time limit is understood to be the main server. It can then take actions as the main server. You could also try to make each server try to understand its spot in line, but if a server crashes you will need a way to reconstruct the line. It’s also worth noting, that while unlikely servers can tie for oldest. In which case you could have them toss dice or something. Should be rare enough you can probably ignore that though. And I don’t know reliable messaging service is so it’s possible there are lots of edge cases which could be a pain to handle, so I would recommend the temporal psuedo-random seed approach.

1 Like

I’ve never used math.randomseed so I’m not sure how to use it but how could it be compatible with picking the same random tower from each rarity, heres my script:


local function restockRoster()
	for i, rarityTable in pairs(towers) do
		local keys = {}
		for key, _ in pairs(rarityTable) do
			table.insert(keys, key)
		end

		if #keys == 1 then
			local onlyKey = keys[1]
			return rarityTable[onlyKey]
		end

		local position = Random.new():NextInteger(1, #keys)
		local key = keys[position]

		table.insert(towerRoster,rarityTable[key])
		
	end
	print(towerRoster)
end

How could I apply a random seed to this function?

1 Like

So to get a random object with a seed, you simply need to pass a number into the .new part of Random.

local rosterRandom = Random.new(1234213412)

Now of course, we can’t just set it to a hard coded number like that. If we did then every time that function ran, it would be the exact same roster. Kind of what we want, or at least what we want to exploit, but we also need it to change. That’s why we will want to be using the time as the seed.

We will be using os.time. Unless I’m mistaken that will return about the same number for every machine within a small tolerance. Since you only need to adjust the roster every hour, we don’t actually need to worry about that small tolerance. The hardest part about this is actually going to be rounding the time correctly. We basically will have to round it to the nearest hour. But if we were querying at half an hour intervals instead, the actual rounding might flip some servers up and others down. So ideally we want our rounding to be based on the hour exactly.

local pickRandomSeedFromTime()
    local t = os.time()
    local newT = t / 3600 --Divide it into hours
    return math.floor(newT + 0.5) add a constant to push it away from cutoff.  You’ll need to adjust this to with the best as it’s super important
end

Now integrating it into your code is rather straightforward


local pickRandomSeedFromTime()
    local t = os.time()
    local newT = t / 3600 --Divide it into hours
    return math.floor(newT + 0.5) add a constant to push it away from cutoff.  You’ll need to adjust this to with the best as it’s super important
end


local function restockRoster()
    local rosterRandom = Random.new(pickRandomSeedFromTime())

	for i, rarityTable in pairs(towers) do
		local keys = {}
		for key, _ in pairs(rarityTable) do
			table.insert(keys, key)
		end

		if #keys == 1 then
			local onlyKey = keys[1]
			return rarityTable[onlyKey]
		end

		local position = rosterRandom:NextInteger(1, #keys)
		local key = keys[position]

		table.insert(towerRoster,rarityTable[key])
		
	end
	print(towerRoster)
end

Now if you run this code, even though its picking random numbers every time, it should only switch once per hour. Though I double checked with ChatGPT that my logic is sound, I wasn’t actually able to run tests on the timePick thing. It should align with servers (with a buffer to help avoid the hour switch point). Though you should probably run some tests yourself on it. You can do this by instead of using os.time() supply a number in the function then just count up

1 Like