Creating a global day system

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

Thank you! :star_struck:

1 Like

What did you need help with again? I don’t think you mentioned it in the post. You only said what you needed to do, not us.

I meant that as in what I need to get done, It’s what I need help with

I mean I would use Messaging service to sync all the server’s time and events up right?

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

1 Like

or rather it would be

os.time()%21600 == 0

since your code would just reset after 6 hours and never come back

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

it says DataTime is nil; In line 10 it shows the error "attempt to index nil with .now(). How can this script be edited to avoid this issue?

my bad replace all DataTime with DateTime, edited above

new error on the same line, UnixTimeStampMillis is not a valid member of DateTime.

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).

idk just brainstorming

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.

1 Like

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

here is my current version of the script.

1 Like

my bad again, mistyped some property names, refer to the original post above it is edited again

Small issue: on line 31 you can’t concatenate text using the + operator, you have to use … (it’s 2 dotd but discourse puts it as 3)

It’s counting up instead of down :flushed:

PS: Sorry you have to edit this so much lol it must be a pain

edited again, dw about me editing frequently i should have had tested the code for all the inconveniences before posting