DataStore2 causing data loss

Hi! A ton of players have been complaining that they have been experiencing data loss in my game. Sometimes when they leave and rejoin, they get previously saved values, resulting in random loss of cash/data.

Anyone can help me figure this out? I have tried looking at other DataStore2 examples and I don’t see what’s wrong with mine.

Code:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

local DataStore2 = require(script:WaitForChild("DataStore2"))
local LevelModule = require(script:WaitForChild("Level"))
local PayoutsModule = require(script:WaitForChild("Payouts"))
local DaysCalModule = require(script:WaitForChild("DaysCalculator"))

local DataVars = {
	--General
	["Cash"] = {"NumberValue", 100},
	["Hunger"] = {"NumberValue", 100},
	["Level"] = {"NumberValue", 1},
	["XP"] = {"NumberValue", 0},
	["CO2"] = {"NumberValue", 0},
	["Days"] = {"NumberValue", 1},
	["RewardTime"] = {"NumberValue", 0},
	--Phone
	["PhoneR"] = {"NumberValue", 87},
	["PhoneG"] = {"NumberValue", 88},
	["PhoneB"] = {"NumberValue", 87},
	--Cars
	["Mercedes-Benz S Class"] = {"BoolValue", false},
	["Rolls-Royce Phantom"] = {"BoolValue", false},
	["Honda Civic Hatchback"] = {"BoolValue", false},
	["Tesla Cybertruck"] = {"BoolValue", false},
	["Tesla Roadster"] = {"BoolValue", false},
	["Toyota Prius"] = {"BoolValue", false},
	["Hyundai Avante Sedan"] = {"BoolValue", false},
	["Lamborghini Aventador SV"] = {"BoolValue", false},
	--Misc Vehicles
	["Motorbike"] = {"BoolValue", false}
}

local DataStoreMainKey = game:GetService("ServerStorage"):WaitForChild("DataStoreMainKey")
DataStore2.Combine(DataStoreMainKey.Value, "Cash", "Hunger", "Level", "XP", "CO2", "Days", "RewardTime", "PhoneR", "PhoneG", "PhoneB", "Mercedes-Benz S Class","Rolls-Royce Phantom","Honda Civic Hatchback","Tesla Cybertruck","Tesla Roadster","Toyota Prius","Hyundai Avante Sedan","Lamborghini Aventador SV","Motorbike")

function addPlayer(player)
	local DataFolder = Instance.new("Folder", player)
	DataFolder.Name = "Data"
	local CarFolder = Instance.new("Folder", DataFolder)
	CarFolder.Name = "Cars"
	
	--Loop to make rep amounts
	for key, defaultval in pairs(DataVars) do
		local keystore = DataStore2(key, player)
	
		local RepAmt
		if defaultval[1] == "BoolValue" then
			RepAmt = Instance.new(defaultval[1], CarFolder)
			RepAmt.Name = key
		else
			RepAmt = Instance.new(defaultval[1], DataFolder)
			RepAmt.Name = key
		end
		
		local function UpdateRepAmt(updatedValue)
			RepAmt.Value = keystore:Get(updatedValue)
		end
	
		UpdateRepAmt(defaultval[2])
		keystore:OnUpdate(UpdateRepAmt)
		print(key.." loaded")
		end
end



for _,player in pairs(Players:GetPlayers())do
	coroutine.wrap(function()
  		addPlayer(player)
	end)()
end

Players.PlayerAdded:Connect(addPlayer)


1 Like

Firstly, you should not have different data stores for each item that is ownable. Moreover, you shouldn’t be using Instances to keep track of data.

Unnecessary. If the instance exists (Which you’re yielding for with WaitToChild) then the Value is already accessible. (that is unless you’re defining it with another script, which you can avoid by just creating the instance in that script). Aditionally, you should avoid wait().

You should use indentation here.

You can use corountine.wrap(addPlayer)(player) here to avoid unnecessary yielding. Furthermore, you should connect your event before this to prevent race conditions.

connect is deprecated. Use Connect instead.

Its being saved as combined datastore, not individually.

Also, thanks for the other tips

Yes, but as you can see here, that’s still a bad setup (and it makes it harder to deal with new/old items!!)

1 Like

Thanks! Will try this and see if it works

I did everything you said and I don’t think I’ll add serialization yet because I’ll need to redo everything. But it should work properly even without serialization. Players are still losing data :confused: