Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Any better way of datastoring folders??

So, what I am trying to do is store data for the folder. Whenever a player is exiting the game, the script will save his/her Data Folder. This script is a Server script and is the Child of ServerScriptService. The script I have written is:

local ds = game:GetService("DataStoreService")
local PlayerAmianData = ds:GetDataStore("AmianData")

game.Players.PlayerRemoving:Connect(function(player)
	local Owned_Amians = player.PlayerGui.Owned_Amian
	
	for tries = 1, 10, 1 do
		local success, errormessage = pcall(function()
			PlayerAmianData:UpdateAsync(player.UserID, Owned_Amians)
		end)
		if success then
			break
		else
			PlayerAmianData:SetAsync(player.Name.."_"..player.UserID, Owned_Amians)
			break
		end
	end
end)

But my script doesn't seem to work properly for datastoring a folder and it's descendants. Is there any better way of doing it?? Thanks in advance!!

2 answers

✓ Accepted answer

for one, DataStores can only store strings, numbers, booleans, and tables which contain elements of the aforementioned types

to save instances, or any roblox datatype, really, you have to serialize them, which means to convert them to a more basic format

two, UpdateAsync expects a callback which returns the data you want it to save, not just the data

if it did it'd literally just be SetAsync 2

-- inconsistent casing is kind of bleh but it's not a massive deal

local ds = game:GetService("DataStoreService")
local PlayerAmianData = ds:GetDataStore("AmianData")

game.Players.PlayerRemoving:Connect(function(player)
    local Owned_Amians = player.PlayerGui.Owned_Amian

    local dataToSave = {}
    for _, child in pairs(Owned_Amians) do
        -- do something idk how you're saving your data
    end

    local success, errormessage
    for tries = 1, 10, 1 do
        success, errormessage = pcall(function()
          PlayerAmianData:SetAsync(player.UserID, Owned_Amians) -- no reason to use UpdateAsync when the old data doesn't matter in the slightest
        end)
        if success then
            break
        else -- what's the point of making a system that tries to save your data several times if it's just going to break on the first iteration, no matter what
            warn("Data failed to save: \n" .. errormessage .. "\nRetrying...") -- \n is a new line, it just makes it a bit nicer to read
        end
    end
    if not success then
        warn("Data failed to save!")
    else
        warn("Data saved successfully.")
    end
end)

idk how your amians thingy is organized but. please please please for the love of god don't just do table.insert(dataToSave, child) and expect it to work, you actually have to convert the data into tables, strings, numbers, and booleans

you can put nested tables in a datastore btw, nested tables are just tables in other tables

so you could save something like this and it would work fine

{ {"hi", "hello"}, {"i love big chungus"} }

2 comments

0

I understand now. Thx!!

0

Thanks again

Thanks to Elyzzia!! Now I made a fully functional script:

wait(1)

local ds = game:GetService("DataStoreService")
local PlayerAmianData = ds:GetDataStore("AmianData")


function update(plr)
	local Owned_Amians = plr.PlayerGUI.Owned_Amians
	
	local DataToSave = {}
	
	for Serial, Amian in pairs(Owned_Amians:GetChildren()) do
		local CurrentAmianData = {}
		
		table.insert(CurrentAmianData, 1, Amian.AmianName.Value)
		table.insert(CurrentAmianData, 2, Amian.Level.Value)
		table.insert(CurrentAmianData, 3, Amian.Data.Battle.CurrentEnergy.Value)
		table.insert(CurrentAmianData, 4, Amian.Data.Battle.CurrentHealth.Value)
		table.insert(CurrentAmianData, 5, Amian.Data.Battle.MaxEnergy.Value)
		table.insert(CurrentAmianData, 6, Amian.Data.Battle.MaxHealth.Value)
		table.insert(CurrentAmianData, 7, Amian.Data.Other.XP_needed.Value)
		table.insert(CurrentAmianData, 8, Amian.Data.Other.XP_current.Value)
		
		table.insert(CurrentAmianData, 9 , Amian.Moves.Move1.Value)
		table.insert(CurrentAmianData, 10, Amian.Moves.Move2.Value)
		table.insert(CurrentAmianData, 11, Amian.Moves.Move3.Value)
		table.insert(CurrentAmianData, 12, Amian.Moves.Move4.Value)
		
		table.insert(DataToSave, Serial, CurrentAmianData)
	end
	
	PlayerAmianData:SetAsync("Player_"..plr.UserID, DataToSave)
end

game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Wait()
	local Owned_Amians = player:WaitForChild("PlayerGui",10):WaitForChild("Owned_Amians",10)
	wait(1)
	local SavedData
	
	for tries = 1, 10, 1 do
		print("Getting Data".."["..tries.."]")
		wait(1)
		local success, errormessage = pcall(function()
			SavedData = PlayerAmianData:GetAsync("Player_"..player.UserID)
		end)
		if success then
			break
		else
			warn([[Could not fetch the data
			Retrying...
			]])
		end
	end
	
	if SavedData ~= nil then
		for Serial, Amian in pairs(SavedData) do
			local CurrentAmian = game.ReplicatedStorage:WaitForChild("Amians",10):FindFirstChild(Amian[1])
			local CurrentTemplate = game.ReplicatedStorage.Mechanism.Templates.Amian_Template:Clone()
			
			CurrentTemplate.Name = CurrentAmian.Name
			CurrentTemplate.Data.Description.Value = CurrentAmian.Data.Description.Value
			CurrentTemplate.Data.Description.Value = CurrentAmian.Data.Description.Value
			CurrentTemplate.Body.Image = CurrentAmian.Body.Image
			
			CurrentTemplate.Data.AmianName.Value = Amian[1]
			CurrentTemplate.Data.Level.Value = Amian[2]
			CurrentTemplate.Data.Battle.CurrentEnergy.Value = Amian[3]
			CurrentTemplate.Data.Battle.CurrentHealth.Value = Amian[4]
			CurrentTemplate.Data.Battle.MaxEnergy.Value = Amian[5]
			CurrentTemplate.Data.Battle.MaxHealth.Value = Amian[6]
			CurrentTemplate.Data.Other.XP_needed.Value = Amian[7]
			CurrentTemplate.Data.Other.XP_current.Value = Amian[8]
			
			CurrentTemplate.Data.Moves.Move1.Value = Amian[ 9]
			CurrentTemplate.Data.Moves.Move2.Value = Amian[10]
			CurrentTemplate.Data.Moves.Move3.Value = Amian[11]
			CurrentTemplate.Data.Moves.Move4.Value = Amian[12]
			
			for i, v in pairs(CurrentAmian.Data.Types:GetChildren()) do
				if i == 2 then
					local Type2 = CurrentTemplate.Data.Types.Type:Clone()
					Type2.Value = v.Value
					Type2.Parent = CurrentTemplate.Data.Types
				else
					CurrentTemplate.Data.Types.Type.Value = v.Value
				end
			end
			
			CurrentTemplate.Parent = Owned_Amians --Executing it at last
		
		end
	else
		error("Error fetching the data")
	end
	
	player.PlayerGui.Intro.Start:FireClient()
	
	Owned_Amians.Changed:Connect(update(player))
end)

This discussion is preserved as it was. New answers, comments, and votes are closed.