You have to manually update it yourself, DataStoreService does not automatically do this for you. It actually is quite simple! Since ProfileService
was mentioned in this thread, I’ll show you the method loleris implemented for this issue.
There are 2 main functions used:
local function DeepCopyTable(t)
--<< Creates a deep copy of the given table and returns >>--
local copy = {}
for key, value in pairs(t) do
if type(value) == "table" then
copy[key] = DeepCopyTable(value)
else
copy[key] = value
end
end
return copy
end
local function Reconcile(Data, Temp)
for k, v in pairs(Temp) do
if type(k) == "string" then -- Only string keys will be reconciled
if Data[k] == nil then
if type(v) == "table" then
Data[k] = DeepCopyTable(v)
else
Data[k] = v
end
elseif type(Data[k]) == "table" and type(v) == "table" then
Reconcile(Data[k], v)
end
end
end
return Data
end
DeepCopyTable
returns a copy of the given table. Reconcile
assigns the new key(s) and value(s) into the existing data.
Implementing this into your own system is relatively easy. You first retrieve the data and then use the data that you received and run the Reconcile
function using the existing data and the data template for the 2 arguments. From the looks of it, however, you don’t seem to keep a data template anywhere other than a function that runs other stuff that you probably don’t want in the event that the player already has existing data. You don’t have to do much to change this, most of the key values do not need to be updated when the player joins for the first time - only the UserId does.
local DataTemplate = {
["PlayerUserId"] = 0, -- Temporary
["Cash"] = 0,
["CashText"] = 0,
["Multiplier"] = 1,
["MultiplierText"] = 1,
["Skill"] = 0
}
-- Or if you just want a function to return this template you can do that too
function CreateStats.ReturnTemplate()
return {
["PlayerUserId"] = 0, -- Temporary
["Cash"] = 0,
["CashText"] = 0,
["Multiplier"] = 1,
["MultiplierText"] = 1,
["Skill"] 0
}
end
To add this to the CreateStats.New()
function, you can just reference the template and update the needed values (like the UserId) manually. The DeepCopyTable
function we created earlier will also help with this:
local DataTemplate = {
["PlayerUserId"] = 0 -- Temporary
["Cash"] = 0,
["CashText"] = 0,
["Multiplier"] = 1,
["MultiplierText"] = 1,
["Skill"] = 0
}
function CreateStats.New(player)
local Data = require(script.Parent.PlayerDataStorage)
local GuiTemplate = game.ServerStorage.NewPlayerStats:Clone()
local PlayerData = DeepCopyTable(DataTemplate)
-- local PlayerData = DeepCopyTable(CreateStats.ReturnTemplate()) if you created a function to return the data
PlayerData["PlayerUserId"] = player.UserId
return PlayerData
end
Now, we just run the Reconcile
function on the existing data when you first retrieve it.
function PlayerHasJoiend(player)
local Data
local success, err = pcall(function()
Data = experienceStore:GetAsync(player.UserId)
end)
if success then
Data = Data and Reconcile(Data, DataTemplate) or Constructor.New(player) -- Reconciles existing data or creates new data if existing data does not exist
PlayerData.AddPlayerData(player, Data)
end
-- Rest of your code here
end
And there you have it! Existing data gets updated with any new keys added to your data template! I didn’t have much time to test or thoroughly examine what I was writing so if you have any issues let me know! 