Hello all! haven’t posted here in a while.
I’ve been working on a game and i have recently tried to implement data saving related stuff to it, but it has resulted in all forms of horrible outcomes
Some of them go as follows
- Data doesn’t save every time (this is why there’s a math.huge used in the sample, as a desperate fix that didn’t even fix anything)
- Data is name based, so if i rename one of the cars it will delete all data for the previous name of the car. (switching to updateasync could work???)
- The saving just doesn’t work right, god i beg of anyone to please help me with this
Here is a full code sample of the main data manager
local DataStoreService = game:GetService("DataStoreService")
local dataStore = DataStoreService:GetDataStore("PlayerStatsStore")
local Attempts = 1 -- Attempt Counter
local Success, Error -- do not mess with these, this is so we can access the pcall within the loop
-- GUIDE TO THE ORDER OF THE DATASTORE--
-- there is no guide
function tableFromFolder(folder: Folder) -- If you want ANY instance, replace with "Instance"
local folderTable = {}
-- Loop through each child
for _, child in folder:GetChildren() do
-- If it is a folder, use recursion to do the same and
-- convert its children into another table and use that
if child:IsA("Folder") then
folderTable[child.Name] = tableFromFolder(child)
-- If it is a value (such as StringValue or BoolValue), store its value directly
elseif child:IsA("ValueBase") then
folderTable[child.Name] = child.Value
end
end
-- Return the finished result
--print(folderTable)
return folderTable
end
local function saveData(player) -- The functions that saves data
local tableToSave = {}
tableToSave = tableFromFolder(player.CarData)
print(tableToSave)
print("WAITED")
repeat
print("WILL DO")
Success, Error = pcall(dataStore.SetAsync, dataStore, player.UserId, tableToSave) -- this is apparently the "better" way
Attempts += 1 -- Adds Attempt
print("DID")
if not Success then task.wait(2) end -- if failed, waits to try again (firing very fast can cause a queue)
until Success or Attempts > math.huge -- Conditions to Break upon
if Success then
print("Data has been saved!")
else
print("Data hasn't been saved!")
warn(Error)
end
end
game.Players.PlayerRemoving:Connect(function(player) -- When a player leaves the game
saveData(player) -- Save the data
end)
game:BindToClose(function() -- When the server shuts down
for _, player in pairs(game.Players:GetPlayers()) do
saveData(player) -- Save the data
end
end)
game.Players.PlayerAdded:Connect(function(player)
local DataFol = Instance.new("Folder")
DataFol.Name = "CarData"
DataFol.Parent = player
local children = game.ReplicatedStorage.Cars:GetChildren()
for i, child in ipairs(children) do
if child:IsA("Model") and child:FindFirstChild("CarColor") then
local Fol = Instance.new("Folder")
Fol.Name = child.Name
Fol.Parent = DataFol
local Dist = Instance.new("NumberValue")
Dist.Name = "Distance"
Dist.Parent = Fol
local ServDist = Instance.new("NumberValue")
ServDist.Name = "ServDistance"
ServDist.Parent = Fol
local Tire = Instance.new("StringValue")
Tire.Name = "Tire"
Tire.Parent = Fol
end
end
local data
local success, err = pcall(function()
data = dataStore:GetAsync(player.UserId)
end)
if success and data then
print("DATA")
print(data)
local children = player.CarData:GetChildren()
for i, child in ipairs(children) do
if child:IsA("Folder") then
print("found child: "..child.Name)
local cardata = data[child.Name]
print("CARDATA")
print(cardata)
if cardata ~= nil then
print("found data!")
child.Distance.Value = cardata["Distance"]
child.ServDistance.Value = cardata["ServDistance"]
child.Tire.Value = cardata["Tire"]
end
end
end
else
print("The player has no data!") -- The default will be set to 0
end
end)
There’s a lot of prints in an attempt to check if it’s working (it isn’t, “WILL DO” is the last one that prints in 99% of cases)
Any help with this please? i don’t know what else to do at this point, datastore related things are definitely not my field, thanks in advance.