Hello! I have a small game idea which has one major component: a day system. Basically you can do stuff for more but every day (every 12 hours) there is a new event which adds some fun to the game. You could also get money if you are online when the day changes.
What I need to do:
Alter/add to my script to create the global day countdown system
Make it so there is a random event when the timer ends (I anticipate the big issue with this is when the timer ends all servers attempt to start different events. To fix this maybe there could be a pattern to the events but not an obvious one)
Other stuff I forgot
Here is the current script I have located in a textlabel in a screengui in startergui:
local countdownText = script.Parent
local str
local day = os.time({year = 2025, month = 2, day = 7, hour = 15, min = 30, sec = 0})
function UpdateDay(OldDay)
--What happens when the timer ends (Restart timer, start new event)
end
UpdateDay()
while true do
while os.time() ~= day do
local secondsBetween = os.difftime(day, os.time())
local secs = secondsBetween % 60
local mins = math.floor(secondsBetween % (60*60) / 60)
local hours = math.floor(secondsBetween % (60*60*24) / (60*60))
local days = math.floor(secondsBetween % (60*60*24*30) / (60*60*24))
if days > 0 then
str = days .. ":"
if hours <= 9 then
str = str .. "0"
end
str = str .. hours .. ":"
else
str = hours .. ":"
end
if days > 0 or hours > 0 then
if mins <= 9 then
str = str .. "0"
end
str = str .. mins .. ":"
elseif mins > 0 then
str = mins .. ":"
end
if days > 0 or hours > 0 or mins > 0 then
if secs <= 9 then
str = str .. "0"
end
str = str .. secs
else
str = secs .. "s"
end
countdownText.Text = str
if secondsBetween <= 0 then break end
end
UpdateDay()
end
okay, how can I make it a 6 hour timer then when the timer ends it restarts the timer again, I don’t think I could use os.time for this because that’s with like dates more than just a timer.
well you can use os.time(), just make a variable that stores the starting time of the timer and then just check if the current os.time() - starting time == 21600
local RS = game:GetService("RunService")
local TimerLength = 12 -- in hours
local TimerStartsAt = 0 -- hour when the timer starts, relative to UTC
local msH = 36e5 -- milliseconds in an hour
local msRef = TimerStartsAt * msH -- reference point in time in milliseconds
local msTimer = TimerLength * msH -- Timer time in milliseconds
local Start = math.ceil((DateTime.now().UnixTimestampMillis - msRef) / msTimer)
local function Event()
-- your event logic here
end
local str = ""
while true do
local elapsedTime = DateTime.now().UnixTimestampMillis - msRef
local msTimerElapsedTime = msTimer - elapsedTime % msTimer
local seconds = math.floor(msTimerElapsedTime * 1e-3) % 60
local minutes = math.floor(msTimerElapsedTime * 1e-3 / 60) % 60
local hours = math.floor(msTimerElapsedTime * 1e-3 / 60 / 60) % 24
local days = math.floor(msTimerElapsedTime * 1e-3 / 60 / 60 / 24)
str = tostring(days)..":"
if hours < 10 then
str = str.."0"
end
str = str..hours..":"
if minutes < 10 then
str = str.."0"
end
str = str..minutes..":"
if seconds < 10 then
str = str.."0"
end
str = str..seconds
-- update your textlabel here e.g textlabel.text = str
-- when the time passes start consecutive timer and proceed with the event
if elapsedTime / msTimer >= Start then
Start += 1
Event()
end
RS.Heartbeat:Wait()
end
You could generate the “random” event by manipulating the RNG. You can learn more here, but basically you’re either going to want to set a seed yourself based on a data shared across every server. You need to make sure that every day, the seed will be different tho, if not you’ll always get the same “random” event.
Lmk if you need more details.
Why do they all need to run the same event? The person on the server will only see one anyway. (unless its an event that spans many hours and you want them all to match)
If they all need to match, maybe you can make one server elected to push out the chosen event with messaging service. Or a kinda brute force(dumb?) way to do it might be to use memorystore, have them all attempt to set the same variable and the last one standing wins? One would have to be first, so maybe ,check the value, if its nil set it(to the random event chosen), then wait (few seconds) check again, whatever is there wins the election(on all servers which will check in and get the same event).
the game is a sort of gimmick game where every you can do stuff to collect daybucks. every day there is a new event like “fog” or “2x daybucks”. the event chosen lasts for the 12 hours and is global, so all servers have the same event and the time amount of time until the next day.
Ok, well that check/set, check again method, may work with memorystore. Try it.
My assumption,
one server will be first to set the value, (snooze you lose right?)
the rest will see the posted value and use it (and not attempt to set it)
problem? at some point the value will need to be set to nil(or some known blank value) for the next cycle. depending on how close you get your time syncs this could be a short time, a minute or 2 even.
random may not be a good idea, because you can get the same number over and over(2 or 3 days of the same random event might not be fun)
hey can you alter the script? it has errors at lines: 31, 35, 39 (that I know of)
local RS = game:GetService("RunService")
local textlabel = script.Parent
local TimerLength = 12 -- in hours
local TimerStartsAt = 0 -- hour when the timer starts, relative to UTC
local msH = 36e5 -- milliseconds in an hour
local msRef = TimerStartsAt * msH -- reference point in time in milliseconds
local msTimer = TimerLength * msH -- Timer time in milliseconds
local Start = math.floor((DateTime.now().UnixTimestamp * 1000 - msRef) / msTimer)
local function Event()
-- your event logic here
end
local str = ""
while true do
local elapsedTime = DateTime.now().UnixTimestamp * 1000 - msRef
local msTimerElapsedTime = elapsedTime % msTimer
local seconds = math.floor(msTimerElapsedTime * 1e-3) % 60
local minutes = math.floor(msTimerElapsedTime * 1e-3 / 60) % 60
local hours = math.floor(msTimerElapsedTime * 1e-3 / 60 / 60) % 24
local days = math.floor(msTimerElapsedTime * 1e-3 / 60 / 60 / 24)
str = tostring(days)..":"
if hours < 10 then
str = str.."0"
end
str += hours + ":"
if minutes < 10 then
str = str.."0"
end
str += minutes + ":"
if seconds < 10 then
str = str.."0"
end
str += seconds
textlabel.Text = str
-- when the time passes start consecutive timer and proceed with the event
if elapsedTime / msTimer >= Start then
Start = Start + 1
Event()
end
RS.Heartbeat:Wait()
end