There are a number of problems with your script.
- You do not use the player's character, but wait for it anyway
- You do not wait for the leaderboard script to insert the "Leaderstats" object into the player. You should use
WaitForChild in that case (with a timeout in-case something goes wrong). Since you're accessing multiple children, it may be worth using the function I wrote below.
- You call GetAsync twice unnecessarily. You should assign the result to a variable so you only need to call GetAsync once.
- You do not implement debounce on the save feature. A person could rapidly click to save repeatedly, wasting your server's requests.
- You must put datastore commands in
pcall as they may error
local DSService = game:GetService('DataStoreService'):GetDataStore('Stats')
function WaitForChildren(obj, timeout, ...)
local t = {...}
for i = 1, #t do
obj = obj:WaitForChild(t[i], timeout)
if not obj then return nil end
end
return obj
end
game.Players.PlayerAdded:connect(function(plr)
local skillpoints = WaitForChildren(plr, 5, "Leaderstats", "Skillpoints")
if not skillpoints then print(plr, "did not receive Leaderstats.Skillpoints") return end
local uniquekey = 'id-'..plr.userId
local success, value
for i = 1, 5 do
success, value = pcall(function() return DSService:GetAsync(uniquekey) end)
if success then break end
if i == 5 then
print("Could not retrieve data for", plr,", error message:", value)
value = nil
break
end
wait(15)
end
if value then
skillpoints.Value = value
end
local save = WaitForChildren(plr, 5, "PlayerGui", "Options", "Frame", "Save")
if save then
local saveDB = false
save.MouseButton1Click:connect(function()
if saveDB then return end
local success, errorMsg = pcall(function()
DSService:SetAsync(uniquekey, skillpoints.Value)
end)
if success then
save.Text = 'Saved'
else
save.Text = "Error: " .. errorMsg
end
saveDB = true
wait(2)
saveDB = false
save.Text = 'Save'
end)
end
end)
I also recommend against allowing players to save every 2 seconds. Per player, you get a request every 6 seconds (and a few more for the server), meaning that it's only safe to save every 6 seconds on average (per player). Though, if you don't expect players to abuse this, it's probably okay.
2 comments
Because you're not saving it as a table. Just do DSService:GetAsync(uniquekey) and see if that works.
Thanks! it works now, however the script loads too fast to the point where the making of the values in the other script are slow, and when it says "Leaderstats is not apart of Player" but I just added a wait(10) above the GetAsync thing and now it works fine. Is there a better way for it to wait?