I want to sync the time of day and season between all servers for a game. I’m aiming for a system that doesn’t lose track of time when all servers are closed and regularly updates the time for each server every hour or so to ensure correct sync.
The time or season doesn’t need to advance while all servers are off, but I would like it if they could save, so I can end all servers and then open a new server after a few hours and the time/season will still be the same as when I ended all servers.
I can’t use os.time() because the time system is different. I tried using os.time() and converting it to my custom time, but ended up getting a headache trying to deal with math.
The problem is, I have no idea how to do this. I was thinking of using a website with a built-in clock that uses my custom time and getting the servers to request data from this site via webhooks, but I have no clue how to make, code and run a website like that.
So, if anyone would have any ideas, I’m all ears.
Thanks!
My first response was going to be to use os.time(), then translate it to whatever time system you’re using. It’s honestly probably the best way to go about this. But, if you want to get an even bigger headache, you could try sending messages across each server and subscribe to those messages across each server to keep the time synced. Then store the time in a DataStore when servers are off.
Here’s the step by step process you’ll need to follow:
When a server opens, retrieve the time from the dataStore. If there’s not a time that already exists, set it to a default time.
From the first server, use MessagingService to send the correct time to newly opened servers. You can detect when a server opens by forcing a newly opened server to send a message across the MessagingService.
Subscribe to the MessagingService and update each server after x seconds, minutes, etc.
For more info on DataStores, click here.
For more info on MessagingService, click here.
I’d probably just make a JS express server that handles the time, and when a server is created get the time of the server and tick based on that. It might be a few seconds desynced, but that’s a lot better than a few hours based on timezone. If you want it to stop when all servers are gone, have the servers POST to your express servers with the JobID, and when the server closes POST again with the job id removing it from an array. When the array length is zero, stop ticking the time on the server. If you need an example just reply to me and I’ll draft up a crude one.
It doesn’t matter, it can continue or pause. As long as it never resets.
I’ll see what I can do about syncing time with that os.time() trick. And the system I used was using os.time(), but I’m horrible at math and could never get any good readings.
As per the seasons, I remember I managed to get a value between 0 and 1 out of days since the epoch. And 0 was the start of the year, 0.5 was the middle and 1 was the end. Is there any efficient, reliable way I could do this?
But one thing before that, are you basing your in-game seasons on real world days? Because I must mention that not everyone is available the entire day, so there are some seasons that some players will never get to experience due to limited free time.
Anyways, similar to how to find time every ten minutes, you can use almost the same code:
-- 60 * 60 * 24 = 86400
local daysPassed = os.time() / 86400
local secondsSinceToday = os.time() % 86400
local fractionDayPassed = secondsSinceToday / 86400 -- number between 0 and 1 to how much of the (real world) current day has passed.
IGNORE THE BELOW IF YOU DON’T CARE ABOUT THE CURRENT DAY (TO DISPLAY IT)
Also, daysPassed will return since 1970, a long long time ago. If you need it to be, for example, since 2020, you would need to subtract os.time by 6060243652020. I.e. os.time() - 63702720000 (Note: This does not account for leap years)
The season system works off days passed, it’s quite complicated for me. There are 128 days in a year, a season lasts 32 days. So, a player can log in at the same time each day, but the seasons will be different each time because the seasons don’t sync with real-world seasons. They are obviously A LOT shorter.
Should’ve clarified how seasons will work, sorry about that
I’ve already gotten a reliable time system working. Thanks for that!
And thanks for the help, by the way, I greatly appreciate it!
Managed to find out how I did it, turns out I didn’t use a number between 0 and 1. Hard to explain how I did it, but the code was simply DaysPassed - (128 * math.floor(DaysPassed / 128)) which I then used a bunch of bigger than or smaller than statements to determine the season.
So, that’s everything sorted, thanks for you help!