Why my script for DataStore doesn't work?

I tried many ways to do datastore, I Enable Api Services, I watch many tutorial, I read Roblox Documentation but still doesn’t. Can anyone help me?

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

local CASH_DATA_STORE_NAME = "PlayerCashData"

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

	local Cash = Instance.new("NumberValue")
	Cash.Name = "Cash"
	Cash.Value = 0
	Cash.Parent = leaderstats
end)

local function savePlayerData(player)
	local cashValue = player:FindFirstChild("leaderstats"):FindFirstChild("Cash")
	if cashValue then
		local dataStore = DataStoreService:GetDataStore(CASH_DATA_STORE_NAME)
		local key = "Player_" .. player.UserId

		local success, error = pcall(function()
			dataStore:SetAsync(key, cashValue.Value)
		end)

		if not success then
			warn("Error saving player data for " .. player.Name .. ": " .. error)
		end
	end
end

Players.PlayerRemoving:Connect(function(player)
	savePlayerData(player)
end)



3 Likes

I have had this issue before.

The reason this doesn’t work is because the game closes before the data saves.
An easy fix is to tell the game to delay 5 seconds before it shuts down.

Put this before any functions in your script:

game.BindToClose:Connect(function() --Runs the code inside before the game closes.
    task.wait(5)
end)
1 Like

something doesn’t work, I got an error:

ServerScriptService.SaveDataStore:19: attempt to index function with ‘Connect’

1 Like

Oh, my mistake. The BindToClose isn’t a proper function.

Try this:

game:BindToClose(function(
    task.wait(5)
end)
1 Like

can you say me more detailed whe I have to put this part of code?

1 Like

You can put it anywhere, but in my opinion I’d put it above every other function.

game:BindToClose(function()
    task.wait(5)
end)

--All other functions go below.
2 Likes

Still doesn’t work :confused: , idk why data store doesn’t work for me!

1 Like

Then it’s something with the actual data saving.

1 Like

You are saving the data, but you are not loading the data when the player joins

1 Like

Replace this part:

game:BindToClose(function(
    task.wait(5)
end)

with this corrected version:

game:BindToClose(function()
    task.wait(5)
end)

this removes the syntax error

Also instead of relying solely on game:BindToClose , you should consider saving player data at regular intervals, like when they make changes to their cash.

here’s how you can modify the savePlayerData function to save data more frequently:

local function savePlayerData(player)
    local cashValue = player:FindFirstChild("leaderstats"):FindFirstChild("Cash")
    if cashValue then
        local dataStore = DataStoreService:GetDataStore(CASH_DATA_STORE_NAME)
        local key = "Player_" .. player.UserId

        local success, error = pcall(function()
            dataStore:SetAsync(key, cashValue.Value)
        end)

        if not success then
            warn("Error saving player data for " .. player.Name .. ": " .. error)
        end
    end
end

-- Call savePlayerData whenever the player's cash changes
-- For example, you can put this in a script that listens to a player's actions
Cash.Changed:Connect(function(newValue)
    savePlayerData(player)
end)

-- Also save data when the player is leaving
Players.PlayerRemoving:Connect(function(player)
    savePlayerData(player)
end)
1 Like

I tried this and it completely works, because I added the :BindToClose(), it’s something with his script that doesn’t do data saving correctly.

Making it change every time the Cash value changes could be consistent, but if you’re continuosly getting cash, then that can be a problem.

You might say, “just don’t get lots of cash at a time, to slow down the data store queue”, but that’s a big limitation. I’d save data every time the player leaves the game.

2 Likes

Oh you’re right, ig we should just focus on when the player leaves.

this might work

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

local CASH_DATA_STORE_NAME = "PlayerCashData"

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

    local Cash = Instance.new("NumberValue")
    Cash.Name = "Cash"
    Cash.Value = 0
    Cash.Parent = leaderstats
end)

local function savePlayerData(player)
    local cashValue = player:FindFirstChild("leaderstats"):FindFirstChild("Cash")
    if cashValue then
        local dataStore = DataStoreService:GetDataStore(CASH_DATA_STORE_NAME)
        local key = "Player_" .. player.UserId

        local success, error = pcall(function()
            dataStore:SetAsync(key, cashValue.Value)
        end)

        if not success then
            warn("Uh-oh, we couldn't save " .. player.Name .. "'s data: " .. error)
        end
    end
end

Players.PlayerRemoving:Connect(function(player)
    savePlayerData(player)
end)

game:BindToClose(function()
    for _, player in pairs(Players:GetPlayers()) do
        savePlayerData(player)
    end
end)
1 Like

Is it correct version of the script?

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

local CASH_DATA_STORE_NAME = "PlayerCashData"

game:BindToClose(function()
	task.wait(5)
end)

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

	local Cash = Instance.new("NumberValue")
	Cash.Name = "Cash"
	Cash.Value = 0
	Cash.Parent = leaderstats
	
	game:BindToClose(function()
		task.wait(5)
	end)
	
	local function savePlayerData(player)
		local cashValue = player:FindFirstChild("leaderstats"):FindFirstChild("Cash")
		if cashValue then
			local dataStore = DataStoreService:GetDataStore(CASH_DATA_STORE_NAME)
			local key = "Player_" .. player.UserId

			local success, error = pcall(function()
				dataStore:SetAsync(key, cashValue.Value)
			end)

			if not success then
				warn("Error saving player data for " .. player.Name .. ": " .. error)
			end
		end
	end

	-- Call savePlayerData whenever the player's cash changes
	-- For example, you can put this in a script that listens to a player's actions
	game:BindToClose(function()
		task.wait(5)
	end)
	
	Cash.Changed:Connect(function(newValue)
		savePlayerData(player)
	end)
	
	game:BindToClose(function()
		task.wait(5)
	end)
	
	-- Also save data when the player is leaving
	Players.PlayerRemoving:Connect(function(player)
		savePlayerData(player)
	end)
end)


1 Like

Why did you put BindToClose() twice?

Remove the one that’s inside the PlayerAdded function.

1 Like
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")

local CASH_DATA_STORE_NAME = "PlayerCashData"
local dataStore = DataStoreService:GetDataStore(CASH_DATA_STORE_NAME)

local function savePlayerData(player)
	local cashValue = player:FindFirstChild("leaderstats"):FindFirstChild("Cash")
	if cashValue then
		local key = "Player_" .. player.UserId

		local success, err = pcall(function()
			dataStore:SetAsync(key, cashValue.Value)
		end)

		if not success then
			warn("Error saving player data for " .. player.Name .. ": " .. err)
		end
	end
end

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

	local Cash = Instance.new("NumberValue")
	Cash.Name = "Cash"
	Cash.Value = 0
	Cash.Parent = leaderstats
	
	local key = "Player_" .. player.UserId
	
	local data
	local success, err = pcall(function()
		data = dataStore:GetAsync(key)
	end)
	
	if success then
		Cash.Value = data
	end
	
	Cash.Changed:Connect(function()
		savePlayerData(player)
	end)
end)

Players.PlayerRemoving:Connect(savePlayerData)

game:BindToClose(function()
	task.wait(3)
end)
1 Like

Idk, It still doesn’t work. Can you test this script on our own place so I can be sure does I have problem or script.

1 Like

also doesn’t work :confused: does it work for you?

1 Like

Let me give a template.

local DSS = game:GetService("DataStoreService")
local dataStores = {
    Cash = DSS:GetDataStore("CashData")
}

game:BindToClose(function()
    task.wait(5)
end)

game.Players.PlayerAdded:Connect(function(player)
    
    local leaderstats = Instance.new("Folder", player)
    leaderstats.Name = "leaderstats"
    
    local cash = Instance.new("IntValue", leaderstats)
    cash.Name = "Cash"
    cash.Value = dataStores.Cash:GetAsync(tostring(player.UserId)) or 0
    
end)

game.Players.PlayerRemoving:Connect(function(player)
    if player:FindFirstChild("leaderstats") then
        dataStores.Cash:SetAsync(tostring(player.UserId), player.leaderstats.Cash.Value)
    end
end)

To give yourself cash during tests, run this in your console (F9):

game.Players.username.leaderstats.Cash.Value = 0

It’s working perfectly fine for me, are you changing the value through the server though?

You should use pcall() when saving or loading data