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