Why can't I add to Data in ProfileService?

Hey!

Here is the line of Script I am having an issue with:

profile.Data.XP += 1
XP.Value = profile.Data.XP
print("Given XP")

The error it’s giving me is ‘attempt to perform arithmetic (add) on nil and number.’ I am using ProfileService to make my level system, and I’m testing with my XP part to see if it works and it gave me that error. Let me know how I can fix this. If you need more script to be shown, let me know.

Thanks a lot.

Need to use XP.Value += 1 just XP is an instance, but since your error is stating nil you might have other issues present.

Ah unless profile.Data.XP is part of a table where XP is not a valid member of Data.

You probably need to set XP to a number like 0 or 1 before adding on to it.

2 Likes
local saveStructure = {
	Points = 0;
	Rubys = 0;
	Deaths = 0;
	Kills = 0;
	playTime = 0;
	Wins = 0;
	Level = 0;
	XP = 0;
	RequiredXP = 0;
}

Here is the table I have

1 Like

@gertkeno @PigTPM_S3

Here is my whole script if you guys wanna see the whole thing

local Players = game:GetService("Players")
local MareketPlaceService = game:GetService("MarketplaceService")
local cachedProfiles = {}
local ProfileService = require(game.ServerScriptService.Leaderstats.ProfileService)
local saveStructure = {
	Points = 0;
	Rubys = 0;
	Deaths = 0;
	Kills = 0;
	playTime = 0;
	Wins = 0;
	Level = 0;
	XP = 0;
	RequiredXP = 0;
}

local PlayerProfileService = ProfileService.GetProfileStore("PlayerData", saveStructure)

local function playerDataLoaded(player)
	local profile = cachedProfiles[player]
	
	local folder = Instance.new("Folder")
	folder.Name = "leaderstats"
	folder.Parent = player
	
	local points = Instance.new("IntValue")
	points.Name = "Points"
	points.Value = profile.Data.Points
	points.Parent = folder
	
	local rubys = Instance.new("IntValue")
	rubys.Name = "Rubys"
	rubys.Value = profile.Data.Rubys
	rubys.Parent = folder
	
	local deaths = Instance.new("IntValue")
	deaths.Name = "Deaths"
	deaths.Value = profile.Data.Deaths
	deaths.Parent = folder
	
	local kills = Instance.new("IntValue")
	kills.Name = "Kills"
	kills.Value = profile.Data.Kills
	kills.Parent = folder
	
	local playtime = Instance.new("IntValue")
	playtime.Name = "playTime"
	playtime.Value = profile.Data.playTime
	playtime.Parent = folder
	
	local wins = Instance.new("IntValue")
	wins.Name = "Wins"
	wins.Value = profile.Data.Wins
	wins.Parent = folder
	
	local Level = Instance.new("IntValue")
	Level.Name = "Level"
	Level.Value = profile.Data.Level
	Level.Parent = folder
	
	local RequiredXP = Instance.new("IntValue")
	RequiredXP.Name = "RequiredXP"
	RequiredXP.Value = profile.Data.RequiredXP
	RequiredXP.Parent = folder
	
	local XP = Instance.new("IntValue")
	XP.Name = "XP"
	XP.Value = profile.Data.XP
	XP.Parent = folder
	
	local RoundKills = Instance.new("IntValue")
	RoundKills.Name = "RoundKills"
	RoundKills.Value = 0
	RoundKills.Parent = player
	
	local ServerAgeForPlayer = Instance.new("IntValue")
	ServerAgeForPlayer.Name = "PlayerServerAge"
	ServerAgeForPlayer.Parent = folder
	
	spawn(function()
		while true do
			if profile ~= nil then
				points.Value = profile.Data.Points
				rubys.Value = profile.Data.Rubys
				deaths.Value = profile.Data.Deaths
				kills.Value = profile.Data.Kills
				playtime.Value = profile.Data.playTime
				wins.Value = profile.Data.Wins
				Level.Value = profile.Data.Level
				XP.Value = profile.Data.XP
				RequiredXP.Value = profile.Data.RequiredXP
			else
				break
			end
			wait(.1)
		end
	end)
	
	print(player.Name .. "'s data is loaded.")
	
	XP:GetPropertyChangedSignal("Value"):Connect(function()
		if player:FindFirstChild("leaderstats"):FindFirstChild("PlayerServerAge").Value <= 15 then
			print("Can't change they're XP at this moment.")
		elseif XP.Value >= RequiredXP.Value then
			XP.Value = 0

			Level.Value += 1
			RequiredXP.Value = Level.Value * 100
		end
	end)
	
	while true do
		wait(1)
		profile.Data.playTime += 1
		
		player:FindFirstChild("leaderstats"):FindFirstChild("playTime").Value = profile.Data.playTime
		
		player:FindFirstChild("leaderstats"):FindFirstChild("PlayerServerAge").Value += 1
		
		wait(15)

		profile.Data.XP += 1
		XP.Value = profile.Data.XP
		print("Given XP")
	end
end

local function PlayerAdded(player)
	local profile = PlayerProfileService:LoadProfileAsync("Player_" ..player.UserId, "ForceLoad")
	
	if profile ~= nil then
		profile:ListenToRelease(function()
			cachedProfiles[player] = nil
			player:Kick("Your data loaded Remotly, please rejoin.")
		end)
		
		if player:IsDescendantOf(Players) then
			cachedProfiles[player] = profile
			playerDataLoaded(player)
		else
			profile:Release()
		end
	else
		player:Kick("Data did not load, please rejoin or report in the links below of game Description.")
	end
end

for _, player in ipairs(Players:GetPlayers()) do
	spawn(function()
		PlayerAdded(player)
	end)
end

Players.PlayerAdded:Connect(PlayerAdded)

Players.PlayerRemoving:Connect(function(player)
	local profile = cachedProfiles[player]
	if profile ~= nil then
		profile:Release()
	end
end)

return cachedProfiles
1 Like

Can you also print(profile) near your problem line?

1 Like

It prints this:

{
                    ["Data"] =  ▶ {...},
                    ["GlobalUpdates"] =  ▶ {...},
                    ["KeyInfo"] = Instance,
                    ["KeyInfoUpdated"] =  ▶ {...},
                    ["MetaData"] =  ▶ {...},
                    ["MetaTagsUpdated"] =  ▶ {...},
                    ["RobloxMetaData"] = {},
                    ["UserIds"] = {},
                    ["_hop_ready"] = false,
                    ["_hop_ready_listeners"] =  ▶ {...},
                    ["_is_user_mock"] = false,
                    ["_load_timestamp"] = 37977.248036869,
                    ["_profile_key"] = "Player_1056152894",
                    ["_profile_store"] =  ▶ {...},
                    ["_release_listeners"] =  ▶ {...}
                 }
1 Like

This is because you haven’t used the profile:Reconcile() function in PlayerAdded function, because when a new player joins the game, the profile.Data table would be empty. profile:Reconcile() fixes that problem by filling it with the data structure you provided at the beginning of the script.

Another solution you could do is by referencing key values by brackets instead.
So this:

profile.Data.XP += 1

Should be instead this:

profile.Data["XP"] += 1

(also i would highly recommend reading the profileService documentations first)

3 Likes

Thank you, the profile:Reconile() Helped a lot. Here is my script that I did:

local function PlayerAdded(player)
	local profile = PlayerProfileService:LoadProfileAsync("Player_" ..player.UserId, "ForceLoad")
	
	if profile ~= nil then
		profile:AddUserId(player.UserId)
		profile:Reconcile()
		profile:ListenToRelease(function()
			cachedProfiles[player] = nil
			player:Kick("Your data loaded Remotly, please rejoin.")
		end)
		
		if player:IsDescendantOf(Players) then
			cachedProfiles[player] = profile
			playerDataLoaded(player)
		else
			profile:Release()
		end
	else
		player:Kick("Data did not load, please rejoin or report in the links below of game Description.")
	end
end

for _, player in ipairs(Players:GetPlayers()) do
	spawn(function()
		PlayerAdded(player)
	end)
end

Players.PlayerAdded:Connect(PlayerAdded)
1 Like

Glad that helped!

Also i would recommend you using task.spawn or coroutine.wrap(PlayerAdded)(player) instead, since spawns are VERY outdated and inefficient to use.

1 Like