Help with Datastores (No Leaderboard)

Hi devforum! I’m working on a cash system for my game, using this tutorial.

I need help reformatting the code to work with my system. Everything prints fine, but the store just doesn’t change in any way when i gain money, leave, and rejoin. I might be stupid. Who knows.

Server Script (comments are from copy and paste, but i still read the post)

local DataStoreService = game:GetService("DataStoreService")
local dataStore = DataStoreService:GetDataStore("Cash")

local function saveData(player) -- The functions that saves data

	local tableToSave = {
		player.CashStats.Cash.Value -- First value from the table
	}

	local success, err = pcall(function()
		dataStore:SetAsync(player.UserId, tableToSave) -- Save the data with the player UserId, and the table we wanna save
	end)

	if success then -- If the data has been saved
		print("Data has been saved!")
	else -- Else if the save failed
		print("Data hasn't been saved!")
		warn(err)		
	end
end

game.Players.PlayerAdded:Connect(function(player) -- When a player joins the game

	-- // Assigning player stats //
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "CashStats"
	leaderstats.Parent = player

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

	local data -- We will define the data here so we can use it later, this data is the table we saved
	local success, err = pcall(function()

		data = dataStore:GetAsync(player.UserId) -- Get the data from the datastore

	end)

	if success and data then -- If there were no errors and player loaded the data

		Money.Value = data[1] -- Set the money to the first value of the table (data)
		print("Set value for datastore!")

	else -- The player didn't load in the data, and probably is a new player
		print("The player has no data!") -- The default will be set to 0
	end

end)

game.Players.PlayerRemoving:Connect(function(player) -- When a player leaves
	local success, err  = pcall(function()
		saveData(player) -- Save the data
	end)

	if success then
		print("Data has been saved")
	else
		print("Data has not been saved!")
	end
end)

game:BindToClose(function() -- When the server shuts down
	for _, player in pairs(game.Players:GetPlayers()) do -- Loop through all the players
		local success, err  = pcall(function()
			saveData(player) -- Save the data
		end)
	end
end)

LocalScript, inside of TextLabel

local localplayer = game:GetService("Players").LocalPlayer
local cash = localplayer.CashStats.Cash
wait(0.5)
script.Parent.Text = "$"..cash.Value

game.ReplicatedStorage.Served.OnClientEvent:Connect(function(_, order)
	cash.Value += math.random(5, 15) -- this works just fine, but the server script wont save it
	script.Parent.Text = "$"..tostring(cash.Value)
end)

3 Likes

The script looks fine to me, does “Data has been saved!” print when you leave the game?

1 Like

Yes, everything prints perfectly.

1 Like

You could try using UpdateAsync, it should work either way but its worth a shot:

dataStore:UpdateAsync(player.UserId, function()
   return tableToSave
end
1 Like

Where would i put this in either of the scripts?

local DataStoreService = game:GetService("DataStoreService")
local dataStore = DataStoreService:GetDataStore("Cash")

local function saveData(player) -- The functions that saves data

	local tableToSave = {
		player.CashStats.Cash.Value -- First value from the table
	}

	local success, err = pcall(function()
		dataStore:UpdateAsync(player.UserId, function()
           return tableToSave
        end 
	end)-- Save the data with the player UserId, and the table we wanna save

	if success then -- If the data has been saved
		print("Data has been saved!")
	else -- Else if the save failed
		print("Data hasn't been saved!")
		warn(err)		
	end
end

game.Players.PlayerAdded:Connect(function(player) -- When a player joins the game

	-- // Assigning player stats //
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "CashStats"
	leaderstats.Parent = player

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

	local data -- We will define the data here so we can use it later, this data is the table we saved
	local success, err = pcall(function()

		data = dataStore:GetAsync(player.UserId) -- Get the data from the datastore

	end)

	if success and data then -- If there were no errors and player loaded the data

		Money.Value = data[1] -- Set the money to the first value of the table (data)
		print("Set value for datastore!")

	else -- The player didn't load in the data, and probably is a new player
		print("The player has no data!") -- The default will be set to 0
	end

end)

game.Players.PlayerRemoving:Connect(function(player) -- When a player leaves
	local success, err  = pcall(function()
		saveData(player) -- Save the data
	end)

	if success then
		print("Data has been saved")
	else
		print("Data has not been saved!")
	end
end)

game:BindToClose(function() -- When the server shuts down
	for _, player in pairs(game.Players:GetPlayers()) do -- Loop through all the players
		local success, err  = pcall(function()
			saveData(player) -- Save the data
		end)
	end
end)

Try this

1 Like

Still prints “Set Value for Datastore!”, but the value is still 0, not 12, like when i left the first time.

What script is setting the value of the cash?

I’m the idiot of the century. The client is changing the value. I’m guessing i should use a RemoteEvent for the server to change the value?

Yes that is what I expected, don’t be hard on yourself I think every programmer ever has made this mistake, a remote event will work fine here.

You should mark the post as solved so people know its already fixed

1 Like

Are you testing this in studio? If so, test it in the game and it should work fine.

I don’t believe i’m doing this right.
Client

local localplayer = game:GetService("Players").LocalPlayer
local cashstats = localplayer:WaitForChild("CashStats")
local cash = cashstats:WaitForChild("Cash")
wait(0.5)
script.Parent.Text = "$"..cash.Value

local rs = game:GetService("ReplicatedStorage")

rs.Served.OnClientEvent:Connect(function(_, order)
	rs.SetCash:FireServer(localplayer, math.random(5, 15))
	script.Parent.Text = "$"..tostring(cash.Value)
end)

Server

local DataStoreService = game:GetService("DataStoreService")
local dataStore = DataStoreService:GetDataStore("Cash")

local RS = game:GetService("ReplicatedStorage")

local function saveData(player) -- The functions that saves data

	local tableToSave = {
		player.CashStats.Cash.Value -- First value from the table
	}

	local success, err = pcall(function()
		dataStore:UpdateAsync(player.UserId, function()
			return tableToSave
		end)
	end)-- Save the data with the player UserId, and the table we wanna save

	if success then -- If the data has been saved
		print("Data has been saved!")
	else -- Else if the save failed
		print("Data hasn't been saved!")
		warn(err)		
	end
end

game.Players.PlayerAdded:Connect(function(player) -- When a player joins the game

	-- // Assigning player stats //
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "CashStats"
	leaderstats.Parent = player

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

	local data -- We will define the data here so we can use it later, this data is the table we saved
	local success, err = pcall(function()

		data = dataStore:GetAsync(player.UserId) -- Get the data from the datastore

	end)

	if success and data then -- If there were no errors and player loaded the data

		Money.Value = data[1] -- Set the money to the first value of the table (data)
		print("Set value for datastore!")

	else -- The player didn't load in the data, and probably is a new player
		print("The player has no data!") -- The default will be set to 0
	end

end)

game.Players.PlayerRemoving:Connect(function(player) -- When a player leaves
	local success, err  = pcall(function()
		saveData(player) -- Save the data
	end)

	if success then
		print("Data has been saved")
	else
		print("Data has not been saved!")
	end
end)

game:BindToClose(function() -- When the server shuts down
	for _, player in pairs(game.Players:GetPlayers()) do -- Loop through all the players
		local success, err  = pcall(function()
			saveData(player) -- Save the data
		end)
	end
end)

RS.SetCash.OnServerEvent:Connect(function(player, num)
	player.CashStats.Cash.Value = num
end)

Output gives me this for Server, line 76 (line 76 is player.CashStats.Cash.Value = num)

value of type Instance cannot be converted to a number

Add a “.Value” to the end of that Instance’s name when you are referencing it

1 Like

So would that be “num.Value”? What am i adding Value to?

Yes, you are already adding .Value to the Cash Instance in assignment, but not to the “num” parameter. Try it out and it should get rid of the error.

The num variable is already a number, but i’ll try it and tell you if it works.

This tells me Value is not a valid member of Player "Players.milkmanthememer".

I think it’s assuming that num is actually the player variable?

Fixed it by simply making the random number with the server script, rather than the local one. Thank you for your help, everyone.

1 Like

This doesn’t work because I’m assuming you’re trying to set the money using the text label or a value object. If the text/value inside the text label/object value isn’t replicated to the server then the server will see the current cash as 0. It would be better to use a remote event and use that to add cash to the player.

1 Like

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