Does my saving data script a good one or is there is a way to improve it

so I have this leaderstats script is it a good one and is my way in saving data a good way also is there is a way to improve it and make it more safety and avoid data lose

ocal DataStoreService = game:GetService("DataStoreService")
local MainDataStore = DataStoreService:GetDataStore("MainDataStore")

game.Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player

	local Wins = Instance.new("IntValue")
	Wins.Name = "Wins"
	Wins.Parent = leaderstats

	local Losses = Instance.new("IntValue")
	Losses.Name = "Losses"
	Losses.Parent = leaderstats

	local Solved = Instance.new("IntValue")
	Solved.Name = "Solved"
	Solved.Parent = leaderstats

	local playerData = MainDataStore:GetAsync(player.UserId)
	if playerData then
		Wins.Value = playerData.Wins
		Losses.Value = playerData.Losses
		Solved.Value = playerData.Solved
	end
	
	game.Players.PlayerRemoving:Connect(function(player)
		MainDataStore:SetAsync(player.UserId, {
			Wins = Wins.Value,
			Losses = Losses.Value,
			Solved = Solved.Value
		})
	end)
end)

Hi! I revised your script, and made it cleaner and easier to edit. Try this:

-- // VARIABLES
-- / Services
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")

-- / Data Store
local dataStore = DataStoreService:GetDataStore(--[[insert name here]])

-- // FUNCTIONS
-- / Creating Instances
local function createFolder(name: string, parent: Instance)
    local folder = Instance.new("Folder")
    folder.Name = name or "Folder"
    folder.Parent = parent -- No 'or' because the parent is already nil.

    return folder
end

local function createInt(name: string, int: number, parent: Instance)
    local intObject = Instance.new("IntValue")
    intObject.Value = int or 0
    intObject.Name = name or "IntValue"
    intObject.Parent = parent

    return intObject
end

-- / Data Store
local function saveData(player: Player)
    local leaderstats = player:FindFirstChild("leaderstats")

    if not leaderstats then return end

    -- Get the data.
    local data = {}

    for _, child in ipairs(leaderstats:GetChildren()) do -- Prevents typing out every value.
        data[child.Name] = child.Value
    end

    -- Save the data.
    local success, reason = pcall(function()
        dataStore:SetAsync(player.UserId, data)
    end)

    if not success then warn(reason) end
end

-- // MAIN
Players.PlayerAdded:Connect(function(player)
    -- Retrieve the player's data.
    local data
    local success, reason = pcall(function()
        data = dataStore:GetAsync(player.UserId)
    end)

    if not success then
        warn(reason)
        
        -- Tell the player to rejoin (data error).

        return
    end

    -- Create the leaderstats (using the data).
    local leaderstats = createFolder("leaderstats")

    createInt("Wins", data.Wins, leaderstats)
    createInt("Losses", data.Losses, leaderstats)
    createInt("Solved", data.Solved, leaderstats)

    leaderstats.Parent = player
end)

Players.PlayerRemoving:Connect(saveData)

game:BindToClose(function() -- In case the game shuts down.
    for _, player in ipairs(Players:GetPlayers()) do
        saveData(player)
    end
end)

I edited the createInt() function.

3 Likes

game:BindToClose() is definitely a good addition

1 Like

Isn’t doing :UpdateAsync() instead of :SetAsync() better?

yea but I don’t really know how to change the setasync with updateasync

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.