Currently, my DataStore is capable of saving // restoring all values within a given folder - However, the format only works if the Values are direct children of the Folder / Configuration being changed as such:
Below is what I wish to achieve:
I wish to maintain the over-all Save function in which it is capable of saving everything rather than looking for a labelled specific value. I have included the coding.
SaveData
local success, Data = pcall(function()
return DataStoreService:SetAsync(Player.UserId, saveToDictionary(Player["PlayerData"]))
end)
if success then end
end
function saveToDictionary(object)
if not object:IsA("Configuration") then
if (object:IsA("Color3Value")) then
return { "Color3", tostring(object.Value) }
end
return object.Value
else
local newTable = {}
for i,v in pairs(object:GetChildren()) do
newTable[v.Name] = saveToDictionary(v)
end
return newTable
end
LoadData
function materializeDictionary(input)
if typeof(input) == "table" then
if (input[1] == "Color3") then
local newColor3Value = Instance.new("Color3Value")
newColor3Value.Value = Color3.new(unpack(input[2]:split(", ")))
return newColor3Value
end
local newConfig = Instance.new("Configuration")
for i,v in pairs(input) do
local newObject = materializeDictionary(v)
newObject.Name = i
newObject.Parent = newConfig
end
return newConfig
elseif typeof(input) == "number" then
local newIntValue = Instance.new("NumberValue")
newIntValue.Value = input
return newIntValue
elseif typeof(input) == "string" then
local newStringValue = Instance.new("StringValue")
newStringValue.Value = input
return newStringValue
elseif typeof(input) == "boolean" then
local newBoolValue = Instance.new("BoolValue")
newBoolValue.Value = input
return newBoolValue
end
end
Well dude.
Your save function only looks at the children of objects with the configuration classname. HairType and OutfitType aren’t configuration objects so the save function never looks at their children.
Try this
userdata_to_table = function (userdata)
if not (userdata and type(userdata)=='userdata') then
return nil
end
local entry = {}
entry.Class=userdata.ClassName
if (userdata:IsA('ValueBase')) then
entry.Value=tostring(userdata.Value)
end
entry.children = {}
for _, obj in pairs(userdata:GetChildren()) do
local child = userdata_to_table(obj)
entry.children[obj.Name]=child
end
return entry
end
table_to_userdata = function(tab)
if not (tab and type(tab)=='table' and tab.Class) then
return nil
end
local class=tab.Class
local instance=Instance.new(class)
if class=='NumberValue' or class=='IntValue' then
instance.Value = tonumber(tab.Value)
elseif class=='StringValue' then
instance.Value = tab.Value
elseif class=='BoolValue' then
instance.Value = 'true'==tab.Value
elseif class=='Color3Value' then
instance.Value = Color3.new(unpack(tab.Value:split(',')))
elseif class=='BrickColor' then
instance.Value = BrickColor.new(tab.Value)
elseif class=='CFrameValue' then
instance.Value = CFrame.new(unpack(tab.Value:split(',')))
elseif class=='Vector3Value' then
instance.Value = CFrame.new(unpack(tab.Value:split(',')))
end
for name, obj in pairs(tab.children) do
local child = table_to_userdata(obj)
child.Name=name
child.Parent=instance
end
return instance
end
@greatgavin - Hi, yes. The original coding does work as intended, agreed the formatting is off and I am working on fixing it.
Ideally I am looking at how to save the Children of the values shown above so that I can keep my Folders categorised as opposed to having everything under a single folder.
@SuperSpeedy101 Oh yeah, u right. The if statement only on the Color3 threw me off.
@iiKossmoZ My bad about only color3 values being considered. lol, but again you still only perform recursion on your save function to the children of Configuration class objects. So I mean this would work if HairType and OutfitType were also Configurations. If you want the children of all types of objects to be considered, then you’ll need to store a table for each userdata object. The example I gave does do that. Feel free to look it over, try it out, and ask any questions.
Why not have a table to organize everything?
I made a script that uses an organized method of serializing different datatypes by putting the functions in tables. For now, I only have a serializer and deserializer for the Color3 object.
local Serializers = {
Color3 = function(Value)
return string.format("%d,%d,%d", Value.R, Value.G, Value.B)
end
}
local Deserializers = {
Color3 = function(Value)
return Color3.new(unpack(string.split(Value, ",")))
end
}
function Serialize(Data)
local SerializedData = {}
for Name, Element in pairs(Data) do
local DataType = typeof(DataType)
if Serializers[DataType] then
Element = DataType .. ":" .. Serializers[DataType](Value)
end
SerializedData[Name] = Element
end
return SerializedData
end
function Deserialize(SerializedData)
local Data = {}
for Name, Element in pairs(SerializedData) do
local DataType, Value = unpack(string.split(Element, ":")) -- example: Color3:0,1,0
if Deserializers[DataType] then
Element = Deserializers[DataType](Value)
end
Data[Name] = Element
end
return Data
end