Gear only saves but not cash

im trying to learn datastores on how to save tools and cash. but i cannot save cash. tool actualy saves btw. ofc yes. i tried tested it by changing value from server. and it doesn’t seem to work, there aren’t any error or anything. so i created part that gives cash when clicked but doesn’t seem to work neither :confused:. i would love to have help

here is my code

---VARIABLES---

local datastore = game:GetService("DataStoreService")
local ds = datastore:GetDataStore("MyDatastore")
local itemfolder = game:GetService("ServerStorage"):WaitForChild("Items")
local plrs = game:GetService("Players")

-----------------------------------------------------------------------------

local data = {}


plrs.PlayerAdded:Connect(function(plr)--fires if player joins--
	
	--creates leaderstats--
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	local val = Instance.new("IntValue")
	val.Parent = leaderstats
	val.Name = "cash"
	
	--atempt--
	local attempt = 1
	local success;
	local plrdata;
	
	--catches error--
	repeat 
		success, plrdata = pcall(function() return ds:GetAsync(plr.UserId)end)
		
		attempt += 1
		if not success then
			warn(plrdata)
			task.wait(3)
		end
		
	until attempt == 5 or success
	
	--if it's sucessfull--
	if success then
		
		print(plrdata)
		print("sucessfully loaded!")
		
		--sets up data--	
		data[plr.UserId] = plrdata
		if data[plr.UserId] then
			for i, savditm in pairs(data[plr.UserId]) do
				local itm = itemfolder:FindFirstChild(savditm)
				if itm then
					itm:Clone().Parent = plr.Backpack
				end
			end
		end
		
	--if doesn't have any data (that mean player is new)--
	if not plrdata then
			warn("assigning data")
			plrdata = {
				["Invetory"] = {},
				["Cash"] = 0
			}
	end
	--kicks player if it's a failure--
	else
		warn("not able to get data")
		plr:Kick("srryyy data not loaded correctly")
	end
	
	--leaderstat value will match to data cash value--
	val.Value = data[plr.UserId].Cash
	val.Changed:Connect(function(value)
		data[plr.UserId].Cash = val.Value
	end)
	
	leaderstats.Parent = plr
end)

--inserts item to table when player is about to leave--
local function InsertItem(plr : Player)
	if plr.Character then
		for i, itm in pairs(plr.Character:GetChildren()) do
			if itm and itm:IsA("Tool") and not table.find(data[plr.UserId],itm.Name) then
				table.insert(data[plr.UserId],itm.Name)
				print("item added")
			end
		end

		for i, itm in pairs(plr.Backpack:GetChildren()) do
			if itm and itm:IsA("Tool") and not table.find(data[plr.UserId],itm.Name) then
				table.insert(data[plr.UserId],itm.Name)
				print("item added")
			end
		end
	end
end

--function that triggers either if server will end or if player leaves--
local function dataSave(plr)
	local attempt = 1
	local success;
	local err;
	
	InsertItem(plr)
	
	--catches error and saves--
	repeat
		success, err = pcall(function() ds:SetAsync(plr.UserId,data[plr.UserId]) end)

		attempt += 1
		if not success then
			warn(err)
			task.wait(3)
		end
	until success or attempt == 5
	if success then
		print("sucessfuly saved!")
		print(data)
	else
		warn("not able to save data")
	end
end



--connecting function to playerremoving event--
plrs.PlayerRemoving:Connect(dataSave)

--if game is about to shut down--
game:BindToClose(function()
	--for ipairs player because it's quicker--
	for i, plr in ipairs(plrs:GetPlayers()) do
		--saves data before server shutdown--
		dataSave(plr)
	end
	print("saved data before closing")
end)


and yes… api is enabled. it’s inside serverscriptservice and it’s not a local script

trying to add cash


image

and… it doesn’t work…

i will be very happy if someone would help me out! cheers!

The game might not have enough time to save the data before it shuts down. Try modifying your BindToClose() function:

local runService = game:GetService("RunService") --this line goes at the top of the script
game:BindToClose(function()
    if runService:IsStudio() then task.wait(5) return end --PlayerRemoving will always fire in studio
    for i, plr in ipairs(plrs:GetPlayers()) do
        dataSave(plr)
    end
    task.wait(5)
end)

This should work, I just fixed some minor issues, went through the script and made sure everything is fine.

---VARIABLES---

local datastore = game:GetService("DataStoreService")
local ds = datastore:GetDataStore("MyDatastore2")
local itemfolder = game:GetService("ServerStorage"):WaitForChild("Items")
local plrs = game:GetService("Players")

-----------------------------------------------------------------------------

local data = {}


plrs.PlayerAdded:Connect(function(plr)--fires if player joins--

	--creates leaderstats--
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = plr
	
	local val = Instance.new("IntValue")
	val.Parent = leaderstats
	val.Name = "cash"

	--atempt--
	local attempt = 1
	local success;
	local plrdata;

	--catches error--
	repeat 
		success, plrdata = pcall(function() return ds:GetAsync(plr.UserId)end)

		attempt += 1
		if not success then
			warn(plrdata)
			task.wait(3)
		end

	until attempt == 5 or success

	--if it's sucessfull--
	if success then

		print(plrdata)
		print("sucessfully loaded!")

		--sets up data--	
		data[plr.UserId] = plrdata
		val.Value = data[plr.UserId].Cash
		
		if data[plr.UserId] then
			for i, savditm in pairs(data[plr.UserId].Inventory) do
				local itm = itemfolder:FindFirstChild(savditm)
				if itm then
					itm:Clone().Parent = plr.Backpack
				end
			end
		end

		--if doesn't have any data (that mean player is new)--
		if not plrdata then
			warn("assigning data")
			plrdata = {
				["Inventory"] = {},
				["Cash"] = 0
			}
		end
		--kicks player if it's a failure--
	else
		warn("not able to get data")
		plr:Kick("srryyy data not loaded correctly")
	end

	--leaderstat value will match to data cash value--
	
	val:GetPropertyChangedSignal("Value"):Connect(function()
		data[plr.UserId].Cash = val.Value
	end)

	
end)

--inserts item to table when player is about to leave--
local function InsertItem(plr : Player)
	if plr.Character then
		for i, itm in pairs(plr.Character:GetChildren()) do
			if itm and itm:IsA("Tool") and not table.find(data[plr.UserId],itm.Name) then
				table.insert(data[plr.UserId].Inventory,itm.Name)
				print("item added")
			end
		end

		for i, itm in pairs(plr.Backpack:GetChildren()) do
			if itm and itm:IsA("Tool") and not table.find(data[plr.UserId],itm.Name) then
				table.insert(data[plr.UserId].Inventory,itm.Name)
				print("item added")
			end
		end
	end
end

--function that triggers either if server will end or if player leaves--
local function dataSave(plr)
	local attempt = 1
	local success;
	local err;

	InsertItem(plr)
	--catches error and saves--
	repeat
		success, err = pcall(function() ds:SetAsync(plr.UserId,data[plr.UserId]) end)

		attempt += 1
		if not success then
			warn(err)
			task.wait(3)
		end
	until success or attempt == 5
	if success then
		print("sucessfuly saved!")
		print(data)
	else
		warn("not able to save data")
	end
end



--connecting function to playerremoving event--
plrs.PlayerRemoving:Connect(dataSave)

--if game is about to shut down--
game:BindToClose(function()
	--for ipairs player because it's quicker--
	for i, plr in ipairs(plrs:GetPlayers()) do
		--saves data before server shutdown--
		dataSave(plr)
	end
	print("saved data before closing")
end)

its your same script but I fixed minor errors I found. Also changed the datastorekey so its a new datastore you can try on

sorry for being late because i were asleep but i will try!

ServerScriptService.MoneySave:49: attempt to index nil with ‘Cash’

strange… it prints out error. did you test it?