Server Storage for important data issues

When a player joins a game, It creates a folder in server storage to store player stats, the current stat I have in this system is GoldCoins. When the player clicks a part in the workspace the player’s GoldCoins increase by 100. What I have observed is that when a friend of mine helped me test this system, everything worked fine as it should until he left game and re-joined. It saved his previous GoldCoins data, but added an additional folder that started him back at 0 as well… Now I know I need to add a check in there some where like if this folder exists then do nothing or something of that sort, Just not sure how I would implement that or where I would go about doing it. (Also for the record, just using player name right now instead of UserId for easy use of getting/setting/printing data in the game client console)


DATASTORE SCRIPT THAT ADDS FOLDER AND STATS


replicatedStorage = game:GetService("ReplicatedStorage")
serverStorage = game:GetService("ServerStorage")


-- GET DATA STORE SERVICE--
local DataStoreService = game:GetService("DataStoreService")

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

--DATA STORES--
local GoldStore = DataStoreService:GetDataStore("PlayerGold")

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


-- ON PLAYER ADDED --
game.Players.PlayerAdded:Connect(function(player)


	--DATA VARIABLES SET AS NIL VALUE FOR NOW, GET UPDATED BELOW --
	local GoldCoinsData
	
	-- LEADERSTATS --

	
	-- PLAYER STATS --
	
	local playerStats = Instance.new("Folder")
	playerStats.Name = player.Name
	playerStats.Parent = serverStorage
	
	local goldCoins = Instance.new("IntValue")
	goldCoins.Name = "GoldCoins"
	goldCoins.Parent = playerStats
	goldCoins.Value = 0
	
	for i, child in pairs(serverStorage:GetChildren()) do
		if child:IsA("Folder") then
			if child.Name == player.Name then
				local playerName = child.Name
				print(playerName.."IS THE PLAYERS NAME")
				local PlayerStats = serverStorage:WaitForChild(playerName)
				GoldCoins = PlayerStats:WaitForChild("GoldCoins")
				print("FOUND GOLDCOINS VARIABLE")
			end
		end
	end
	

	local success, errormessage = pcall(function() 
		GoldCoinsData = GoldStore:GetAsync(player.UserId, GoldCoins.Value)
	end)


	if success then -- if success then sets a the value to DATA variable
		GoldCoins.Value = GoldCoinsData

	else
		warn(errormessage) -- if fails then gives error
	end
end)

-- ON PLAYER REMOVE --
game.Players.PlayerRemoving:Connect(function(player)
	local success, errormessage = pcall(function()
		GoldStore:SetAsync(player.UserId, GoldCoins.Value)
	end)
	
	if success then -- if success then the data gets saved via SetAsync above
		print("DATA SAVED")
	else
		warn(errormessage) -- if fails then gives error
	end
end)

-- LOOP ON PLAYER ADDED TO SAVE DATA EVERY 120 SECONDS)
game.Players.PlayerAdded:Connect(function(player)

	while true do

		wait(300) -- SAVE INTERVAL (SAFTEY IN CASE SERVER CRASHES, ETC)

		local success, errormessage = pcall(function()
			GoldStore:SetAsync(player.UserId, GoldCoins.Value)
		end)

		if success then -- if success then the data gets saved via SetAsync above
			print("DATA SAVED")
		else
			warn(errormessage) -- if fails then gives error
		end
	end

end)

GOLD GIVER SCRIPT (PLAYER CLICK ON PART TO GIVE GOLD STAT)


serverStorage = game:GetService("ServerStorage")
replicatedStorage = game:GetService("ReplicatedStorage")
local Event = replicatedStorage:WaitForChild("Gold")



game.Workspace.GoldGiver:WaitForChild("ClickDetector").MouseClick:Connect(function(player)
	for i, child in pairs(serverStorage:GetChildren()) do
		if child:IsA("Folder") then
			if child.Name == player.Name then
			print(child.Name)
			goldCoins = child:WaitForChild("GoldCoins")
			goldCoins.Value = goldCoins.Value + 100
			print(goldCoins.Value)
			end
		end
	end
	Event:FireClient(player, goldCoins.Value)
end)

TEXT LABEL SCRIPT (Remote event to show server stat data to client Gui)

textLabel = script.Parent
textValue = textLabel.Text


local serverStorage = game:GetService("ServerStorage")
local replicatedStorage = game:GetService("ReplicatedStorage")
local event = replicatedStorage:WaitForChild("Gold")

local player = game.Players.LocalPlayer

for i, child in pairs(serverStorage:GetChildren()) do
	if child:IsA("Folder") then
		if child.Name == player.Name then
			local playerName = child.Name
			local PlayerStats = serverStorage:WaitForChild(playerName)
			GoldCoins = PlayerStats:WaitForChild("GoldCoins")
		end
	end
end

local function goldCoins(Gold)
	textLabel.Text = ""..Gold
	print("Event Fired From Local")
end

event.OnClientEvent:Connect(goldCoins)

I think you may have been saving a folder and adding a folder at the same time like instead of setting a value to datastore info or 0 you set the folder to datastore or 0.

You are not checking if there is already a folder under the player’s name.

That is already what I said… below is part of my question. I am not sure on how I should implement this check :slight_smile:

" Now I know I need to add a check in there some where like if this folder exists then do nothing or something of that sort, Just not sure how I would implement that or where I would go about doing it."

Before creating the new folders, do ServerStorage:FindFirstChild(player.Name). If that returns nil, there is no folder and proceed to make one.

2 Likes

ill have to wait and see if it works. seems to work in studio, but i need a secondary person on the server to verify… I’ll update the post when its been resolved.

Thank you! seems to work. Didn’t realize it would be that simple.

	if serverStorage:FindFirstChild(player.Name) == nil then
		local playerStats = Instance.new("Folder")
		playerStats.Name = player.Name
		playerStats.Parent = serverStorage
1 Like