I am trying to create a daily and weekly shop, as in Apex Legends or Fortnite (Thank you everyone for the help! Learn something new everyday!)
The issue I am having, I want the servers to automatically choose the item to be sold and this to be random, but using the service to have all the servers, well have the same item.
I want the item to be randomly picked, and it to be unique every 24 hours. I can have it updated and checked per time, per the loop of the game. Now, what if two servers both try to update it, or if I have the very first server up to host it. What if that shuts down?
If a new server was to open, does the subscription automatically check upon the server’s creation and setting the function?
I am very unfamiliar with how this system works, and where to start. I don’t want to run my own server or anything to handle that, and want it to be across servers.
How would I start with this, and have it be efficient I have been trying to think of different ways but can’t seem to find a good place to start.
Just think of the Fortnite shop, and how the 24 hours system happens. Except the servers running determine the item across all of the servers. Now, how do I prevent all the servers trying to update and change it, and how does the subscription system work with new games?
I am asking for advice and where to start and handle this, some code example would help and maybe details to how exactly the system and stuff works, and I don’t want to run my own server and don’t want to set the items manually.
MessagingService doesn’t seem necessary if you want to create a weekly shop. If the servers choose the item randomly, then you can use some sort of synchronized time as the seed to generate it with.
For example, since the unix timestamp (as of writing this) is 1554014511, and the number of seconds in a week is 604800, then you would use floor(1554014511/604800) as your shop’s seed. as long as your server times are synchronized, your weekly shop will generate a new set of items exactly every week.
How would I go about making it exactly the same items for every server on that day…? Do I have to create a type of code per item, as I’m just trying to make it random and determine it on it’s own, and my initial idea was to have the server get a random one, and then update all of the other servers with that item. The issue is I’m not gonna run my own server, or anything to be up to update the servers.
I have no issue working with the time and settings that up, just settings up the system to have all the server. Have the same exact item, that is randomly chosen, and not using my own server or any preset information.
If the items are randomly generated and you use the exact same seed for every server, then wouldn’t it follow that every server would have the same items?
What @XAXA is saying is you probably want to use Random.new for randomness and use time as the seed since time is globally available in all servers. This way you’ll see the same result in all servers.
I’m honestly trying to mess with this, but say you have two scripts in the same game. ServerScriptService on startup, how would I get them to print the same numbers (random) in the same order? Like the first print is 1, the 2nd is 8 and etc…
From my understanding is you set the randomseed to the os.time
local seed = os.time()
math.randomseed(seed)
print(math.random(seed/604800))
I honestly can’t think right now, so I’m sorry for being inconvenient but I am really thankful for the help so far.
Don’t use math.randomseed as this globally modifies the seed.
Secondly Random.new offers useful functions for you.
NextInteger will be useful for selecting shop items.
If #seconds in a week is 604800 then you can divide by 604800 and floor your result to get the number of weeks since the epoch instead of seconds. math.floor(os.time()/604800)
Edit:
Since you’re looking for every week use your weeks since epoch as the seed. NextInteger allows you to use a max and min so you can use local item = shopItems[random:NextInteger(1, #shopItems)]
Use Random.new(seed). Every Random object initialized with the same seed will generate the same sequence of numbers.
local r1 = Random.new(1234)
-- I *guarantee* this will output these numbers if you run this yourself:
-- 0.10645921279869
-- 0.64572802332265
-- 0.47714277796746
print(r1:NextNumber(), r1:NextNumber(), r1:NextNumber())
What you could also do, is have a webhost where you store json data of the shop. Then when the timestamp is equal or greater than the next week timestamp, you can update the game shop based on the response data.
local seed = math.floor(os.time()/(3600*24*7))
local ran = Random.new(seed)
print(ran:NextNumber().."\n"..ran:NextNumber().."\n"..ran:NextNumber())
This code will generate a pseudorandom sequence of numbers that changes every Thursday at 00:00, so servers have no need to communicate with each other as long as the code used to generate the offers are the same.
For example:
local offerList = {"ItemA", "ItemB", "ItemC", "ItemD", "ItemE"}
function getShopItems(seed)
local ran = Random.new(seed)
local weeklyOffer = {}
for i = 1, 3 do
table.insert(weeklyOffer, 1, offerList[ran:NextInteger(1, #offerList)])
ran:NextNumber()
end
return weeklyOffer
end
local seed = math.floor(os.time()/(3600*24*7)+4/7) --The seed should now change every Monday instead of every thursday
local weeklyOffer = getShopItems(seed)
for _, v in pairs(weeklyOffer) do
print(v)
end
Please feel free to correct me if I did the date wrong, but I believe this is how you add a day to os.time
local uptime = os.time()+60 * 60 * 24 --the extra time
local r1 = Random.new(math.floor(uptime/86400))
local r2 = Random.new(math.floor(os.time()/86400))
print(math.floor(os.time()/86400)) --Current time
print(math.floor(uptime/86400)) --Current time + a day and some just to see if I get a different result
local shopItems = {}
-- Pretty much a folder full of whatever you want
for i,v in pairs(game:GetService("ServerStorage"):WaitForChild("Modules"):GetChildren()) do
table.insert(shopItems,v)
end
local item = shopItems[r1:NextInteger(1, #shopItems)] --You can just switch r1 for r2 to check the result
print(item)
This seems to work, albeit sloppy, feel free to correct me and advice is always welcome
The only issue is duplicate items, as with the above code. To which you could probably just do the next thing again and check that. Really cool though, and am I doing the time/dates right?
Something you should be careful about is when you want to update the code used to generate your weekly offers as this would result in your weekly offers suddenly changing within the week (which may result in unhappy players) and inconsistent weekly offers across your servers as there might be older servers still up that are running an older version of your code.
Something you could do to fix this:
function getWeeklyOfferOld(seed) --uses the old code to generate weekly offers
local offerList = {"ItemA", "ItemB", "ItemC", "ItemD", "ItemE"}
local ran = Random.new(seed)
local weeklyOffer = {}
for i = 1, 3 do
table.insert(weeklyOffer, 1, offerList[ran:NextInteger(1, #offerList)])
ran:NextNumber()
end
return weeklyOffer
end
function getWeeklyOffer(seed)
local dontUseBeforeWeek = 2572 -- use the old code before the 7th of April 2019, give roblox 1-2 weeks to phase out your older servers
if seed < dontUseBeforeWeek then
return getWeeklyOfferOld(seed)
end
local offerList = {"ItemA", "ItemB", "ItemC", "ItemD", "ItemE", "ItemF"}
local ran = Random.new(seed)
local weeklyOffer = {}
for i = 1, 3 do
table.insert(weeklyOffer, 1, offerList[ran:NextInteger(1, #offerList)])
ran:NextNumber()
end
return weeklyOffer
end
local dayOffset = 4
local currentdate = os.time()+60 * 60 * 24 * dayOffset
local seed = math.floor(currentdate / (60 * 60 * 24 * dayOffset))
local weeklyOffer = getWeeklyOffer(seed)
for _, v in pairs(weeklyOffer) do
print(v)
end
No, me doing that is to check the result across the days and how it is overall.
Also, typically I release my stuff in large updates. The smaller things are usually something that wouldn’t affect something like this, but thanks for bringing it to my attention as I didn’t think about it.