How to update Datastore that already contains user data but without clearing it?

I’m having an issue where I find myself needing to add new lines to a datastores saved table that determines local user settings. I want to make it so I can update the user data without having to remove the currently set settings in the datastore with the new template.

For example, let’s just say this table was what I had my datastore start out as, and the user set both options to true.

local Template = {
	LowGraphics = false,
	NoParticles = false,
	-- etc
}

My issue is, if I were to add more options below, new users would have these options, but older players wouldn’t. I don’t know how to update the older players Datastores without nuking their saved settings.

Any help would be greatly appreciated.

I need to know this too because it keeps making new keys in my datastore. I’m using setasnyc but it keeps adding new keys.

Mine isn’t exactly that problem. My issue is that I add new features to my game that players might want to disable, and the only way for the game to remember that is datastores. So when I add a new feature, I need to update the settings template to reflect that new feature.

For players that have already played the game, their datastore will cause an error because they have an older version of my template while new players have no issues.

I had a similar issue a while back, I solved it by creating a function that would verify player saved data and add any new information to the table that wasn’t there:

local function VerifyPlayerData(PlrData)
	
	if PlrData.LowGraphics==nil then PlrData.LowGraphics=false end
	if PlrData.NoParticles==nil then PlrData.NoParticles=false end
	if PlrData.A_NEW_OPTION==nil then PlrData.A_NEW_OPTION=false end -- Set to default Value
	return PlrData
	
end

local function GetPlayerData(Player)
	
	local MyPlrData= -- Read data from datastore
	local VerifiedData=VerifyPlayerData(MyPlrData)
	-- VerifiedData now contains old player data and any new entries you've added to the table
end

You can now add new entries to the savefile by just adding them in the VerifyData function.

3 Likes

Okay, I’ll test that right now to verify if this solves my problem. I have high hopes for this.

This doesn’t seem to work correctly with my actual setup, it does follow the same principle, just different value types.


image

The above images of my code show that I did indeed add one more value, one to the template, and one to the verifier, however when I check my data as a pre-existing player, the new setting is nowhere to be found

Edit:
I forgot to include that I do end up saving the updated table, THEN I make changes to the game for the player so it saves their data first before continuing.

Edit 2:
Nevermind I just noticed a mistake I made. I will double check this and make a third edit regarding the issue

Edit 3:

I think this might actually be working now? It prints the new setting that I just added to the table, so I think your script works. I have one last question though before I mark solution…

How would I make sure it DOESN’T save even if the datastore has the same value? Everytime the player respawns it saves the data even though the data is already the same in the datastore. This could cause request queue size fill, and I want to prevent that.

Thanks in advance!

I don’t understand fully, are you talking about not saving the file if no extra fields are added during the verify process? If that’s the case you could just add a bool value in the return to let you know if any of the fields were added during verifying:

local function VerifyPlayerData(PlrData)
	
    local TableUpdated=false
	if PlrData.LowGraphics==nil then PlrData.LowGraphics=false TableUpdated=true end
	if PlrData.NoParticles==nil then PlrData.NoParticles=false TableUpdated=true end
	if PlrData.A_NEW_OPTION==nil then PlrData.A_NEW_OPTION=false TableUpdated=true end -- Set to default Value
	return PlrData,  TableUpdated
	
end

--Calling the function:

local VerifiedTable, Changes = VerifyPlayerData(SavedData)
if Changes==true then
-- Save New Data
end

It’s not the verifier itself I have issues with, it’s rather saving the same data again.

Let’s say I have this:

local Hello = {
ThisIsEpic = true,
ThisIsNotEpic = false,
}

and then the verifier makes sure I have this:

local Hello = {
ThisIsEpic = true,
ThisIsNotEpic = false,
ThisIsAlsoNotEpic = false,
}

How would I check if the datastore already saved this new table? Do I just do

if OldTable == NewTable then
-- do nothing
end

?

Im confused here, updating a datastore will keep previously saved data. Adding a new line won’t do nothing as long as you dont clear the data.

Also if this remains an issue why dont you create a new datastore all together, and check the data from the old datastore and put those values into the new one.

I’ve cleared my data several times. I’m using SetAsync(), so it doesn’t take previous actions into account like UpdateAsync() does.

I want to be able to NOT set the exact same data that the datastore already contains using an if check. I’m confused as to how that is difficult to understand.

1 Like

You want to check the values?




SavingValues =  {
Idk.Value
Idk2.Value
}

NewData = {}

If SavingValues[1] == 1 then
-- do something for if Idk.Value == 1
else
--do something if it doesn't
end


If SavingValues[2] == 1 then
-- do something for if Idk2.Value == 1
else
--do something if it doesn't
end

No, I want to check if the outdated table is the exact same as the updated table. It appears when I do so, after updating the datastore it says it’s the same table and will not update, which seems to be what I want.

I’m unsure if this is the right way, but it seems to be what I needed.

Here is the post that helped me solve this:

Reason I’m marking this as solution is because I’m merging the solution for my main issue, and my other issue so that others can see it. Thanks for the help.

local table1 = {}
local table2 = {}

print(table1 == table2) --false

Table values will always differ from one another even if two or more tables contain the same values, in the same order. This is because they are stored at different addresses in memory. Here’s a recursive function I just wrote which returns true if two tables are equal.

local EmptyTable1 = {}
local EmptyTable2 = {}

local function CompareTwoTablesRecursive(Table1, Table2)
	local Table1Keys, Table2Keys, Table1Values, Table2Values = {}, {}, {}, {}
	
	for Key, Value in pairs(Table1) do
		table.insert(Table1Keys, Key)
		table.insert(Table1Values, Value)
	end
	
	for Key, Value in pairs(Table2) do
		table.insert(Table2Keys, Key)
		table.insert(Table2Values, Value)
	end
	
	if #Table1Keys == #Table1Values then
		local Length = (#Table1Keys + #Table2Keys)/2
		for Index = 1, Length do
			local Key1, Key2, Value1, Value2 = Table1Keys[Index], Table2Keys[Index], Table1Values[Index], Table2Values[Index]
			
			if type(Key1) == "table" and type(Key2) == "table" then
				if not CompareTwoTablesRecursive(Key1, Key2) then
					return false
				end
			elseif Key1 ~= Key2 then
				return false
			end
			
			if type(Value1) == "table" and type(Value2) == "table" then
				if not CompareTwoTablesRecursive(Value1, Value2) then
					return false
				end
			elseif Value1 ~= Value2 then
				return false
			end
		end
		return true
	else
		return false
	end
end

print(CompareTwoTablesRecursive(EmptyTable1, EmptyTable2)) --true
2 Likes

Oh thanks for that. I think I’ll import that function into a module since I don’t want my script being taken up with that huge script that you made. I already did find my own solution but I suppose I’ll use this one, seems more ethical.