Saving Folders/Tables with DataStores

I need help with saving a folder that turns into a table. I need a script revamp to make my script work, the issue is that it doesent load correctly, and it doesn’t set the values.

My Script

local DataStoreService = game:GetService('DataStoreService')
local DataBase = DataStoreService:GetDataStore("PlayerBase18")

local data = {}

function bootSetup(character, selectedBoots)

	if character:FindFirstChild("LeftBoot") then

		character:FindFirstChild("LeftBoot"):Destroy()

	end
	if character:FindFirstChild("RightBoot") then

		character:FindFirstChild("RightBoot"):Destroy()

	end

	local leftBoot2 = game:GetService('ReplicatedStorage'):WaitForChild("Boots"):FindFirstChild(selectedBoots.Value):Clone()
	leftBoot2:SetPrimaryPartCFrame(character["Left Leg"].CFrame * CFrame.new(0,-.6,0) * CFrame.Angles(0,math.rad(270),0))
	leftBoot2.Parent = character
	leftBoot2.WeldConstraint.Part0 = leftBoot2.PrimaryPart
	leftBoot2.WeldConstraint.Part1 = character["Left Leg"]
	leftBoot2.Name = "LeftBoot"

	local rightBoot2 = game:GetService('ReplicatedStorage'):WaitForChild("Boots"):FindFirstChild(selectedBoots.Value):Clone()
	rightBoot2:SetPrimaryPartCFrame(character["Right Leg"].CFrame * CFrame.new(0,-.6,0) * CFrame.Angles(0,math.rad(270),0))
	rightBoot2.Parent = character
	rightBoot2.WeldConstraint.Part0 = rightBoot2.PrimaryPart
	rightBoot2.WeldConstraint.Part1 = character["Right Leg"]
	rightBoot2.Name = "RightBoot"

end

game.Players.PlayerAdded:Connect(function(player)
	
	local boots = Instance.new("Folder", player)
	boots.Name = "Boots"

	local playerData -- data
	local success, errorMsg = pcall(function() -- should be like this

		playerData = DataBase:GetAsync(player.UserId)

	end)

	if success then

		if not playerData then

			playerData = {
				["SelectedBoots"] = "Default",
			}

			for i, boot in pairs(game:GetService("ReplicatedStorage"):WaitForChild("Boots"):GetChildren()) do

				if boot.Name == "Default" then

					table.insert(playerData, {
						[boot.Name] = {
							["BootName"] = boot.Name,
							["Owned"] = true
						}
					})

				else

					table.insert(playerData, {
						[boot.Name] = {
							["BootName"] = boot.Name,
							["Owned"] = false
						}
					})

				end

			end

			print(playerData)

		end

		data[player.UserId] = playerData

		else warn(errorMsg)
	end
	
	local leaderstats = Instance.new("Folder", player)
	leaderstats.Name = "leaderstats"
	
	for i, boot in pairs(game:GetService("ReplicatedStorage"):WaitForChild("Boots"):GetChildren()) do
		
		local cloneBoot = Instance.new("BoolValue", boots)
		cloneBoot.Name = boot.Name
		
		if data[player.UserId][boot.Name] then
			
			if data[player.UserId][boot.Name].Owned == true then
				
				cloneBoot.Value = true
				
			else
				
				cloneBoot.Value = false
				
			end
			
		else
			
			if boot.Name == "Default" then

				cloneBoot.Value = true

			else

				cloneBoot.Value = false

			end
			
		end
		
	end
	
	local height = Instance.new("NumberValue", leaderstats)
	height.Name = "Height"
	
	local selectedBoots = Instance.new("StringValue", player)
	selectedBoots.Name = "SelectedBoots"
	selectedBoots.Value = playerData.SelectedBoots or "Default"
	
	local character = player.Character or player.CharacterAdded:Wait()
	
	bootSetup(character, selectedBoots)

	selectedBoots.Changed:Connect(function()
			
		data[player.UserId].SelectedBoots = selectedBoots.Value

		bootSetup(character, selectedBoots)

	end)
	
	player.CharacterAdded:Connect(function(c)
		
		character = c
		
		bootSetup(character, selectedBoots)
		
	end)
	
	while wait() do
		
		for i, item in pairs(boots:GetChildren()) do

			item:GetPropertyChangedSignal("Value"):Connect(function()
				
				print(data[player.UserId])
				data[player.UserId][item.Name].Owned = item.Value

			end)

		end

		local humanoidPart = character:WaitForChild("HumanoidRootPart") or character:WaitForChild("Torso")

		if humanoidPart then

			height.Value = math.round(humanoidPart.Position.Y / 3)

		end

	end
	
end)

game.Players.PlayerRemoving:Connect(function(player)
	
	local totalTable = {["SelectedBoots"] = player:WaitForChild("SelectedBoots").Value}

	for i, boot in pairs(player:WaitForChild("Boots"):GetChildren()) do

		table.insert(totalTable, {
			[boot.Name] = {
				["BootName"] = boot.Name,
				["Owned"] = boot.Value,
			}
		})

	end

	local playerData
	local success, errorMsg = pcall(function()

		print(totalTable)

		playerData = DataBase:SetAsync(player.UserId, totalTable)

	end)
	
end)

are you getting an error or anything like that?

no, it’s just not loading the data’s values correctly

if success then
        if not playerData then
            playerData = {
                ["SelectedBoots"] = "Default",
            }

            for i, boot in pairs(game:GetService("ReplicatedStorage"):WaitForChild("Boots"):GetChildren()) do
                if boot.Name == "Default" then
                    table.insert(playerData, {
                        [boot.Name] = {
                            ["BootName"] = boot.Name,
                            ["Owned"] = true
                        }
                    })
                else
                    table.insert(playerData, {
                        [boot.Name] = {
                            ["BootName"] = boot.Name,
                            ["Owned"] = false
                        }
                    })
                end
            end

            print(playerData)
        end

        data[player.UserId] = playerData
    else
        warn(errorMsg)
    end

here you are only checking if they don’t have playerData.

You’re not doing anything if they do have playerdata from my quick look at it.

You only have parameters defined if not playerData

actually misread, I see where you are setting the data.

I’ve loaded it up into a Roblox Studio, and set it up to boot properly, what exactly isn’t loading correctly? I made fake “boots” folder in replicatedstorage

So, when the player joins the game, it creates a folder into the player named OwnedBoots or soemthing. When the player leaves, it should save the instances property (value) inside the OwnedBoots folder, when the player rejoin, it should set the values from the saved vales, but it deosent load it correctly! It just doesent load it, and sets it to the default values

Yeah, I’ve replicated the issue, I’m debugging it right now. I’ll lyk what I can find in a minute here

btw, if you want, you can revamp my scripts. cuz i think i did pretty bad with de script…

Whenever you change set the property of a new boot to true do you get any errors?

no, it just doesen’t set the value of the instance…

okay i’m gonna send you a fixed version now data is saving for me.


local DataStoreService = game:GetService('DataStoreService')
local DataBase = DataStoreService:GetDataStore("PlayerBase91")

local data = {}

function bootSetup(character, selectedBoots)
	if character:FindFirstChild("LeftBoot") then
		character:FindFirstChild("LeftBoot"):Destroy()
	end
	if character:FindFirstChild("RightBoot") then
		character:FindFirstChild("RightBoot"):Destroy()
	end

	local leftBoot2 = game:GetService('ReplicatedStorage'):WaitForChild("Boots"):FindFirstChild(selectedBoots.Value)
		:Clone()
	leftBoot2:SetPrimaryPartCFrame(character["Left Leg"].CFrame * CFrame.new(0, -.6, 0) *
		CFrame.Angles(0, math.rad(270), 0))
	leftBoot2.Parent = character
	leftBoot2.WeldConstraint.Part0 = leftBoot2.PrimaryPart
	leftBoot2.WeldConstraint.Part1 = character["Left Leg"]
	leftBoot2.Name = "LeftBoot"

	local rightBoot2 = game:GetService('ReplicatedStorage'):WaitForChild("Boots"):FindFirstChild(selectedBoots.Value)
		:Clone()
	rightBoot2:SetPrimaryPartCFrame(character["Right Leg"].CFrame * CFrame.new(0, -.6, 0) *
		CFrame.Angles(0, math.rad(270), 0))
	rightBoot2.Parent = character
	rightBoot2.WeldConstraint.Part0 = rightBoot2.PrimaryPart
	rightBoot2.WeldConstraint.Part1 = character["Right Leg"]
	rightBoot2.Name = "RightBoot"
end

game.Players.PlayerAdded:Connect(function(player)
	local boots = Instance.new("Folder", player)
	boots.Name = "Boots"

	local playerData                        -- data
	local success, errorMsg = pcall(function() -- should be like this
		playerData = DataBase:GetAsync(player.UserId)
	end)

	if success then
		if not playerData then
			playerData = {
				["SelectedBoots"] = "Default",
			}
			for i, boot in pairs(game:GetService("ReplicatedStorage"):WaitForChild("Boots"):GetChildren()) do
				if boot.Name == "Default" then
					playerData[boot.Name] = {
						["BootName"] = boot.Name,
						["Owned"] = true
					}
				else
					playerData[boot.Name] = {
						["BootName"] = boot.Name,
						["Owned"] = false
					}
				end
			end

			print(playerData)
		end
		
		data[player.UserId] = playerData
	else
		warn(errorMsg)
	end

	local leaderstats = Instance.new("Folder", player)
	leaderstats.Name = "leaderstats"

	for i, boot in pairs(game:GetService("ReplicatedStorage"):WaitForChild("Boots"):GetChildren()) do
		local cloneBoot = Instance.new("BoolValue", boots)
		cloneBoot.Name = boot.Name

		if data[player.UserId][boot.Name] then
			if data[player.UserId][boot.Name].Owned == true then
				cloneBoot.Value = true
			else
				cloneBoot.Value = false
			end
		else
			if boot.Name == "Default" then
				cloneBoot.Value = true
			else
				cloneBoot.Value = false
			end
		end
	end

	local height = Instance.new("NumberValue", leaderstats)
	height.Name = "Height"

	local selectedBoots = Instance.new("StringValue", player)
	selectedBoots.Name = "SelectedBoots"
	selectedBoots.Value = playerData.SelectedBoots or "Default"

	local character = player.Character or player.CharacterAdded:Wait()

	bootSetup(character, selectedBoots)

	selectedBoots.Changed:Connect(function()
		data[player.UserId].SelectedBoots = selectedBoots.Value

		bootSetup(character, selectedBoots)
	end)

	player.CharacterAdded:Connect(function(c)
		character = c

		bootSetup(character, selectedBoots)
	end)

	for bootName, item in pairs(boots:GetChildren()) do
		item:GetPropertyChangedSignal("Value"):Connect(function()
			data[player.UserId][bootName].Owned = item.Value
		end)
	end
end)

game.Players.PlayerRemoving:Connect(function(player)
	local totalTable = {}

	totalTable["SelectedBoots"] = player:FindFirstChild("SelectedBoots").Value
	
	local bootsFolder = player:FindFirstChild("Boots")
	if bootsFolder then
		for _, boot in pairs(bootsFolder:GetChildren()) do
			totalTable[boot.Name] = {
				BootName = boot.Name,
				Owned = boot.Value,
			}
		end
	end

	-- Attempt to save the data to the DataStore
	local success, errorMsg = pcall(function()
		-- Use the DataStore's SetAsync method
		DataBase:SetAsync(player.UserId, totalTable)
		print('Saved data for', player.Name)
	end)

	if not success then
		warn("Error saving player data: " .. errorMsg)
	end
end)

Let me test the SelectedBoot real quick and make sure that’s saving, but other stuff was saving properly.

Edit: everything is saving properly for me

asdjkljflcovjnerapdjaosjdajdoajfosidfd it didnt save’

Edit : let me try changing the values on the server side
Edit 2 : THANK YOU SOOO MUCHHH OMGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG

ye, have a good one, good luck with your game.

Uh, its not saving now ;-; ĂĂĂĂĂĂĂAAĂAĂAĂAĂĂĂĂA

Edit : Nevermindddddd

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