How can I save all descendants of a folder?

Hi, I want to save all the BoolValues in the players folder.

I have a very similar aim to this scripter: How can I save everything in a folder? (In the datastores) - Help and Feedback / Scripting Support - DevForum | Roblox

I’m not experienced with DataStores, so their script helped me adjust mine in ServerScriptService:

local players = game:GetService("Players")

local dSService = game:GetService("DataStoreService")
local sStorage = game:GetService("ServerStorage")

local data = dSService:GetDataStore("EggDataStore#15")

local function PlayerAdded(player)
	local key = player.UserId
	local plrFolder = Instance.new("Folder", player)
	plrFolder.Name = "DiscoveredEggs"
	for i,v in pairs(sStorage.DiscoveredEggs:GetChildren()) do
			Instance.new("BoolValue", plrFolder).Name = tostring(v)
	end
	for i, v in pairs(sStorage.DiscoveredEggs:GetDescendants()) do
			if plrFolder:FindFirstChild(v.Name) then
				
			else
				local vToString = tostring(v.Name)
				local eggNoNumbers = string.gsub(vToString,"%d+", "")
				local parent = plrFolder:FindFirstChild(eggNoNumbers)
				Instance.new("BoolValue", parent).Name = tostring(v)
			end
	end
	
	local discoveredDataStore = data:GetAsync(key)
	
	if discoveredDataStore ~= nil then
		for i, data in pairs(discoveredDataStore) do
			local egg = plrFolder:FindFirstChild(data[1])
			local instance = Instance.new(data[3])
			if egg then
				instance.Value = data[2]
			else
				if instance then
					if plrFolder:FindFirstChild(instance.Name) then
						instance.Value = data[2]
					else
						instance.Name = data[1]
						instance.Value = data[2]
						local instanceToString = tostring(instance.Name)
						local eggNoNumbers = string.gsub(instanceToString,"%d+", "")
						local parent = plrFolder:FindFirstChild(eggNoNumbers)
						instance.Parent = parent	
					end
				end
			end
		end
	else
		data:SetAsync(key, {})
	end
end

local function PlayerRemoving(player)
	local key = player.UserId
	local discoveredDataStore = data:GetAsync(key)
	local plrFolder = player:FindFirstChild("DiscoveredEggs")
	if not plrFolder then return end
	plrFolder = plrFolder:GetDescendants()
	local eggData = {}
	for i, egg in pairs(plrFolder) do
		table.insert(eggData, {egg.Name, egg.Value, egg.ClassName})
	end
	if discoveredDataStore == nil then
		data:SetAsync(key, eggData)
	else

		data:UpdateAsync(key, function(oldValue)
			oldValue = eggData
			return eggData
		end)
	end
end

players.PlayerAdded:Connect(PlayerAdded)
players.PlayerRemoving:Connect(PlayerRemoving)

It creates a folder full of BoolValues &, in those BoolValues, are more BoolValues. The problem is, it doesn’t save if their values are true or false. Sorry if this is confusing or a badly organised script, as I said, I’m not experienced with DataStores. Feel free to ask questions, thanks to anyone who can help!

2 Likes

Bool values was not saving for me either, then i converted them to string.


Saving the value

local bool = false
datastore:SetAsync("key",tostring(bool))

or

local bool = false
if (bool) then bool = "true" else bool = "false" end
datastore:SetAsync("key",bool)

Getting and setting the value

local data = datastore:GetAsync("key")
local boolValue = Instance.new("BoolValue")

if data == "false" then 
  boolValue.Value = false
elseif data == "true" then
  boolValue.Value = true
end

image

Thats how I save bool values.

1 Like

Thanks for this, I’m just testing then I’ll let you know if it’s working :slightly_smiling_face:

1 Like

Here’s my new script, do you have any idea why the values aren’t saving? Any help would be appreciated!

local players = game:GetService("Players")

local dSService = game:GetService("DataStoreService")
local sStorage = game:GetService("ServerStorage")

local data = dSService:GetDataStore("EggDataStore#18")

local function PlayerAdded(player)
	local key = player.UserId
	local plrFolder = Instance.new("Folder", player)
	plrFolder.Name = "DiscoveredEggs"
	for i, v in pairs(sStorage.DiscoveredEggs:GetChildren()) do
			Instance.new("BoolValue", plrFolder).Name = tostring(v)
	end
	for i, v in pairs(sStorage.DiscoveredEggs:GetDescendants()) do
			if plrFolder:FindFirstChild(v.Name) then
				
			else
				local vToString = tostring(v.Name)
			local eggNoNumbers = string.gsub(vToString,"%d+", "")
			if plrFolder:FindFirstChild(eggNoNumbers):FindFirstChild(v.Name) then
				else
				local parent = plrFolder:FindFirstChild(eggNoNumbers)
				Instance.new("BoolValue", parent).Name = tostring(v)
				end
			end
	end
	
	local discoveredDataStore = data:GetAsync(key)
	
	if discoveredDataStore ~= nil then
		for i, data in pairs(discoveredDataStore) do
			local egg = plrFolder:FindFirstChild(data[1])
			local instance = Instance.new(data[3])
			if egg then
				if tostring(data[2]) == false then
					instance.Value = false
				else
					instance.Value = true
				end
			else
				if instance then
					if plrFolder:FindFirstChild(instance.Name) then
						if tostring(data[2]) == false then
							print("DATA EQUAL TO FALSE")
							instance.Value = false
						else
							print("DATA EQUAL TO TRUE")
							instance.Value = true
						end
					else
						instance.Name = data[1]
						if tostring(data[2]) == false then
							print("DATA EQUAL TO FALSE")
							instance.Value = false
						else
							print("DATA EQUAL TO TRUE")--Always prints this
							instance.Value = true
						end
						local instanceToString = tostring(instance.Name)
						local eggNoNumbers = string.gsub(instanceToString,"%d+", "")
						if plrFolder:FindFirstChild(eggNoNumbers):FindFirstChild(instance.Name) then
							
						else
							local parent = plrFolder:FindFirstChild(eggNoNumbers)
							instance.Parent = parent	
						end
					end
				end
			end
		end
	else
		data:SetAsync(key, {})
	end
end

local function PlayerRemoving(player)
	local key = player.UserId
	local discoveredDataStore = data:GetAsync(key)
	local plrFolder = player:FindFirstChild("DiscoveredEggs")
	if not plrFolder then return end
	plrFolder = plrFolder:GetDescendants()
	local eggData = {}
	for i, egg in pairs(plrFolder) do
		table.insert(eggData, {egg.Name, egg.Value, egg.ClassName})
	end
	if discoveredDataStore == nil then
		data:SetAsync(key, eggData)
	else

		data:UpdateAsync(key, function(oldValue)
			oldValue = eggData
			return eggData
		end)
	end
end

players.PlayerAdded:Connect(PlayerAdded)
players.PlayerRemoving:Connect(PlayerRemoving)

image
is this a bool value?

1 Like

You cannot save a string in a datastore, convert it into a table.

1 Like

The egg variable is the BoolValue, yes

table.insert(eggData,{egg.Name, tostring(egg.Value), egg.ClassName})
1 Like

Thanks all your help, but it’s still not working :[

1 Like

What is the error you recieve in the output when you try to save it?

1 Like

Unfortunately, there is no errors in the output.

image
works for me, idk whats the issue with your script.

1 Like

Hmm… ok let me experiment & I’ll let you know if I can get it to work

Not gonna read ya code properly, however if the primary problemo is that the data isn’t saving, and there are no warnings or errors in the console, please checc that the Studio Access to API Services config is enabled.

Second of all, DataStores save tables, not singular types. Ya can’t save UserData types either.
Here’s an example for saving booleans in a Roblox Datastore, using DatastoreService

I haven’t actually used DataStoreService from experience before, I’d recommend ProfileService, a session locking promoting wrapper by @loleris

local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("DataStore Name")
local Success, Response = pcall(function()
    DataStore:Set("Key", {
        ... -- Example: Egg = true
    })
end)
1 Like

Works :man_shrugging:
Saving:

local e = {} 
table.insert(e,{"hi",tostring(false),"Egg"}) 
local dataService = game:GetService("DataStoreService") 
local data = dataService:GetDataStore("test") 
data:SetAsync("key",e)

Getting:

local dataService = game:GetService("DataStoreService") 
local data = dataService:GetDataStore("test") 
print(data:GetAsync("key"))
1 Like

Try using pcall whenever you use datastore.

It will help you catch errors.

local suc, errorMessage = pcall(function()
     for i, egg in pairs(plrFolder) do
      table.insert(eggData, {egg.Name, tostring(egg.Value), egg.ClassName})
    end
    if discoveredDataStore == nil then
		data:SetAsync(key, eggData)
	else
		data:UpdateAsync(key, function(oldValue)
			oldValue = eggData
			return eggData
		end)
	end
end)

if errorMessage then
   error(errorMessage)
end
1 Like

table.insert is used for when the setting of keys is unnecessary, in this case you’re adding a table in a table and that’s redundant, call the function on each of the types separately.

1 Like

Ok, thank you!
(characters)))))))

Folder with eggs
image


Saving

local datastoreService = game:GetService("DataStoreService")
local datastore = datastoreService:GetDataStore("eggs")

local suc, err = pcall(function()
	local tab = {}
	for i,egg in pairs(workspace.Folder:GetDescendants()) do
		table.insert(tab,{egg.Name, tostring(egg.Value), egg.ClassName})
	end
	if not datastore:GetAsync("key") then
		datastore:SetAsync("key",tab)
	else
		datastore:UpdateAsync("key",function(oldVal)
			return tab
		end)
	end
end)

Getting

local datastoreService = game:GetService("DataStoreService")
local datastore = datastoreService:GetDataStore("eggs")

print(datastore:GetAsync("key"))

Output
image


image
Inserted another table using table.insert

1 Like

I haven’t fixed it yet but you have proved that it works, so thank you!

1 Like