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
01 | local DSService = game:GetService( 'DataStoreService' ):GetDataStore( 'Stats' ) |
02 | function WaitForChildren(obj, timeout, ...) |
05 | obj = obj:WaitForChild(t [ i ] , timeout) |
06 | if not obj then return nil end |
10 | game.Players.PlayerAdded:connect( function (plr) |
11 | local skillpoints = WaitForChildren(plr, 5 , "Leaderstats" , "Skillpoints" ) |
13 | if not skillpoints then print (plr, "did not receive Leaderstats.Skillpoints" ) return end |
14 | local uniquekey = 'id-' ..plr.userId |
19 | success, value = pcall ( function () return DSService:GetAsync(uniquekey) end ) |
20 | if success then break end |
22 | print ( "Could not retrieve data for" , plr, ", error message:" , value) |
29 | skillpoints.Value = value |
33 | local save = WaitForChildren(plr, 5 , "PlayerGui" , "Options" , "Frame" , "Save" ) |
36 | save.MouseButton 1 Click:connect( function () |
37 | if saveDB then return end |
38 | local success, errorMsg = pcall ( function () |
39 | DSService:SetAsync(uniquekey, skillpoints.Value) |
44 | save.Text = "Error: " .. errorMsg |
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.