Update the dictionary table inside ProfileService (DataStore)

So, I planned to have ProfileService that will store all the boolean data on whether the player has these game characters or not. So, I’ve made I profile template that contains all the characters that I have in the game, and gave it a boolean value.

-- This ProfileTemplate contain all the characters that will be in the game, and each
-- player will have their own boolean value whether they have these character or not
local ProfileTemplate = {
	Bobby = false;
	Loki = false;
	Saiyan = false;
	Dida = false;
	Assasin = false;
}

-- Set up the profileService
local ProfileService = require(game.ReplicatedStorage.ProfileService)

local DictProfileStore = ProfileService.GetProfileStore(
	"PlayerHaveTheseCharacters",
	ProfileTemplate
)

-- Load data to player when they joined the game
local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(player)
	local profile = DictProfileStore:LoadProfileAsync(
		"Player_" .. player.UserId,
		"ForceLoad"
	)
	print(profile.Data.Bobby) -- This will print false
end)

The problem is if I update my game and create a new character named “Newman” and add to the profile template, he will not get added. This is the code box in the same script, but I added new characters and changed it a bit.

-- This ProfileTemplate contain all the characters that will be in the game, and each
-- player will have their own boolean value whether they have these character or not
local ProfileTemplate = {
	Bobby = false;
	Loki = false;
	Saiyan = false;
	Dida = false;
	Assasin = false;
        Newman = false;
}

-- Set up the profileService
local ProfileService = require(game.ReplicatedStorage.ProfileService)

local DictProfileStore = ProfileService.GetProfileStore(
	"PlayerHaveTheseCharacters",
	ProfileTemplate
)

-- Load data to player when they joined the game
local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(player)
	local profile = DictProfileStore:LoadProfileAsync(
		"Player_" .. player.UserId,
		"ForceLoad"
	)
	print(profile.Data.Bobby) -- This will print false
	print(profile.Data.Newman) -- This will print nil!? I don't want that... I want the boolean value...
end)

So, I want to know is there any way to achieve my goal using ProfileService. Since this is my first time using ProfileService so I don’t know much. Thanks in advance.

You’d have to make a copy of the table, because once tables are saved, you can’t just edit the variable and expect it to overwrite data that has already been saved, this should work:


-- This ProfileTemplate contain all the characters that will be in the game, and each
-- player will have their own boolean value whether they have these character or not
local ProfileTemplate = {
	Bobby = false;
	Loki = false;
	Saiyan = false;
	Dida = false;
	Assasin = false;
	Newman = false;
}

local ProfileService = require(game.ReplicatedStorage.ProfileService)

-- Load data to player when they joined the game
local Players = game:GetService("Players")

local function DeepCopy(original)
	local copy = {}
	for i, v in pairs(original) do
		if type(v) == "table" then
			v = DeepCopy(v)
		end
		copy[i] = v
	end
	return copy
end

local function MergeDataWithTemplate(data, template)
	for i, v in pairs(template) do
		if type(i) == "string" then -- Only string keys will be merged
			if data[i] == nil then
				if type(v) == "table" then
					data[i] = DeepCopy(v)
				else
					data[i] = v
				end
			elseif type(data[i]) == "table" and type(v) == "table" then
				MergeDataWithTemplate(data[i], v)
			end
		end
	end
end

local DictProfileStore = ProfileService.GetProfileStore(
	"PlayerHaveTheseCharacters",
	ProfileTemplate
)



Players.PlayerAdded:Connect(function(player)
	local profile = DictProfileStore:LoadProfileAsync(
		"Player_" .. player.UserId,
		"ForceLoad"
	)
	
	MergeDataWithTemplate(profile.Data, ProfileTemplate)
	print(profile.Data.Bobby) -- This will print false
	print(profile.Data.Newman) -- Should print false
end)



Hope this works, if it does i’d appreciate an accept :+1:

1 Like

ProfileService has a built-in method for this use case, Reconcile. If you add any new keys to your profile template you can call Reconcile so that the missing keys will get added to profiles. Ideally you could call Reconcile every time you load a profile.

5 Likes

Thanks guys, it’s all good now.