Can you help me fix my leaderstats not saving?

I’m currently trying to make a leaderstats system, but there’s currently no way to save the points. I’m confused, and I’ve been trying to make a way to save for what feels like ages.

Please help me :frowning:

SCRIPT:


local DataStoreService = game:GetService("DataStoreService")
local playerDataStore = DataStoreService:GetDataStore("PlayerData")

game.Players.PlayerRemoving:Connect(function(player)
    -- Save the player's leaderstats to the data store
    local success, error = pcall(function()
        playerDataStore:SetAsync(player.UserId .. "_leaderstats", player.leaderstats)
    end)
    if not success then
        warn("Failed to save player data: " .. error)
    end
end)

game.Players.PlayerAdded:Connect(function(player)
    -- Load the player's leaderstats from the data store
    local success, leaderstats = pcall(function()
        return playerDataStore:GetAsync(player.UserId .. "_leaderstats")
    end)
    if success and leaderstats then
        leaderstats.Parent = player
    end
end)
1 Like

Your issue is that you are trying to save an instance, which you cannot do.
You have to pass a table or a value through to save.

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

--> Data Store
local DataStore = DataStoreService:GetDataStore("PlayerData")

--> Functions
local function PlayerAdded(player: Player)
    --> Create Players Leaderstats
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	
	local coins = Instance.new("NumberValue")
	coins.Name = "Coins"
	
	coins.Parent = leaderstats
	
	leaderstats.Parent = player
	
    --> Load Players Data
	local succ, data = pcall(function()
		return DataStore:GetAsync(player.UserId)
	end)
	
	if succ and data ~= nil then
		coins.Value = data["Coins"]
	end
end

--> Save The Players Data
local function PlayerRemoving(player: Player)
    --> Get Players Leaderstats
	local leaderstats = player:FindFirstChild("leaderstats")
	local coins = leaderstats:FindFirstChild("Coins")
	
	local DataTable = {
		["Coins"] = coins.Value,
	}
	
    --> Save Players Data
	pcall(function()
		DataStore:SetAsync(player.UserId, DataTable)
	end)
end

for _, v in pairs(Players:GetPlayers()) do
	PlayerAdded(v)
end

Players.PlayerAdded:Connect(PlayerAdded)
Players.PlayerRemoving:Connect(PlayerRemoving)

You should also look at the documentation for Data Stores

1 Like

For some reason this script still doesn’t work. I have no Idea if I did something wrong, but I don’t think I did.

I put the script inside of ServerScriptService, and changed the names to Gold instead of Coins. I tried it out, and the leaderstats worked, but the Data Store didn’t.

I also made a backup of your script and tried it out completely unchanged. That also didn’t work. Thank You for trying to help me though! :slight_smile:

Are you testing it in studio? If you are make sure studio has access to Data Stores in your game settings.

1 Like

Wait let me load studio i got a module where u just put the name and starter value
it automaticly make it datastore and saves when updated

This, and make sure you have a bind to close feature, or it wont save sometimes in studio or if the last player I’m a server leaves.

If Gold is the only value you’d like to save then you can use this:

local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

local playerDataStore = DataStoreService:GetDataStore("PlayerData")

local function onPlayerAdded(player)
	local success, value = xpcall(playerDataStore.GetAsync, warn, playerDataStore, player.UserId.."_leaderstats")

	if success then
		local leaderstats = Instance.new("Folder")
		leaderstats.Name = "leaderstats"
		leaderstats.Parent = player

		local Gold = Instance.new("IntValue")
		Gold.Name = "Gold"

		if value then
			Gold.Value = value
		end

		Gold.Parent = leaderstats
	end
end

local function onPlayerRemoving(player)
	local leaderstats = player:FindFirstChild("leaderstats")

	if leaderstats then
		xpcall(playerDataStore.SetAsync, warn, playerDataStore, player.UserId.."_leaderstats", leaderstats.Gold.Value)
	end
end

if RunService:IsStudio() then
	game:BindToClose(function()
		task.wait(1)
	end)
else
	game:BindToClose(function()
		local x, y = 0, 0

		local spawn = task.spawn
		local wait = task.wait

		local function onBindToClose(player)
			onPlayerRemoving(player)

			y += 1
		end

		for _, player in Players:GetPlayers() do
			x += 1

			spawn(onBindToClose, player)
		end

		repeat wait(0) until y == x
	end)
end

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

But if in the future you’d like to save more values you’ll need to do this instead:

local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

local playerDataStore = DataStoreService:GetDataStore("PlayerData")

local function onPlayerAdded(player)
	local success, data = xpcall(playerDataStore.GetAsync, warn, playerDataStore, player.UserId.."_leaderstats")

	if success then
		local leaderstats = Instance.new("Folder")
		leaderstats.Name = "leaderstats"
		leaderstats.Parent = player

		local Gold = Instance.new("IntValue")
		Gold.Name = "Gold"

		local Example = Instance.new("IntValue")
		Example.Name = "Example"

		if data then
			Gold.Value = data.Gold
			Example.Value = data.Example
		end

		Gold.Parent = leaderstats
		Example.Parent = leaderstats
	end
end

local function onPlayerRemoving(player)
	local leaderstats = player:FindFirstChild("leaderstats")

	if leaderstats then
		xpcall(playerDataStore.SetAsync, warn, playerDataStore, player.UserId.."_leaderstats", {
			Gold = leaderstats.Gold.Value,
			Example = leaderstats.Example.Value
		})
	end
end

if RunService:IsStudio() then
	game:BindToClose(function()
		task.wait(1)
	end)
else
	game:BindToClose(function()
		local x, y = 0, 0

		local spawn = task.spawn
		local wait = task.wait

		local function onBindToClose(player)
			onPlayerRemoving(player)

			y += 1
		end

		for _, player in Players:GetPlayers() do
			x += 1

			spawn(onBindToClose, player)
		end

		repeat wait(0) until y == x
	end)
end

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

Although for both scripts to work you must make sure that:

  • It’s a server Script
  • You have Studio access to API services enabled
  • You’re testing in a place that’s published to Roblox
  • You change the values while in server mode when play-testing (there should be a green border around the viewport if you have the latest version of Studio installed)
  • You change the values within server scripts during actual gameplay

I knew this DataStore template script I made would come in handy :sweat_smile:

2 Likes

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