Hello, I can go in depth since I figured this out
(Oops, replied to the wrong person.)
Os.time() is more or less accurate, but I dont use it because there have been reports of it being off by up to 3-5 minutes. I don’t know if os.time()'s
inaccuracy is fixed now, but I use a module that gets time externally to make sure everything is ALWAYS in sync.
I’ll show you what I did (thank you for referencing my post haha)
Paste this in a module:
local monthStrMap = {
Jan=1,
Feb=2,
Mar=3,
Apr=4,
May=5,
Jun=6,
Jul=7,
Aug=8,
Sep=9,
Oct=10,
Nov=11,
Dec=12
}
local HttpService = game:GetService("HttpService")
local function RFC2616DateStringToUnixTimestamp(dateStr)
local day, monthStr, year, hour, min, sec = dateStr:match(".*, (.*) (.*) (.*) (.*):(.*):(.*) .*")
local month = monthStrMap[monthStr]
local date = {
day=day,
month=month,
year=year,
hour=hour,
min=min,
sec=sec
}
return os.time(date)
end
local isInited = false
local originTime = nil
local responseTime = nil
local responseDelay = nil
local function inited()
return isInited
end
local function init()
if not isInited then
local ok = pcall(function()
local requestTime = tick()
local response = HttpService:RequestAsync({Url="http://google.com"})
local dateStr = response.Headers.date
originTime = RFC2616DateStringToUnixTimestamp(dateStr)
responseTime = tick()
-- Estimate the response delay due to latency to be half the rtt time
responseDelay = (responseTime-requestTime)/2
end)
if not ok then
warn("Cannot get time from google.com. Make sure that http requests are enabled!")
originTime = os.time()
responseTime = tick()
responseDelay = 0
end
isInited = true
end
end
local function time()
if not isInited then
init()
end
return originTime + tick()-responseTime - responseDelay
end
return {
inited=inited,
init=init,
time=time
}
Here is my shop script (I’ll explain it, too) with weighted randomization for item rarity. If you don’t want item rarity, then just use one table and change the for loop to only get random items in that table.
local syncedtime = require(game.ReplicatedStorage.Utilities.SyncedTime) -- require the module
syncedtime.init() -- Will make the request to google.com to get a time. This will always be synced on all servers, because the time is external.
-- Rarity tables (put any items you want in there)
local commonItems = {
"Common Item",
"Common Item",
"Common Item",
"Common Item"
}
local uncommonItems = {
"Uncommon Item",
"Uncommon Item",
"Uncommon Item",
"Uncommon Item"
}
local rareItems = {
"Rare Item",
"Rare Item",
"Rare Item",
"Rare Item"
}
local veryrareItems = {
"Very Rare Item",
"Very Rare Item",
"Very Rare Item",
"Very Rare Item"
}
local legendaryItems = {
"Legendary Item",
"Legendary Item",
"Legendary Item",
"Legendary Item"
}
local mythicalItems = {
"Mythical Item",
"Mythical Item",
"Mythical Item",
"Mythical Item"
}
local unseenItems = {
"Unseen Item",
"Unseen Item",
"Unseen Item",
"Unseen Item"
}
--Used ratios to calculate the percentages below. Make sure your weights don't go over 100 (I made my range 1-100 so it wouldn't get complicated)
local weights = {
Common = 100, -- 70%
Uncommon = 35, -- 35%
Rare = 20, -- 20%
VeryRare = 10, -- 10%
Legendary = 1, -- 1%
Mythical = 0.1, -- 0.1%
Unseen = 0.01 -- 0.01%
}
local function toHMS(s) -- Just a function for time formatting
return string.format("%02i:%02i:%02i", s/60^2, s/60%60, s%60)
end
function getAvailableItems(day)
local rng = Random.new(day)
local shopItems = {}
for i = 1, 10 do
if rng:NextNumber(0,100) < weights.Unseen then -- Unseen
local item = unseenItems[rng:NextInteger(1, #unseenItems)]
table.insert(shopItems, item)
elseif rng:NextNumber(0,100) < weights.Mythical then -- Mythical
local item = mythicalItems[rng:NextInteger(1, #mythicalItems)]
table.insert(shopItems, item)
elseif rng:NextNumber(0,100) < weights.Legendary then -- Legendary
local item = legendaryItems[rng:NextInteger(1, #legendaryItems)]
table.insert(shopItems, item)
elseif rng:NextNumber(0,100) < weights.VeryRare then -- Very Rare
local item = veryrareItems[rng:NextInteger(1, #veryrareItems)]
table.insert(shopItems, item)
elseif rng:NextNumber(0,100) < weights.Rare then -- Rare
local item = rareItems[rng:NextInteger(1, #rareItems)]
table.insert(shopItems, item)
elseif rng:NextNumber(0,100) < weights.Uncommon then -- Uncommon
local item = uncommonItems[rng:NextInteger(1, #uncommonItems)]
table.insert(shopItems, item)
else -- Common
local item = commonItems[rng:NextInteger(1, #commonItems)]
table.insert(shopItems, item)
end
end
return shopItems
end
local currentDay = nil
local currentShopItems = {}
local offset = (60 * 60 * 17) -- Os.time() / this synced time module both return proper Unix time, which is started from 12:00 AM on Thursday, January 1, 1970. I offset it by 17 hours for it to become 5 PM PST.
while wait(1) do
local day = math.floor((syncedtime.time() + offset) / (60 * 60 * 24))
local t = (math.floor(syncedtime.time())) + offset -- Sets the date to Thursday 5PM PST
local origtime = t - offset
local daypass = origtime % 86400
local timeleft = 86400 - daypass
local timeleftstring = toHMS(timeleft)
print("The time left until 5:00 PM PST is ".. timeleftstring) -- Optional printout, obviously I'd use "timeleftstring" for a countdown timer in a shop
if day ~= currentDay then
currentDay = day
currentShopItems = getAvailableItems(day)
print("The items for today are these: a ".. table.concat(currentShopItems, ", "))
print('Updated shop items')
end
end