Hey my game has just hit an issue, I noticed datastore 2 reverted a lot of data for no reason. They revert data from 1-7 days ago I’m not sure how to fix it. I only got one solution in mind that is adding auto save, but how do I auto save with tables?
Can you give your script?
(by the way, just put the save lines you use when a player leaves repeating each 10 seconds when a player joins, I make that on my games and I never get data problems!)
Basically i switched to datastore 2 after creating my game with datastore 1 so i had to check if datastore2 was nil and if so i would check if datastore 1 was nil if not then i would get the data with datastore 1 and save it on datastore 2 afterwards.
I just learned a bit of datastore 2 tables and this is my way of saving tables without having to write 15 lines of code just to change a simple value.
local data2 = MainKey:Get() print(data2) if data2 == nil then if data ~= nil and success then print("Recieved Data") local s, e = pcall(function() if data["TestSize"] == nil then if data["Size"] ~= nil then TestSize.Value = tostring(data["Size"]) print("Nil") end else TestSize.Value = data["TestSize"] print("NotNil") end if data["RealCoins"] == nil then if data["Coins"] ~= nil then RealCoins.Value = tostring(data["Coins"]) print("Nil") end else RealCoins.Value = data["RealCoins"] print("NotNil") end TotalSize.Value = data["TotalSize"] if tonumber(RealCoins.Value) / 1000 >= 1 then Coins.Value = Format(tonumber(RealCoins.Value), 1) else Coins.Value = tonumber(RealCoins.Value) end Kills.Value = data["Kills"] MaxHealth.Value = data["MaxHealth"] SizeVal2.Value = data["SizeVal2"] CoinsVal2.Value = data["CoinsVal2"] local s, e = pcall(function() HideAura.Value = data["HideAura"] AuraSFX.Value = data["AuraSFX"] end) Music.Value = data["Music"] SFX.Value = data["SFX"] Popups.Value = data["Popups"] Sell.Value = data["Sell"] Teleport.Value = data["Teleport"] if data["AquaCoins"] ~= nil then AquaCoins.Value = data["AquaCoins"] end if data["AquaSize"] ~= nil then AquaSize.Value = data["AquaSize"] end if data["AquaMaxHealth"] ~= nil then AquaMaxHealth.Value = data["AquaMaxHealth"] end MaxSizeDesc.Value = data["MaxSizeDesc"] Likes.Value = data["1.5mvisits"] Visits.Value = data["5klikes"] YoutuberCode.Value = data["doctorplanezonyt"] updatedelay.Value = data["updatedelay"] sorryfordataloss.Value = data["sorryfordataloss"] DNA.Value = data["DNA"] Tool.Value = data["Tool"] Rank.Value = data["Rank"] if data["AquaDNA"] ~= nil then AquaDNA.Value = data["AquaDNA"] end if data["AquaRank"] ~= nil then AquaRank.Value = data["AquaRank"] end if data["AquaTool"] ~= nil then AquaTool.Value = data["AquaTool"] end SecLeftOf10XSize.Value = data["SecLeftOf10XSize"] SecLeftOf30XSize.Value = data["SecLeftOf30XSize"] SecLeftOfAutoSell.Value = data["SecLeftOfAutoSell"] for i, v in pairs(RanksOwned:GetChildren()) do if game.StarterGui:WaitForChild("GameShop"):WaitForChild("MainFrame"):WaitForChild("Ranks"):WaitForChild("ToolList"):FindFirstChild(v.Name) ~= nil and data[v.Name] ~= nil then local s,e = pcall(function() v.Value = data[v.Name] end) end end for i, v in pairs(DnaOwned:GetChildren()) do if game.StarterGui:WaitForChild("GameShop"):WaitForChild("MainFrame"):WaitForChild("Dna1"):WaitForChild("ToolList"):FindFirstChild(v.Name) ~= nil and data[v.Name] ~= nil then local s,e = pcall(function() v.Value = data[v.Name] end) end end for i, v in pairs(ToolsOwned:GetChildren()) do if game.StarterGui:WaitForChild("GameShop"):WaitForChild("MainFrame"):WaitForChild("Tools1"):WaitForChild("ToolList"):FindFirstChild(v.Name) ~= nil and data[v.Name] ~= nil then local s,e = pcall(function() v.Value = data[v.Name] end) end end for i, v in pairs(Auras:GetChildren()) do if data[v.Name] ~= nil then local s,e = pcall(function() v.Value = data[v.Name] end) end end RobuxSpent.Value = data["RobuxSpent"] RebirthMultiplier.Value = data["RebirthMultiplier"] WalkSpeed.Value = data["WalkSpeed"] Concealed.Value = data["Concealed"] for i, v in pairs(ToolsOwned:GetChildren()) do if game.StarterGui:WaitForChild("AquaShop"):WaitForChild("MainFrame"):WaitForChild("Tools1"):WaitForChild("ToolList"):FindFirstChild(v.Name) ~= nil and data[v.Name] ~= nil then local s,e = pcall(function() v.Value = data[v.Name] end) if s then else warn(e) end end end for i, v in pairs(RanksOwned:GetChildren()) do if game.StarterGui:WaitForChild("AquaShop"):WaitForChild("MainFrame"):WaitForChild("Ranks"):WaitForChild("ToolList"):FindFirstChild(v.Name) ~= nil and data[v.Name] ~= nil then local s,e = pcall(function() v.Value = data[v.Name] end) if s then else warn(e) end end end for i, v in pairs(DnaOwned:GetChildren()) do if game.StarterGui:WaitForChild("AquaShop"):WaitForChild("MainFrame"):WaitForChild("Dna1"):WaitForChild("ToolList"):FindFirstChild(v.Name) ~= nil and data[v.Name] ~= nil then local s,e = pcall(function() v.Value = data[v.Name] end) if s then else warn(e) end end end if data["Height"] > 0 then Height.Value = data["Height"] Width.Value = data["Width"] Head.Value = data["Head"] Depth.Value = data["Depth"] else Height.Value = 1 end if data["AquaDnaPage2"] ~= nil then AquaDnaPage.Value = data["AquaDnaPage2"] else local HighestPage = 1 for i, v in pairs(DnaOwned:GetChildren()) do if v.Value == true then if game.StarterGui.AquaShop.MainFrame.Dna1.ToolList:FindFirstChild(v.Name) ~= nil then local Object = game.StarterGui.AquaShop.MainFrame.Dna1.ToolList[v.Name] if Object.Number.Value > HighestPage then HighestPage = Object.Number.Value end end end end print(HighestPage) AquaDnaPage.Value = HighestPage end if data["AquaToolPage"] ~= nil then AquaToolPage.Value = data["AquaToolPage"] else local HighestPage = 1 for i, v in pairs(ToolsOwned:GetChildren()) do if v.Value == true then if game.StarterGui.AquaShop.MainFrame.Tools1.ToolList:FindFirstChild(v.Name) ~= nil then local Object = game.StarterGui.AquaShop.MainFrame.Tools1.ToolList[v.Name] if Object.Number.Value > HighestPage then HighestPage = Object.Number.Value end end end end print(HighestPage) AquaToolPage.Value = HighestPage end local s, e = pcall(function() if data["DnaPage"] ~= nil then DnaPage.Value = data["DnaPage"] else local HighestPage = 1 for i, v in pairs(DnaOwned:GetChildren()) do if v.Value == true then if game.StarterGui.GameShop.MainFrame.Dna1.ToolList:FindFirstChild(v.Name) ~= nil then local Object = game.StarterGui.GameShop.MainFrame.Dna1.ToolList[v.Name] if Object.Number.Value > HighestPage then HighestPage = Object.Number.Value end end end end print(HighestPage) DnaPage.Value = HighestPage end end) local s, e = pcall(function() if data["ToolPage"] ~= nil then ToolPage.Value = data["ToolPage"] else local HighestPage = 1 for i, v in pairs(ToolsOwned:GetChildren()) do if v.Value == true then if game.StarterGui.GameShop.MainFrame.Tools1.ToolList:FindFirstChild(v.Name) ~= nil then local Object = game.StarterGui.GameShop.MainFrame.Tools1.ToolList[v.Name] if Object.Number.Value > HighestPage then HighestPage = Object.Number.Value end end end end print(HighestPage) ToolPage.Value = HighestPage end end) LoadingData.Value = false end) elseif success == true and data == nil then LoadingData.Value = false elseif success == false and data ~= nil then LoadingData.Value = true Player.PlayerGui:WaitForChild("PopUps"):WaitForChild("ErrorGettingData").Visible = true while LoadingData.Value == true do wait(1) for i = Retrysec.Value, 0, -1 do Player.PlayerGui.PopUps.ErrorGettingData.Text = "Data Error, Retrying in: "..i wait(1) end local success, errorMessage = pcall(function() if DataStoresService:GetRequestBudgetForRequestType(Enum.DataStoreRequestType.GetAsync) > 0 then data = PlayerData:GetAsync(Player.UserId) else repeat task.wait(1) until DataStoresService:GetRequestBudgetForRequestType(Enum.DataStoreRequestType.GetAsync) > 0 data = PlayerData:GetAsync(Player.UserId) end end) if success == true then Player.PlayerGui.PopUps.ErrorGettingData.Text = "Data Recived" Player.PlayerGui.PopUps.ErrorGettingData.TextColor3 = Color3.fromRGB(85, 255, 0) local s, e = pcall(function() if data["TestSize"] == nil then if data["Size"] ~= nil then TestSize.Value = tostring(data["Size"]) print("Nil") end else TestSize.Value = data["TestSize"] print("NotNil") end if data["RealCoins"] == nil then if data["Coins"] ~= nil then RealCoins.Value = tostring(data["Coins"]) print("Nil") end else RealCoins.Value = data["RealCoins"] print("NotNil") end TotalSize.Value = data["TotalSize"] if tonumber(RealCoins.Value) / 1000 >= 1 then Coins.Value = Format(tonumber(RealCoins.Value), 1) else Coins.Value = tonumber(RealCoins.Value) end Kills.Value = data["Kills"] MaxHealth.Value = data["MaxHealth"] SizeVal2.Value = data["SizeVal2"] CoinsVal2.Value = data["CoinsVal2"] local s, e = pcall(function() HideAura.Value = data["HideAura"] AuraSFX.Value = data["AuraSFX"] end) Music.Value = data["Music"] SFX.Value = data["SFX"] Popups.Value = data["Popups"] Sell.Value = data["Sell"] Teleport.Value = data["Teleport"] if data["AquaCoins"] ~= nil then AquaCoins.Value = data["AquaCoins"] end if data["AquaSize"] ~= nil then AquaSize.Value = data["AquaSize"] end if data["AquaMaxHealth"] ~= nil then AquaMaxHealth.Value = data["AquaMaxHealth"] end MaxSizeDesc.Value = data["MaxSizeDesc"] Likes.Value = data["1.5mvisits"] Visits.Value = data["5klikes"] YoutuberCode.Value = data["doctorplanezonyt"] updatedelay.Value = data["updatedelay"] sorryfordataloss.Value = data["sorryfordataloss"] DNA.Value = data["DNA"] Tool.Value = data["Tool"] Rank.Value = data["Rank"] if data["AquaDNA"] ~= nil then AquaDNA.Value = data["AquaDNA"] end if data["AquaRank"] ~= nil then AquaRank.Value = data["AquaRank"] end if data["AquaTool"] ~= nil then AquaTool.Value = data["AquaTool"] end SecLeftOf10XSize.Value = data["SecLeftOf10XSize"] SecLeftOf30XSize.Value = data["SecLeftOf30XSize"] SecLeftOfAutoSell.Value = data["SecLeftOfAutoSell"] for i, v in pairs(RanksOwned:GetChildren()) do if game.StarterGui:WaitForChild("GameShop"):WaitForChild("MainFrame"):WaitForChild("Ranks"):WaitForChild("ToolList"):FindFirstChild(v.Name) ~= nil and data[v.Name] ~= nil then local s,e = pcall(function() v.Value = data[v.Name] end) end end for i, v in pairs(DnaOwned:GetChildren()) do if game.StarterGui:WaitForChild("GameShop"):WaitForChild("MainFrame"):WaitForChild("Dna1"):WaitForChild("ToolList"):FindFirstChild(v.Name) ~= nil and data[v.Name] ~= nil then local s,e = pcall(function() v.Value = data[v.Name] end) end end for i, v in pairs(ToolsOwned:GetChildren()) do if game.StarterGui:WaitForChild("GameShop"):WaitForChild("MainFrame"):WaitForChild("Tools1"):WaitForChild("ToolList"):FindFirstChild(v.Name) ~= nil and data[v.Name] ~= nil then local s,e = pcall(function() v.Value = data[v.Name] end) end end for i, v in pairs(Auras:GetChildren()) do if data[v.Name] ~= nil then local s,e = pcall(function() v.Value = data[v.Name] end) end end RobuxSpent.Value = data["RobuxSpent"] RebirthMultiplier.Value = data["RebirthMultiplier"] WalkSpeed.Value = data["WalkSpeed"] Concealed.Value = data["Concealed"] for i, v in pairs(ToolsOwned:GetChildren()) do if game.StarterGui:WaitForChild("AquaShop"):WaitForChild("MainFrame"):WaitForChild("Tools1"):WaitForChild("ToolList"):FindFirstChild(v.Name) ~= nil and data[v.Name] ~= nil then local s,e = pcall(function() v.Value = data[v.Name] end) if s then else warn(e) end end end for i, v in pairs(RanksOwned:GetChildren()) do if game.StarterGui:WaitForChild("AquaShop"):WaitForChild("MainFrame"):WaitForChild("Ranks"):WaitForChild("ToolList"):FindFirstChild(v.Name) ~= nil and data[v.Name] ~= nil then local s,e = pcall(function() v.Value = data[v.Name] end) if s then else warn(e) end end end for i, v in pairs(DnaOwned:GetChildren()) do if game.StarterGui:WaitForChild("AquaShop"):WaitForChild("MainFrame"):WaitForChild("Dna1"):WaitForChild("ToolList"):FindFirstChild(v.Name) ~= nil and data[v.Name] ~= nil then local s,e = pcall(function() v.Value = data[v.Name] end) if s then else warn(e) end end end if data["Height"] > 0 then Height.Value = data["Height"] Width.Value = data["Width"] Head.Value = data["Head"] Depth.Value = data["Depth"] else Height.Value = 1 end if data["AquaDnaPage2"] ~= nil then AquaDnaPage.Value = data["AquaDnaPage2"] else local HighestPage = 1 for i, v in pairs(DnaOwned:GetChildren()) do if v.Value == true then if game.StarterGui.AquaShop.MainFrame.Dna1.ToolList:FindFirstChild(v.Name) ~= nil then local Object = game.StarterGui.AquaShop.MainFrame.Dna1.ToolList[v.Name] if Object.Number.Value > HighestPage then HighestPage = Object.Number.Value end end end end print(HighestPage) AquaDnaPage.Value = HighestPage end if data["AquaToolPage"] ~= nil then AquaToolPage.Value = data["AquaToolPage"] else local HighestPage = 1 for i, v in pairs(ToolsOwned:GetChildren()) do if v.Value == true then if game.StarterGui.AquaShop.MainFrame.Tools1.ToolList:FindFirstChild(v.Name) ~= nil then local Object = game.StarterGui.AquaShop.MainFrame.Tools1.ToolList[v.Name] if Object.Number.Value > HighestPage then HighestPage = Object.Number.Value end end end end print(HighestPage) AquaToolPage.Value = HighestPage end if data["DnaPage"] ~= nil then DnaPage.Value = data["DnaPage"] else local HighestPage = 1 for i, v in pairs(DnaOwned:GetChildren()) do if v.Value == true then if game.StarterGui.GameShop.MainFrame.Dna1.ToolList:FindFirstChild(v.Name) ~= nil then local Object = game.StarterGui.GameShop.MainFrame.Dna1.ToolList[v.Name] if Object.Number.Value > HighestPage then HighestPage = Object.Number.Value end end end end print(HighestPage) DnaPage.Value = HighestPage end if data["ToolPage"] ~= nil then ToolPage.Value = data["ToolPage"] else local HighestPage = 1 for i, v in pairs(ToolsOwned:GetChildren()) do if v.Value == true then if game.StarterGui.GameShop.MainFrame.Tools1.ToolList:FindFirstChild(v.Name) ~= nil then local Object = game.StarterGui.GameShop.MainFrame.Tools1.ToolList[v.Name] if Object.Number.Value > HighestPage then HighestPage = Object.Number.Value end end end end print(HighestPage) ToolPage.Value = HighestPage end LoadingData.Value = false end) Player.PlayerGui.PopUps.ErrorGettingData:TweenPosition(UDim2.new(0.637, 0,1.05, 0), Enum.EasingDirection.In, Enum.EasingStyle.Quad, 1) LoadingData.Value = false else Retrysec.Value *= 2 end end end end local data = ValuesFolderData:Get() if data ~= nil then for i, v in pairs(data) do if ValuesFolder:FindFirstChild(i) then ValuesFolder[i].Value = v end end end for i, v in pairs(ValuesFolder:GetChildren()) do v.Changed:Connect(function() local tab = savedata(ValuesFolder) ValuesFolderData:Set(tab) end) end local data = SettingsData:Get() if data ~= nil then for i, v in pairs(data) do if Settings:FindFirstChild(i) then Settings[i].Value = v end end end for i, v in pairs(Settings:GetChildren()) do v.Changed:Connect(function() local tab = savedata(Settings) SettingsData:Set(tab) end) end local data = DnaOwnedData:Get() if data ~= nil then for i, v in pairs(data) do if DnaOwned:FindFirstChild(i) then DnaOwned[i].Value = v end end end for i, v in pairs(DnaOwned:GetChildren()) do v.Changed:Connect(function() local tab = savedata(DnaOwned) DnaOwnedData:Set(tab) end) end local data = EquippedFolderData:Get() if data ~= nil then for i, v in pairs(data) do if EquippedFolder:FindFirstChild(i) then EquippedFolder[i].Value = v end end end for i, v in pairs(EquippedFolder:GetChildren()) do v.Changed:Connect(function() local tab = savedata(EquippedFolder) EquippedFolderData:Set(tab) end) end local data = RanksOwnedData:Get() if data ~= nil then for i, v in pairs(data) do if RanksOwned:FindFirstChild(i) then RanksOwned[i].Value = v end end end for i, v in pairs(RanksOwned:GetChildren()) do v.Changed:Connect(function() local tab = savedata(RanksOwned) RanksOwnedData:Set(tab) end) end local data = ToolsOwnedData:Get() if data ~= nil then for i, v in pairs(data) do if ToolsOwned:FindFirstChild(i) then ToolsOwned[i].Value = v end end end for i, v in pairs(ToolsOwned:GetChildren()) do v.Changed:Connect(function() local tab = savedata(ToolsOwned) ToolsOwnedData:Set(tab) end) end for i, v in pairs(ValuesFolder:GetChildren()) do local tab = savedata(ValuesFolder) ValuesFolderData:Set(tab) end for i, v in pairs(Settings:GetChildren()) do local tab = savedata(Settings) SettingsData:Set(tab) end for i, v in pairs(DnaOwned:GetChildren()) do local tab = savedata(DnaOwned) DnaOwnedData:Set(tab) end for i, v in pairs(EquippedFolder:GetChildren()) do local tab = savedata(EquippedFolder) EquippedFolderData:Set(tab) end for i, v in pairs(RanksOwned:GetChildren()) do local tab = savedata(RanksOwned) RanksOwnedData:Set(tab) end for i, v in pairs(ToolsOwned:GetChildren()) do local tab = savedata(ToolsOwned) ToolsOwnedData:Set(tab) end Datastore 1 and Datastore 2 don’t storage in same way, so when you change to datastore 2, you lose all things in Datastore 1, so do that way:
Create a new key for Datastore 2.
And do to when the data of the person is nil, you open datastore 1 and see if has data on the old datastore, if has, put the old data inside the datastore 2, so you convert the old data to the new datastore.
You should cut down on the amount of unnecessary code you are writing, and not use Datastore2 as it’s unreliable. I suggest using ProfileService; it protects against data loss, patches item duping exploits, and has a global update system.
If you’re interested in switching, take a look here.
Any specific examples of DataStore2 being unreliable? In my two years of using it I have never received reports of data loss because of DS2, and the creator even says himself that he has not received a report of data loss with DS2. Any reports of data loss I’ve received using DS2 were down to my own faults in code.
i can’t afford to loose the players data sadly, as i got over 600 ccu.
Is there any ways around this?
I said what you could do, I think you didn’t read (or you didn’t understood it, maybe)
Create a new key for the data of the Datastore 2 script
Then each time the data is loaded, check if it’s nil, if it’s load the datastore 1, so you can check if the player had data before the datastore2 was added on your game.
If he had data on datastore 1, get all the data and save it on the datastore 2, so it converts the data to the new datastore.
That’s what i’m doing right now.
I suggest you use ProfileService to store data, it is really better than DataStore v2.
Home page: ProfileService
Setting-up: Setting up - ProfileService
Basic usage: Basic Usage - ProfileService
Youtube tutorial: Use Profile Service as Your Data Store! Roblox Development - YouTube
API: API - ProfileService
