Table Data Corrupting when new Datatype is added

Basically, I’m making a quest system with tables, But when I try and add a new quest to the pool of quests, It doesn’t add it, Until I change the data key, However When I change the data key, It wipes existing data. Is there a way to circumvent this?

local function QuestsData()
	return {
		Play3Maps = {
			Value = false;
			CodeName = "PLAY3MAPS";
			InProgress = false;
			NameQuest = "Play 3 Maps!";
			Description = "Play any 3 maps in game for a reward.";
			RewardInCoins = nil;
			RewardInXP = 100
		};
		Walk100Studs = {
			Value = false;
			CodeName = "Walk100Studs";
			InProgress = false;
			NameQuest = "Walk 100 Studs";
			Description = "Walk 100 studs in any given direction.";
			RewardInCoins = 25;
			RewardInXP = nil
		};
	}
end
4 Likes

Could you show your data saving script? Or whichever script is utilizing this Data return function?

local function QuestsData()
	return {
		Play3Maps = {
			Value = false;
			CodeName = "PLAY3MAPS";
			InProgress = false;
			NameQuest = "Play 3 Maps!";
			Description = "Play any 3 maps in game for a reward.";
			RewardInCoins = nil;
			RewardInXP = 100
		};
		Walk100Studs = {
			Value = false;
			CodeName = "Walk100Studs";
			InProgress = false;
			NameQuest = "Walk 100 Studs";
			Description = "Walk 100 studs in any given direction.";
			RewardInCoins = 25;
			RewardInXP = nil
		};
	}
end

local function loadData(p)
	local data
	local Success, Error = pcall(function() data = PlayerData:GetAsync("data:"..p.UserId)
	end)

	if not Success then
		warn("Could not get data for "..p.Name)
		return
	end

	if not data then
		data = QuestsData()
	end

	ServerData[p] = data
end

local function saveData(p)
	if not SavingFor[p] then
		SavingFor[p] = true

		if ServerData[p] then

			local Success, Error = pcall(function() 
				PlayerData:SetAsync("data:"..p.UserId, ServerData[p]) 
			end)

			if not Success then
				warn("Data wasn't saved for "..p.Name..".")
				return
			end

			ServerData[p] = nil
		end

		SavingFor[p] = nil
	end
end```

You are not reconciling old data. Clone your new data contents over to any existing data.

How do I do this? I’m not experienced with data handling on roblox.

Compare the players data to the data in the QuestsData() function and add any tables that don’t exist inside the players data.

Anything data related is like runes to me. anything outside of datastore im fine at but I have zilch knowledge on data handling, Perhaps could you provide an example?

You could try and replace this part with:

if not data then
	data = QuestsData()
else
    local template = QuestsData()
    for _, t in pairs(template) do
        if not table.find(data, t) then
            table.insert(data, t)
        end
    end
end

Not the biggest expert with data handling either, so you should probably take my advice with a grain of salt.

Forgot to mention that you should probably also delete data that doesn’t exist in the template.
Like:

for _, t in pairs(data) do
   if not table.find(template, t) then
      table.remove(data, table.find(t))
   end
end

(You can probably just put this right below the part I added above)

Ok it’s very weird, I didn’t change the datakey BUT It now does show the results without needing the datakey, But it just resets it to false and the original value.
image

By that do you mean it’s resetting the other tables that were previously already in there?

No no no, Whenever I try and add a new table to the pool, It does show that it was added without needing to change the datakey, But wipes the old data. And sets it to its template

Ah, I see my mistake. Try and change it to this:
The last example I gave checked if the entire tables were the same, and since some values were different, it changed them anyway. This one should just check whether it can find a table with the same CodeName.

if not data then
	data = QuestsData()
else
    local template = QuestsData()
    for _, t in pairs(template) do
        local found = false
        for _, t2 in pairs(data) do
           if t.CodeName == t2.CodeName then
              found = true
           end
        end
        if not found then
           table.insert(data, t)
        end
    end
end
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.