How can I add more values into DataStore without overwriting data

Hi all,

I’ve made a DataStore system to save achievements that players can earn when playing or completing objectives in the game. I’m wondering how I can add more achievements into the DataStore without overwriting data, it is currently set out like this:

local DefaultAchievements = {

{‘MM Osmosis’, 0}

}

In future there will obviously be more values that I need to add, as the game gets updated, so I need a reliable solution on how to do this.

Thanks

So as I could of understand you you want to create more default Datastore IntValue’s.
Your code example:

local DefaultAchievements = {

{‘MM Osmosis’, 0}  -- First argument is name of value and second argument is default value

}

So basically you will have to add it like this:

local DefaultAchievements = {

    {‘MM Osmosis’, 0}  -- Your first default IntValue
    {‘MM Osmosis2’, 1}  -- Your second default IntValue with name 'MM Osmosis2' and value of 1

    {"ArmorAdamant", false}  -- This is an example for BoolValue and default value "false"
    
    {"NameOfStringValue", "DefaultString"}  -- This is an example for StringValue and default string "DefaultString"
}

If you’d like to create StringValue’s or BoolValue’s as well I recommend you create them by a script as well and then call those default values if there is not DataStore saved for Player that joined.

For example on a BoolValue:

local unlockedArmorAdamant = Instance.new("BoolValue", player)
unlockedArmorAdamant.Name = DefaultAchievements[1].[1]
unlockedArmorAdamant.Value = DefaultAchievements[1].[2]

I hope this helps. :herb:

I don’t think I was as specific as I could’ve been.

What I mean is in future updates how would I be able to add more values inside the table, to players current data, without the loss of the data that already exists i.e overwriting it with an updated default table.

This is usually why I use player data only as templating in scenarios like this rather than their raw data table. This way, player data is modifying a data template rather than being used raw. Edits become colossally much easier to make.

When I save data, it’s only data that actually needs to exist in the player table. For an achievements system, that means only gained achievements. Anything else is discarded and the game treats it as not collected. When player data loads, a template is loaded and the player data is injected into that template to modify it.

I would recommend learing how to use DataStore2 by kampfkarren it simplifies datastores while preventing data loss. :smiley:

I would highly recommend doing something like @colbert2677 suggested.

I essentially do something like this:

local function BuildPlayerDataProfile(PreviousSave)
	return {
		Kills = PreviousSave.Kills or 0,
		Points = PreviousSave.Points or 0,
	}
end

This means you can add any new entry to their “data profile” without worrying about backwards compatibility.

local function BuildPlayerDataProfile(PreviousSave)
	return {
		Kills = PreviousSave.Kills or 0,
		Points = PreviousSave.Points or 0,
		
		-- New feature!
		Lives = PreviousSave.Lives or 9, -- players that have not had "Lives" saved before will automatically start off with 9
	}
end

You can also extend “data profiles” more to be fully fleshed out objects. I use OOP for data, treating data profile as a class, with methods like PlayerData:Send(), which strips away unnecessary data for replication and then sends it across to the player associated with the data object.

Beware of becoming me, using OOP for literally everything, and increasing your development time dramatically, but I think an object-oriented approach works amazingly here.

4 Likes