Hello! Without giving away too many details, I am working on a simple game that progresses globally. The game starts out at level 1, and upon completion will start level 2, etc. Progression is in sync across all servers so everyone playing the game is working collaboratively on the same level.
Here is the help I need:
I want to keep track of how long it takes to complete a level, by recording the time it took to complete that specific level.
Do I:
Keep track of time elapsed by capturing an os.date() when the level opens, and simply tracking how long has elapsed since that point in time (Problem with this is lets assume nobody is playing the game, that time where nobody is actively working on that level will count)
Keep track of how much time has passed since original date, assuming at least one person was actively working on that level (Problem with this is a lack of knowledge about how to track and keep this number in sync with all servers)
Keep track of each individual players time while working on that level, and display collectively how much time it has taken to complete that level. (Eg: Player1 was on for 30 minutes and Player2 was on for 15 minutes so total time spent on level would be 45 minutes)
I was thinking you could use os.date() when the level opens then subtract that with os.date() when the level is finished or when every player has left. Then, you can store that delta in DataStoreService or something along with whether or not the level was finished. If the level was not finished, then the next delta will be added onto the previous delta.
This is the idea I was currently aiming for but ran into some complications:
Assume multiple servers open several minutes apart, how do I get the latest value to all servers? I know I can use MessagingService but am unsure how to track which server has been alive the longest, and using the data from that server to update all the others.
I had an idea to simply update the Datastore every few minutes, and just accepting the fact all servers could be a few minutes out of sync. Each server would ultimately update the DataStore when it closes, assuming its value is larger than the one already stored. But then I will run into rate limits for specific keys within a Datastore, would I not?
Restart my thinking. You should collect data on every player and how long they were playing. You should also have a .Idled check to not include players that are AFK (and subtract 2 minutes since that’s how long it takes for .Idled to fire). This way, you can tell how many players were playing at the time and their lengths. Then, you could add them all up to get a “this is how much time x number of players tried to solve this puzzle”.
The only problem I don’t understand with your data is not every player is equal. There will be players who walk around looking at stuff and not actually solving anything meanwhile there can be speed demons or a collective group of task solvers that randomly happen upon your game and solve it extremely fast.
I have decided to ultimately collect all 3 data points, but starting with data point 2.
Here is how im currently doing it:
A server starts and obtains the latest available time from a Datastore. In addition to this, it will broadcast its current time (initial time + new time) to all servers every 15 seconds. Since the time spent on the level is only saved when the server closes, to prevent throttling on that one key across all game servers, it is possible that a server will begin and obtain now-outdated time information. In this case, it compares its current value to the values received from other servers and will adjust its time accordingly. All of this also adjusts with the Time stamp attached to the message and the time it took to send the message is added to the value
So I guess on server startup there is room for the time to be up to 15 ish seconds off actual time, and will automatically adjust once it receives a message from other servers.