Ideas for synced time in all servers?

I’m working on a facility-based game where 1 IRL week = 1 in-game month. The game revolves around community interaction: each week, a new director is elected to lead, manage funding, and decide which areas (like the cafeteria) are open. A lot of the game mechanics and community events depend on synchronized time across all servers.

However, I’m struggling with how to represent in-game time. For example, it might feel odd for the game to display “Christmas” in July IRL. I could avoid labeling in-game months with real-world names (e.g., just display “Day X of Month Y”), but that feels a bit bland.

Does anyone have ideas for handling in-game time in a way that feels immersive but avoids conflicts with real-world timing? Or should I even bother tracking days/months at all?

You can use data stores to get time from start of the server, and use ticks, only thing you need to do from now is to save specific tick into the data store as date and get this tick to convert it back to date and display it

I couldn’t find a fix all solution for this, since even if you use a multiple of the number of days in the year you’d be able to sync christmas day with a christmas day in-game but obviously where multiple years take place over the course of a single in-game year you’re still gonna end up with christmas at scattered points throughout the irl year so what I’d say is either go all in with immersiveness or leave it out altogether.

What I mean is, have in-game events be untied to irl events but have them still occur OR have events in-game be untied to in-game time and tied to irl events. There’s no way to have them be both and only have it occur once in an irl year unless for whatever reason your game only celebrated christmas once every few in game years.

okay this is actually WAY simpler than it seems;

set your current Unix time as a variable ( print(os.time()) in studio command bar ), this will be used as a DiffStamp

now you can get a universal time passed in seconds by doing this:

local Passed = os.time()-DiffStamp

Ex: print(Passed, 's have passed since start');

since you want 1 week to count as 1 in game month, you can do this by finding out how much 1 IRL second is a in game second, which is about 4.29 seconds. ( 1 IRL = 4.29 IN GAME )

Now you need a date where you want your calendar to start, which you can get in https://www.unixtimestamp.com/
for the example i picked Jan 01 1999. ( Unix time can only go as low as Jan 01 1970 )

Then you simply have to subtract the current time with the diff stamp , multiply it by 4.29, and add it to the start time stamp!

local CurrentDate = StartTimeStamp + (os.time()-DiffStamp)*4.29

Final script w/ time stamps to test

local StartTimeStamp = 915166800 -- when you want your calendar to start
local DiffStamp = 1732906300 -- the time you began to track days

local function TimeInSeconds(_time: number)
	return StartTimeStamp + (_time-DiffStamp)*4.29;
end

local function CurrentTimeInSeconds()
	return StartTimeStamp + (os.time()-DiffStamp)*4.29;
end

local test_times = {
	1732906300, -- Starting point
	1732982700, -- 1 day after DiffStamp
	1733482700, -- 60 days after DiffStamp
	1734320300, -- 100 days after DiffStamp
	1765065300, -- 1 year after DiffStamp
	1796700300, -- 2 years after DiffStamp
	1828335300, -- 3 years after DiffStamp
	1898335300, -- 5 years after DiffStamp
	2000000000, -- 10 years after DiffStamp
}

for _, test_time in ipairs(test_times) do
	print(os.date("%Y-%m-%d %H:%M:%S", StartTimeStamp+(test_time-DiffStamp)), '->', os.date("%Y-%m-%d %H:%M:%S", TimeInSeconds(test_time)))
end

Hope you learned something new :blush: ask me any questions if you have any.