I have this script that’ll keep track of the time you spent in-game. The script itself is working fine, but the time spent won’t save properly. All answers appreciated.
local datastore = game:GetService("DataStoreService"):GetDataStore("Time")
-- since the datastore isn't based on the player, only the keys are,
-- there's no reason to define the datastore instead the PlayerAdded event
local joinTimes = {} -- store a table of when players joined
game:GetService("Players").PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder", player)
-- folders are meant for storing stuff, no need to use an intvalue
leaderstats.Name = "leaderstats"
local playTime = Instance.new("IntValue", leaderstats)
playTime.Name = "Time"
local key = player.UserId
local success, data = pcall(datastore.GetAsync, datastore, key)
-- make sure you handle errors properly, otherwise your code will break
if success then -- if it worked,
playTime.Value = data or 0 -- set it to whatever was saved (or 0 if nothing was saved)
joinTimes[player] = {data or 0, tick()} -- keep track of when the player joined and what they had saved
else
warn(data) -- put the error in the console as a warning
-- ... you can do better error handling here too
end
end)
game:GetService("Players").PlayerRemoving:Connect(function(player)
-- when a player leaves,
local key = player.UserId
local success, error = pcall(datastore.IncrementAsync, datastore, math.floor((tick() - joinTimes[player][2])/ 60))
-- add onto the saved data the amount of time between when they joined and now in minutes
if not success then -- if it errors,
warn("UpdateAsync failed for", player, ":", error)
-- retry or whatever error handling you want
end
end)
game:GetService("RunService").Heartbeat:Connect(function()
-- every frame, for every player, update their time played
local now = tick()
for player, times in pairs(joinTimes) do
local leaderstats = player:FindFirstChild("leaderstats")
if leaderstats and leaderstats:FindFirstChild("Time") then
leaderstats["Time"].Value = times[1] + math.floor((now - times[2]) / 60)
-- set their time played to what was saved + how long it's been since they've joined (in min)
end
end
end)
I assume it’s because you’re not using datastores properly. You have to do something like this
local success, err = pcall(function()
visits = visitsDataStore:IncrementAsync(playerKey, 1)
end)
whereas you’re doing
local success, error = pcall(datastore.IncrementAsync, datastore, math.floor((tick() - joinTimes[player][2])/ 60))
I’ve never seen someone do that with a datastore before, so that’s what stood out to me.
This is a helpful article for using datastores.
1 Like
Actually after tweaking the code, I was able to get it to save properly, thanks!
Final code:
local datastore = game:GetService("DataStoreService"):GetDataStore("Minutes")
-- since the datastore isn't based on the player, only the keys are,
-- there's no reason to define the datastore instead the PlayerAdded event
local joinTimes = {} -- store a table of when players joined
game:GetService("Players").PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder", player)
-- folders are meant for storing stuff, no need to use an intvalue
leaderstats.Name = "leaderstats"
local playTime = Instance.new("IntValue", leaderstats)
playTime.Name = "Minutes"
local key = player.UserId
local success, data = pcall(datastore.GetAsync, datastore, key)
-- make sure you handle errors properly, otherwise your code will break
if success then -- if it worked,
playTime.Value = data or 0 -- set it to whatever was saved (or 0 if nothing was saved)
joinTimes[player] = {data or 0, tick()} -- keep track of when the player joined and what they had saved
else
warn(data) -- put the error in the console as a warning
-- ... you can do better error handling here too
end
end)
game:GetService("Players").PlayerRemoving:Connect(function(player)
-- when a player leaves,
local key = player.UserId
--local success, error = pcall(datastore.IncrementAsync, datastore, math.floor((tick() - joinTimes[player][2])/ 60))
local success, err = pcall(function()
datastore:IncrementAsync(key, math.floor((tick() - joinTimes[player][2])/ 60) )
print("successful")
end)
--add onto the saved data the amount of time between when they joined and now in minutes
end)
game:GetService("RunService").Heartbeat:Connect(function()
-- every frame, for every player, update their time played
local now = tick()
for player, times in pairs(joinTimes) do
local leaderstats = player:FindFirstChild("leaderstats")
if leaderstats and leaderstats:FindFirstChild("Minutes") then
leaderstats["Minutes"].Value = times[1] + math.floor((now - times[2]) / 60)
-- set their time played to what was saved + how long it's been since they've joined (in min)
end
end
end)
4 Likes