Hey, I have currently stuck on how to add new data to existing data?
As you can see below. There is Example1 and Example2. It will be your data when you join the game for the first time.
What if I decide to add another table like โExample3โ to a player that has already played before the update. How do I go on to add that data?
--// ๐๐๐๐๐๐
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local DataStoreService = game:GetService("DataStoreService")
local PlayerData = DataStoreService:GetDataStore("PlayerData")
local ServerData = {}
local function newData()
return {
Example1 = {
Value1 = 50,
Value2 = 100
},
Example2 = {
Value1 = true
}
--[[ This would be the newer data to add.
Example3 = {
Value1 = 250
--]]
}
end
local function loadData(player)
local Success, Data = pcall(function() return PlayerData:GetAsync("data:"..player.UserId) end)
ServerData[player] = Success and Data or newData()
end
local function saveData(player)
if ServerData[player] then
local Success, Error = pcall(function() PlayerData:SetAsync("data:"..player.UserId, ServerData[player]) end)
if not Success then
warn("Data wasn't saved for "..player.Name..".")
return
end
ServerData[player] = nil
end
end
game.Players.PlayerAdded:Connect(function(player)
loadData(player)
end)
game.Players.PlayerRemoving:Connect(function(player)
local retries, maxRetries = 0, 5
repeat
local Success = pcall(saveData, player)
retries = retries + 1
wait(6)
until Success or retries == maxRetries
print("Saved " .. player.Name .. "'s data!")
end)
Good case of why it would be better to modify templated data structures as opposed to using anything raw when it comes to player data. At least itโs worked the best for me when I needed to change the data structure of someoneโs data, either in terms of adding or removing keys and values naturally.
What you should be doing when it comes to data is having a template data set created for the player that contains all the values for the current session which you can add on to in later updates. You could keep that newData function since it handles this templating work.
Whenever a player joins, regardless of if they have save data prior or not, call newData and assign that as their session data. Then, make a call to the DataStore to fetch their saved data. When you have this fetched, instead of using this for the session, iterate through the returned data and modify the template.
Example code:
local function newData()
return {
Level = 1,
EXP = 0,
}
end
local function useSaveData(saved, session)
for key, value in pairs(saved) do
if session[key] then
if type(session[key]) == "table" then
useSaveData(session[key], value)
else
session[key] = value
end
end
end
end
The above code isnโt good for arbitrary additions though, like inventory items.
Thanks! I am thinking of making a Pet Inventory system though and that is considered arbitrary, so that would mean that you would not recommend this system in that case?
If so, do you know any good sources for making a better system in that case?
In the case of arbitrary additions, you could probably go about this in a few ways. I know of creating an ignore list or separating off into another DataStores (inventory structures I envision typically span large enough to warrant a separate DataStore). You could probably also modify this function itself to work for your cases.
I personally have a physical copy of my data template (folders and ValueObjects) that I work from rather than keeping it all pure data for the idea of convenience and all. Iโve been told a lot that itโs a bad idea but out of all the attempts Iโve made, that one worked best for me. Itโs also very easy to handle cases like this.