Help with DataStore Script (StringValue save in a table with DataStore)

  1. What I want to achieve is when a player clicks on a part it saves an accessory in datastore with table and when the player leaves and join it shows him the GUI of the item with options to equip it or unequip it

  2. The problem is that StringValue is not saved when the player joins

Code one (The part when clicked)

function onClicked(plr)
	if not plr:WaitForChild("Hats"):FindFirstChild(script.Parent.Name) then
		plr.PlayerGui.OpenInventory.Frame["Blue Halo"].Visible = true
		game.Players[plr.Name].PlayerGui.OpenInventory.Frame["BlueLocked"].Visible = false
		local NewHalo = Instance.new("StringValue", plr:WaitForChild("Hats"))
		NewHalo.Name = script.Parent.Name
		NewHalo.Value = script.Parent.Name
		game.Players[plr.Name].PlayerGui.OwnedOrNot.BlueNo.Visible = true
		wait(3)
		game.Players[plr.Name].PlayerGui.OwnedOrNot.BlueNo.Visible = false
else
		game.Players[plr.Name].PlayerGui.OwnedOrNot.BlueYes.Visible = true
		wait(3)
		game.Players[plr.Name].PlayerGui.OwnedOrNot.BlueYes.Visible = false
	end
end



script.Parent.ClickDetector.MouseClick:Connect(onClicked)

Code two(When the player joins it shows the GUI if he clicked the part)

local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("HatSaver") -- Change this with a different name.

game.Players.PlayerAdded:Connect(function(Player)
	local Hats = Instance.new("Folder", Player)
	Hats.Name = "Hats"
	
	local PlayerKey = "Player_"..Player.UserId
	local HatsData
	local success, errormessage = pcall(function()
		HatsData = DataStore:GetAsync(PlayerKey)
	end)
	
	if HatsData then
		for _, v in pairs(HatsData) do
			local HatValue = Instance.new("StringValue")
			HatValue.Name = v
			HatValue.Value = v
			print(v.Name)
		end
	end
end)

game.Players.PlayerRemoving:Connect(function(Player)
	local Hats = Player:WaitForChild("Hats")
	local PlayerHats = {}
	
	local PlayerKey = "Player_"..Player.UserId
	
	for _, v in pairs(Hats:GetChildren()) do
		table.insert(PlayerHats, #PlayerHats, v.Name)
		print("Saving "..v.Name)
	end
	DataStore:SetAsync(PlayerKey, PlayerHats)
end)

I’m confused by this post… But are you referring to the HatValue StringValue that you instantiate but do not parent to anything?

This code is a headache with a lot of unnessisary variables, I would cut back on that.

Also what is inserted into the hats table??

StringValue that named like the accessory name.

why do you insert the hats this way? Why not just table.insert(PlayerHats, v.Name)? You get is that in the first loop the hat table has 0 content meaning you are trying to insert in place holder 0, in Roblox the first value is 1 and not 0 I think that is the problem. Remove hats when inserting the data into the table

1 Like

One thing I dont get, why do you need to turn it into a folder and then read through thr folder, its not in replicated storage so its not for server to client communication.

All you need is one array.

Also if a player doesnt have any data saved your script wont know what to do about it. As well as your only pcall statement missing the ability to retry and the :SetAsync is running without pcall at all.

Ehm, an array won’t be useful because it will only be accessed through one script in that case. The only way you would be able to share to other scripts would be to use bindable and remote functions which is inefficient. A remote function takes time to complete as it has to send a get request to the server and then wait for a post from the server back to the client. If you have it in a folder inside the player object all scripts can easily access the items without needing remote functions. An example would be, let’s say you have an inventory and it updates your stuff every time you get a new hat, lose a hat or open the shop. It would be inefficient to use remote functions in all those cases when the client can simply view the hats in a folder in the player object. Hope it makes sense.