Needing help with leaderstats!

First time posting on the devforum so sorry if i done anything wrong.
I am not great at writing datastores, though hopefully this script works out :smiley:

local players  = game:GetService("Players")
local datastoreservice = game:GetService("DataStoreService")

local allTimeKillsDataStore = datastoreservice:GetDataStore("All Time Kills")
local servershuttingdown = false

local function newdata(player : player)
        local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player

	local playerKills = Instance.new("NumberValue")
	playerKills.Name = "Kills"
        playerKills.Value = 0
	playerKills.Parent = leaderstats

	local playerAllTimeKills = Instance.new("NumberValue")
	playerAllTimeKills.Name = "All Time Kills"
        playerAllTimeKills.Value = 0
	playerAllTimeKills.Parent = leaderstats
end

local function fetchdata(player : Player)
        -- Assuming by your script, your key is the player userid
        local key = player.UserId
        local leaderstats = player.leaderstats

        local data = nil

        local retries = 0         
        local success, err do     
                repeat
                       success, err = pcall(function()
                                local data = allTimeKillsDataStore:GetAsync(key)
                       end)

                       if not success then
                              task.wait(10)
                              retries += 1
                       end
                until success or retries > 2   -- Set this to the amount you want
        end

        if not success then   -- There are other ways to do this like storing it in a table
                local dontsave = Instance.new("BoolValue")    -- We can let the player still play
                dontsave.Name = "dontsave"                            -- But their data wont save
                dontsave.Parent = player                                   -- Incase if any data is already stored
        else
                if data then
                        leaderstats["All Time Kills"].Value = data
                end  -- If there was no data, the value of All Time Kills is already 0
        end 

end

local function savedata(player : Player)
        local dontsave = player:FindFirstChild("dontsave")
        if dontsave then
               return
        end

        local key = player.UserId
        local leaderstats = player.leaderstats
        local allTimeKills = leaderstats.allTimeKills.Value

        local success, err do     
                repeat
                       success, err = pcall(function()
                                local data = allTimeKillsDataStore:SetAsync(key, allTimeKills)
                       end)

                       if not success then
                              task.wait(10)
                              retries += 1
                       end
                until success or retries > 2   -- Set this to the amount you want
        end

        if not success then 
                print("Failed")
                warn(err) 
        end
end

local function onServerShutdown()   -- Ensures that all player data is saved before server shutdown
        local MainThread = coroutine.running()  -- Gets the current thread
	local ThreadsRunning = 0
	for index, player in pairs(Players:GetChildren()) do
		local savingDataFunc = coroutine.wrap(function()
			savedata(player)
			ThreadsRunning -= 1
			if ThreadsRunning == 0 then
				coroutine.resume(MainThread)   -- Continues the session after all data is saved
			end
		end)
		ThreadsRunning += 1
		savingDataFunc(player)
	end
	if ThreadsRunning > 0  then  
		coroutine.yield()   -- Prevents the session from shutting down
	end
end

local function onPlayerAdded(player)
       newdata(player)
       fetchdata(player)
end

local function onPlayerRemoving(player : Player)
        -- if RunService:IsStudio() == true then return end
        if servershuttingdown then return end  -- Prevents the game from saving data twice
        savedata(player)
end

players.PlayerAdded:Connect(onPlayerAdded)
players.PlayerRemoving:Connect(onPlayerRemoving)

game:BindToClose(function()
	-- if RunService:IsStudio() == true then return end
	servershuttingdown = true
	onServerShutdown()
end)




I would personally use a module to store in all of the functions since it makes it more organized. Sorry if the spot is improperly indented or there are errors in here :sweat_smile: you might have to tweak it incase something doesnt work

1 Like