What methods can I use as opposed to the only terrible method I know of logging time?
-- No tabbing because this was typed on mobile
local Hours, Minutes = 0, 0
while wait(60) do
if Minutes == 59 then
Hours = Hours + 1; Minutes = 0
else
Minutes = Minutes + 1
end
end
Ideally, I want to log how many hours and minutes someone spends playing a game. It has to be data stored for logging and time only goes when they play. If they leave in the middle of completing a minute played, they have to go back to spend a full minute to increment that data.
Get tick when they join and tick when they leave and subtract the two to get how many seconds they were ingame. You can format the seconds afterwards however you want.
Is the way to go.
Just check the time difference when they join and update it when they leave. Maybe throw in some autosaves in there to just to be safe
To put some code to what they’re saying, here’s an example. When the player enters, store the current time in a table, linked to the player. When the player leaves, calculate the time it has been since the player entered:
local timeTrack = {}
function PlayerAdded(player)
-- Take note of when the player started playing:
timeTrack[player] = tick()
end
function PlayerRemoving(player)
local start = timeTrack[player]
timeTrack[player] = nil
-- Calculate time played:
local timePlayed = tick() - start
-- Save 'timePlayed' somewhere
end
game.Players.PlayerAdded:Connect(PlayerAdded)
game.Players.PlayerRemoving:Connect(PlayerRemoving)
Note: In the case of a server closing, you might also want to run these calculations on game close. However, the PlayerRemoving event might fire still, but I’m not sure. Maybe someone else knows?
Generally, all the answers above have been helpful (except one - I’m not looking for methods I already am aware of), but they don’t seem to be too fulfilling.
Function:
Gui that players can open and see how much time they’ve played for; Hours and Minutes
The Gui updates when either stat increments
When players leave, their time logged saves and they can come back to continue it
In the end, I find myself coming back to that horrid while loop to check the elapsed time. I better understand what to do to check time as opposed to adding to two variables, but the rest of the question remains unanswered.
This has been answered by several users above. Crazyman32 has provided you with some code (you’ll need to save the logged time in a datastore when they leave, and load it when PlayerAdded fires).
There seem to be two things here: (1) checking time played in real time; and (2) formatting seconds into hours and minutes.
As for (1), see below.
As for (2), you can either use os.date("*t", playtime_in_seconds) and read .min and .hour from the table that is returned (subtract 1 from the hour), or you can do a floor division as follows: minutes = math.floor(seconds / 60) hours = math.floor(seconds / 3600)
There are several ways you could do this. A naive approach would be to fire a RemoteEvent every second to update each client. The better way would be to tell the client what their saved playtime is when they join. From then, the client can keep a local record of it and just add a second every second. Display this on the GUI.
I would recommend granularization by 30 or 60 second increments if you’re pushing the data into Google Analytics or similar, since it makes it a lot easier to parse.
You need to take into account and filter for fast “bounces” in whatever collection you’re doing. A lot of people enter a place and almost immediately leave. You still want to track this but it should be distinguishable from the rest of your data.
Generally, for what you’re looking for, doing tick() when the player joins and store it in a table suffices, but seen as to how you don’t want to keep seconds, but rather just the minutes (so that the player must redo the minute as you stated), you can do a slight tweaking on the final tick() - start subtraction.
To keep just the minutes and no second, but also not increase the minute when it shouldn’t be, you can resort to modulus.
I know you know what modulus is, but since some users don’t know (people who could be reading this post!), here’s a quick explanation:
Modulus in Lua is represented by the symbol % and is a mathematical operator.
Modulus takes the division of two numbers and gets the remainder.
As such, 4 % 3 equals 1, while 6 % 3 equals 0.
This is useful in this case, because we can then format the minutes to not be ceiled or floored!
As such, we end up with this:
local TotalSeconds = tick() - initial -- initial being the first tick() set on PlayerAdded
local TotalMinutes = (TotalSeconds - TotalSeconds % 60) / 60
This gives us a nice, clean amount of minutes without any sort of ceiling or flooring!
Here’s how it works: TotalSeconds % 60 gives us the remainder seconds past a minute TotalSeconds - TotalSeconds % 60 gives us the clean amount of seconds equivalent of the minute (modulus is operated first – for example, 128 seconds would become 120) (TotalSeconds - TotalSeconds % 60) / 60 divides the amount of seconds by the amount of seconds in a minute, giving us a precise minutes value!
You can apply the same logic to get an hour, e.g.:
local TotalSeconds = tick() - initial -- initial being the first tick() set on PlayerAdded
local TotalMinutes = (TotalSeconds - TotalSeconds % 60) / 60
local TotalHours = (TotalMinutes - TotalMinutes % 60) / 60
Edit: oops just realized how old it is – might still be useful for users searching the forums
Yeah. This post was made 2 years ago when I was a medicore programmer and had silly misunderstandings of API and vollied valid responses, not sure how you found it that far back enough to give a response. I’ve long since found out how to do this - extremely simple, in fact - and don’t even need it now anyway.
I don’t find tick appropriate in this case. I prefer to use os.time. The decimals from tick aren’t relevant to me, so might as well just use the standard method that returns the amount of seconds since the UNIX Epoch (tick is a Roblox global).