i want to go through a folder full of a varying amount of values. Basically go through the values and save the actual value and then the name of each one. I have never been good with data stores and especially when saving and loading more than one value. Thank you for any help and here is a script i have for saving one value. Basically i want to turn it into a script for saving more than one value
-- this script works for saving one value and i want to have one like this that can go through a folder and save all the values in the folder and then load them
local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("CoinsDataStore")
local PlayersToSave = {} -- setup a table to hold players that the data has changed on
local TimeBetweenAutoSave = 60 -- the time between each autosave checking if they are in table above to save
function SavePlayersData(player)
--- it won't save unless the coins loaded correctly so that it doesn't overwrite the save with 0
if player.Currencies.coins.LoadedCorrectly.Value == true then
local key = "Coins_"..player.UserId
local data = player.Currencies:FindFirstChild("coins").Value
local success, errormessage = pcall(function()
DataStore:SetAsync(key, data)
end)
if success then
else
print("Error")
warn(errormessage)
-- give the player a pop up warning them it failed
local ErrorMessage = game.ReplicatedStorage.Extras.Message:Clone()
ErrorMessage.Parent = player.PlayerGui.PopUps
ErrorMessage.Message.Text = ("Coins failed to save. This is usually due to Roblox data stores failing. If you leave now, your data from this play session may be lost")
end
end
end
game.Players.PlayerAdded:Connect(function(player)
local key = "Coins_"..player.UserId
-- Load data
local data
local success, errormessage = pcall(function()
data = DataStore:GetAsync(key) -- if data has never been set this will return successful and data will be nil
end)
local Value = player.Currencies.coins
if success then
-- set a value to true so that the game knows it can save without overwriting data with 0
player.Currencies.coins.LoadedCorrectly.Value = true
Value.Value = data or 0 -- this will set a default to the value incase they don't have any data which would be nil
-- Set value equal to the data
else
-- a popup telling the player the coins didn't load
local ErrorMessage = game.ReplicatedStorage.Extras.Message:Clone()
ErrorMessage.Parent = player.PlayerGui.PopUps
ErrorMessage.Message.Text = ("Coins failed to load. This is usually due to Roblox data stores failing. You might have to rejoin")
end
Value.Changed:Connect(function() -- this catches if the value changed and it will then add it to the autosave table for the next loop to save the data
table.insert(PlayersToSave,player) -- adds the player to this table because their data has changed
end)
end)
-- Save when leaving
game.Players.PlayerRemoving:Connect(function(player)
if table.find(PlayersToSave,player) then
SavePlayersData(player) -- save when they leave if it can sometimes this doesn't save in studio
table.remove(PlayersToSave,table.find(PlayersToSave,player)) -- after save then remove them from the table
end
end)
-- Auto save
while true do -- this autosave loop only saves player data if it has changed
wait(TimeBetweenAutoSave)
spawn(function() -- spawn incase of error
for _, player in ipairs(PlayersToSave) do -- go through all the players in the PlayersToSave because their data changed and save them
SavePlayersData(player)
table.remove(PlayersToSave,table.find(PlayersToSave,player))
-- after save then remove player from table
end
end)
end
local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("ValuesDataStore")
local PlayersToSave = {}
local TimeBetweenAutoSave = 60
local Players = game:GetService("Players")
local RS = game:GetService("ReplicatedStorage")
local Extras = RS:WaitForChild("Extras")
local Message = Extras:WaitForChild("Message")
function SavePlayersData(player)
local playerStats = player:WaitForChild("PlayerStats")
if #playerStats:GetChildren() >= 1 then
local key = "Stats_"..player.UserId
local statsTable = {}
for _, stat in ipairs(playerStats:GetChildren()) do
statsTable[stat.Name.."|"..stat.ClassName] = stat.Value
end
if #statsTable >= 1 then
local success, errormessage = pcall(function()
DataStore:SetAsync(key, statsTable)
end)
if success then
print("Successfully saved!")
else
print("Save failed!")
warn(errormessage)
local ErrorMessage = Message:Clone()
ErrorMessage.Parent = player.PlayerGui.PopUps
ErrorMessage.Message.Text = ("...")
end
end
end
end
Players.PlayerAdded:Connect(function(player)
local playerStats = Instance.new("Folder")
playerStats.Name = "PlayerStats"
playerStats.Parent = player
local key = "Stats_"..player.UserId
local dataStats
local success, errormessage = pcall(function()
dataStats = DataStore:GetAsync(key)
end)
if success then
print("Successfully saved!")
else
print("Save failed!")
print("Error")
warn(errormessage)
local ErrorMessage = Message:Clone()
ErrorMessage.Parent = player.PlayerGui.PopUps
ErrorMessage.Message.Text = ("...")
end
if type(dataStats) == "table" then
for field, value in pairs(dataStats) do
local name = string.split(field, "|")[1]
local class = string.split(field, "|")[2]
local instanceValue = Instance.new(class)
instanceValue.Parent = playerStats
instanceValue.Value = value
end
end
end)
Players.PlayerRemoving:Connect(function(player)
SavePlayersData(player)
end)
game:BindToClose(function()
for _, player in ipairs(Players:GetPlayers()) do
SavePlayersData(player)
end
end)
while task.wait(TimeBetweenAutoSave) do
for _, player in ipairs(Players:GetPlayers()) do
SavePlayersData(player)
end
end
Stayed as true as possible to the original source material.
Thanks palπ I made some changes to it to but your script helped a lot. I think I almost, partly understand table saving now. Here is my final script just for anyone looking at this in the future
local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("AvatarDataStore")
local PlayersToSave = {}
local TimeBetweenAutoSave = 60
local Players = game:GetService("Players")
local RS = game:GetService("ReplicatedStorage")
local Extras = RS:WaitForChild("Extras")
local Message = Extras:WaitForChild("Message")
function SavePlayersData(player)
local Wearing = player:WaitForChild("Wearing")
local key = "Wearing_"..player.UserId
local itemTable = {}
for _, item in ipairs(Wearing:GetChildren()) do
itemTable[item.Name.."|"..item.ClassName] = item.Value
end
local success, errormessage = pcall(function()
DataStore:SetAsync(key, itemTable)
end)
if success then
else
print("Avatar save failed")
warn(errormessage)
local ErrorMessage = Message:Clone()
ErrorMessage.Parent = player.PlayerGui.PopUps
ErrorMessage.Message.Text = ("Your avatar failed to save. This will not cause you to lose any items. You may have to reapply them to your avatar though")
end
end
Players.PlayerAdded:Connect(function(player)
local key = "Wearing_"..player.UserId
local itemsEquipped
local success, errormessage = pcall(function()
itemsEquipped = DataStore:GetAsync(key)
end)
if success then
else
print("Avatar failed to load!")
warn(errormessage)
local ErrorMessage = Message:Clone()
ErrorMessage.Parent = player.PlayerGui.PopUps
ErrorMessage.Message.Text = ("Your avatar failed to load")
end
if type(itemsEquipped) == "table" then
for field, value in pairs(itemsEquipped) do
local name = string.split(field, "|")[1]
local class = string.split(field, "|")[2]
local instanceValue = Instance.new(class)
instanceValue.Parent = player.Wearing
instanceValue.Value = value
instanceValue.Name = name
end
end
end)
Players.PlayerRemoving:Connect(function(player)
SavePlayersData(player)
end)
while task.wait(TimeBetweenAutoSave) do
for _, player in ipairs(Players:GetPlayers()) do
SavePlayersData(player)
end
end
game:BindToClose(function()
if not game:GetService("RunService"):IsStudio() and #Players:GetPlayers() > 1 then
for _, player in ipairs(Players:GetPlayers()) do
SavePlayersData(player)
end
end
end)