-
What do you want to achieve? Keep it simple and clear!
I want to create a recursive datastore saving system so that it will save any values inside of values, etc. -
What is the issue? Include screenshots / videos if possible!
The saving system itself works, but for some reason it won’t load any values that are supposed to be in other values. -
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I’ve tried printing for starts, but I am completely confused as to why it prints nothing in the console when I try to print a table.
It saves and when you join the game it successfully gets the save:
You check the StatsFolder and none of the values that were meant to be inside of other values are there.
What it’s supposed to look like when loaded:
What it looks like:
Here is my script: (the issue is in the parse()
function from lines 65 - 129.
-- CentiDev :)
local dataStoreService = game:GetService("DataStoreService")
local dataStoreVersion = 1.4
local dataStore = dataStoreService:GetDataStore("DataStoreV"..dataStoreVersion)
local httpService = game:GetService("HttpService")
local defaultData = {
Money = 0,
Exp = 0,
Donated = 0
}
local function len(t)
local n = 0
for _ in pairs(t) do
n += 1
end
return n
end
local function removeEntry(t, e)
local n = 0
for i, v in pairs(t) do
n += 1
if i == e then
table.remove(t, n)
end
end
end
local function find(t, e)
for i, v in pairs(t) do
if i == e then
return true
else
return false
end
end
end
local function checkRealValue(valueName)
for i, v in pairs(defaultData) do
if i == valueName then
return typeof(v)
end
end
end
local function returnIndexValue(index, tbl)
-- haha i look liek hackr man with all these functions
local n = 0
for i, v in pairs(tbl) do
v += 1
if n == index then
return i, v
end
end
end
local serverCloseReady = Instance.new("BindableEvent")
local function parse(i, v, folder)
-- yay it works
if typeof(v) == "number" then
local inst = Instance.new("NumberValue")
inst.Name = i
inst.Value = v
inst.Parent = folder
elseif typeof(v) == "table" then
local Type = checkRealValue(i)
if Type == "number" then
local inst = Instance.new("NumberValue")
inst.Name = i
inst.Value = v.Value
inst.Parent = folder
print(unpack(v))
for x, y in pairs(v) do
if x ~= "Value" then
parse(x, y, inst)
end
end
elseif Type == "boolean" then
local inst = Instance.new("BoolValue")
inst.Name = i
inst.Value = v.Value
inst.Parent = folder
for x, y in pairs(v) do
if x ~= "Value" then
parse(x, y, inst)
end
end
elseif Type == "string" then
local inst = Instance.new("StringValue")
inst.Name = i
inst.Value = v.Value
inst.Parent = folder
for x, y in pairs(v) do
if x ~= "Value" then
parse(x, y, inst)
end
end
elseif Type == "table" then
local inst = Instance.new("NumberValue")
inst.Name = i
inst.Value = v.Value
inst.Parent = folder
for x, y in pairs(v) do
parse(x, y, inst)
end
end
elseif typeof(v) == "boolean" then
local inst = Instance.new("BoolValue")
inst.Name = i
inst.Value = v
inst.Parent = folder
elseif typeof(v) == "string" then
local inst = Instance.new("StringValue")
inst.Name = i
inst.Value = v
inst.Parent = folder
end
end
local function setupPlayer(plr, data)
if data then
print(len(data), len(defaultData))
print(httpService:JSONEncode(data))
if len(data) == len(defaultData) then
for i, v in pairs(data) do
parse(i, v, plr.StatsFolder)
end
-- ur mum
elseif len(data) < len(defaultData) then
print("More datavalues added!")
for y, x in pairs(defaultData) do
if not find(data, defaultData) then
parse(y, x, plr.StatsFolder)
end
end
elseif len(data) > len(defaultData) then
print("Datavalues removed!")
for i, v in pairs(data) do
if not find(defaultData, i) then
print("Removing indigent value: "..i)
removeEntry(data, i)
else
parse(i, v, plr.StatsFolder)
end
end
end
else
setupPlayer(plr, defaultData)
print("Data is nil, using default data.")
end
print("Done setting up data!")
end
game.Players.PlayerAdded:Connect(function(plr)
local statsFolder = Instance.new("Folder")
statsFolder.Name = "StatsFolder"
statsFolder.Parent = plr
local data
local succ, amogus = pcall(function()
local json = dataStore:GetAsync(plr.UserId)
data = httpService:JSONDecode(json)
end)
-- haha lol amogus funny totally not overrated sussy 😳
print(succ, amogus)
if succ then
setupPlayer(plr, data)
print("Success getting data!\nSetting up data...")
else
for i = 1,3,1 do
print("Retrying data...")
wait(1)
local succ, amogus = pcall(function()
local json = dataStore:GetAsync(plr.UserId)
if json then
data = httpService:JSONDecode(json)
end
end)
if succ then
setupPlayer(plr, data)
break
end
end
setupPlayer(plr, defaultData)
end
end)
local function recursiveSave(i, v, data)
if #v:GetChildren() == 0 then
if v:IsA("NumberValue") then
local tbl = {}
tbl["Value"] = v.Value
data[v.Name] = tbl
elseif v:IsA("BoolValue") then
local tbl = {}
tbl["Value"] = v.Value
data[v.Name] = tbl
elseif v:IsA("StringValue") then
local tbl = {}
tbl["Value"] = v.Value
data[v.Name] = tbl
elseif v:IsA("Folder") then
local tbl = {}
data[v.Name] = tbl
end
else
if v:IsA("NumberValue") then
local tbl = {}
for y, x in pairs(v:GetChildren()) do
tbl = recursiveSave(y, x, tbl)
tbl["Value"] = v.Value
end
data[v.Name] = tbl
elseif v:IsA("BoolValue") then
local tbl = {}
for y, x in pairs(v:GetChildren()) do
tbl = recursiveSave(y, x, tbl)
tbl["Value"] = v.Value
end
data[v.Name] = tbl
elseif v:IsA("StringValue") then
local tbl = {}
for y, x in pairs(v:GetChildren()) do
tbl = recursiveSave(y, x, tbl)
tbl["Value"] = v.Value
end
data[v.Name] = tbl
elseif v:IsA("Folder") then
local tbl = {}
for y, x in pairs(v:GetChildren()) do
tbl = recursiveSave(y, x, tbl)
end
data[v.Name] = tbl
end
end
return data
end
game.Players.PlayerRemoving:Connect(function(plr)
if plr.StatsFolder:GetChildren() ~= 0 then
local data = {}
for i, v in pairs(plr.StatsFolder:GetChildren()) do
data = recursiveSave(i, v, data)
end
local encoded = httpService:JSONEncode(data)
local succ, amogus = pcall(function()
dataStore:SetAsync(plr.UserId, encoded)
end)
print(succ, amogus)
if succ then
print(plr.Name.."\n"..encoded)
else
for i = 1,3,1 do
wait(1)
local succ, amogus = pcall(function()
dataStore:SetAsync(plr.UserId, encoded)
end)
print(plr.Name.."\n"..encoded.."\nDone with "..i.." tries left!")
end
end
else
dataStore:SetAsync(plr.UserId, nil)
end
serverCloseReady:Fire()
end)
game:BindToClose(function()
serverCloseReady.Event:Wait()
-- el manana is a good song fite me
end)
--[[ I am very handome aren't I?
........,,,,,,,,,,,,,,.
,,,,,,,,,,,,,,,,,,,,,,,,..
,,,,,,,,,,,,,,*********,,,..
,,,,,*,******************,,,..
,**************************,,,..
*****************************,,,...
******************************,,,,...
********************************,,,....
******************//**/**********,,,,,...
**************///////////////******,,,,,...
**********//////////////////////******,,,,...
******/////////////////////////////*****,,,,....
*****////////////////////////////(((*,/(*/**,,*,,.
*********//////////////////((((##((((((/((/(//**,,,.,,
**********//////////////(###%%%%%%%######(((((((/,,,, ,*,
*************/////////#%#%%%%#%%%%%%%##%#####(((((**,.. .*,.
***************/////(%(#%#%%%%%%%%%%%%%%########(((/*,... *,
****************///###%%%#%%%%%%%%%%%%%%%%%%#####((((/,.*. .,.
****************//%%#%%%###(#%%###%%##%%%%%%%######(///*,/.,.***,.
****************/%%%#%#%#(/*/%%##(#%#####%%%%%%##((##(/////.,,//*.,,
***************/%%&&#####(****/#%###%%###((##%%%%####((,,.*,*/*//...*
**************(##%%%%%#%#/***((##%%%###(((((########(((/, ,((((////.,*.
*************###%%%#%%&%(***/((###%%%%#(//((##%%#%%%##((/,.(#((((((/,/*...
,***********%#%%%%%#&&&%(***//(/##%#%#((/////(######(/*,..,(##(#((((((/,,,..
,********/(%#%%%%%%%&&&&(*,,,**///((///***//,,*///////**,,,#%%##(#####(**,,.,***
/////*//#&%%%%%%%%%&&&&&&********/////****///*,/((((/////**%%%%%######(***//**,,
((#%(%&%%%%%%&&&&&&%&&&&&(*******//(((/**//(((/,(##(((/////%%%%%%%%%%%#/*/((***,
#%%%%%%%&&&&&&&%&&&&&&&&&&/*****///(((((%#(##%%####(((((//#&&&&&&&&%%%*(/#((/***
%%%&&&&&&&&&&&@@@@@&@&&&&&#/***///////////(##((((###((((((&&&&&&&%&%%%%#(/*/(***
&&&&%&%&&&&&@@@&&@&&&&&&&%%////////////*/((((#(*(####((((#&%&&&&&&&&&&&&&%%%#(*.
%&&&&&&&&&@@@@&&@&%%%%%%%%%#///////(##%%%%%%%%%%&&%###((#&&&%&&&&&&&&&&&&&&&&%%%
&&&&&&&&&@@@@&@&&%%%%%%%%%%%%/////((((((##%%%%%%########&&&&%&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&%#%%%%%%%%%%&&((//((((((################%&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&@&&&&&&@&&&&&&&&&@@@@&&%/((((/////((######((##%#(#&&&&&@&&&&&&&&&&&&&&&&&&
&&&&&%&&&&&&&&&&&&&&@@&&&&&&(///(((((//(((########%%##(/&&&@@@&&&&&&&#&&&&&&&&&&
%&%&%&@@@&&&&&@&@@@@@@@&&&&#////(((((######%%%%%%%%%##(/&&&&&&&&&&&&&&&&&&&&&&&&
#&&&&@@&@@@@@@&&@@@@@@@@@&&(/////(((((######%%%%%%%###(&&&&@@&&&&&&&&&&&&&&&&&&&
&&&&@@@@@@@@@@&@@@@@@@@@&&%(////////((((###########(((%&&&&&@&&&&&@@&&&%&&&&%%&&
&&&&@@@@@@@@@&@@@@@@@@@@&&&(/////////(((((((((((///**#&&&&&&@@&&&&&@@@&&&%&&%%&&
&&&&&&@@@@@&@@@@@@@@@@@@@&&&(/////////////////////**#&&&@&&&@@@&&&&&&@@@&&&&&&(&
&&&&&&@@@@@&@@@@@@@@@@@@@@&&&&#(//////////////***/#&&&&@@&&&&@@@&&&&&&@@@&&&&&&&
&&&&&&&@@@&@@@@@@@@@@@@@@@&&&&&&&&&&&&(////////&&&&&&&&@&&&&&@@@@&&&&&&&&&&&&&&&
&&&&&&&&@&@@@@@@@@@@@@@@@@@&&@&&&&&&@@@&&&&&&@@@@@&&&&@@&&&&&&&@@@&&&&&&&&&&&&&&
]]--