PlayerAdded Not firing?!

So I was just messing around with @loleris’s ProfileService Module and wrote my :Get() function but when I require it the PlayerAdded function don’t fire.

DataManager Script-

local Rs = game:GetService("ReplicatedStorage");
local Players = game:GetService("Players");
local ProfileService = require(script:WaitForChild("ProfileService"));

local ProfileStore = ProfileService.GetProfileStore(
	"Player",
	{
		Cash = 0
	}
);

local Profiles = {};

local function MakeLeaderstats(player)
	local profile = Profiles[player];
	
	local leaderstats = Instance.new("Folder", player);
	leaderstats.Name = "leaderstats";
	
	local Cash = Instance.new("IntValue", leaderstats);
	Cash.Name = "Cash"
	Cash.Value = profile.Data.Cash
	
	local thread = coroutine.wrap(function()
		while true do
			Cash.Value = profile.Data.Cash
			game:GetService("RunService").Heartbeat:Wait();
		end
	end)
	thread();
end

function OnPlayerAdded(player)
	local profile = ProfileStore:LoadProfileAsync(
		"Player_" .. player.UserId,
		"ForceLoad"
	);
	
	profile:Reconcile();
	if profile ~= nil then
		profile:ListenToRelease(function()
			Profiles[player] = nil;
			player:Kick();
		end)
		
		if player:IsDescendantOf(Players) then
			Profiles[player] = profile;
			MakeLeaderstats(player);
		else
			profile:Release();
		end
	else
		player:Kick();
	end;
end;

for _,player in ipairs(Players:GetPlayers()) do
	coroutine.wrap(OnPlayerAdded)(player)
end
Players.PlayerAdded:Connect(OnPlayerAdded);

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

local DataManager = {};

function DataManager:Get(player)
	local profile = Profiles[player];
	
	if profile then
		return profile.Data;
	end;
end;

return DataManager;

Script that is not working-

local ProfileService = require(game.ReplicatedStorage:WaitForChild("DataManager"));
game.Players.PlayerAdded:Connect(function(player)
	print(player.Name) -- Doesn't fire
	print(ProfileService:Get(player).Cash) --Doesn't fire
end)

Is it because I have playerAdded event already the module?

Note: If I attach it to a ClickDetector Even for example it woks for some reason.

Script that works-


local part = game.Workspace:WaitForChild("Part");
local ClickDetector = part:WaitForChild("ClickDetector");

local ProfileService = require(game.ReplicatedStorage.DataManager)
print("Yes")
ClickDetector.MouseClick:Connect(function(player)
	local Data = ProfileService:Get(player); -- works
	Data.Cash += 100 --works
end)

The most obvious answer I can think of is that by the time ProfileService is loaded into the script, it yields the thread so the PlayerAdded isn’t connected till then and you already join the game. Don’t know if this is the reason, but I have seen it happen in someone else’s code too previously and although not a good fix, they put it in a spawn block so it doesn’t yield the thread.

1 Like

Do you remember the thread you see this problem before? If yes can you link it?

1 Like

Replace

local ProfileService = require(game.ReplicatedStorage:WaitForChild("DataManager"));
game.Players.PlayerAdded:Connect(function(player)
   print(player.Name) -- Doesn't fire
   print(ProfileService:Get(player).Cash) --Doesn't fire
end)

With

local ProfileService 

coroutine.wrap(function()
ProfileService = require(game.ReplicatedStorage:WaitForChild("DataManager"));
end)()

game.Players.PlayerAdded:Connect(function(player)
if not ProfileService then repeat wait() until ProfileService end
   print(player.Name) -- Doesn't fire
   print(ProfileService:Get(player).Cash) --Doesn't fire
end)
1 Like

Its night here so I will try it tomorrow.

I tried it but it didn’t worked-

so I did few prints and came to know

local ProfileService 

coroutine.wrap(function()
ProfileService = require(game.ReplicatedStorage:WaitForChild("DataManager"));
end)()

game.Players.PlayerAdded:Connect(function(player)
if not ProfileService then 
   repeat wait()  
       print("something") -- this prints infinitely  
   until ProfileService 
end
   print(player.Name) -- Doesn't fire
   print(ProfileService:Get(player).Cash) --Doesn't fire
end)

Try without the :WaitForChild(). I don’t see why it is needed since this is a server script, and the ReplicatedStorage’s children should be loaded already when using the dot operator.

Try this:

local Players = game:GetService('Players')
local Replicated = game:GetService('ReplicatedStorage')
local Module = require(Replicated.DataManager)

Players.PlayerAdded:Connect(function(Player)
	-- Code.
end)

The reason why it might not fire is because WaitForChild yields the thread until a result is ready, it will yield infinitely if the specified object is not found, the default time-out is 5 seconds (unless you change it yourself).

1 Like

PlayerAdded doesn’t fire in Studio because the player added event fires Before your script is instanced. When you play the game, the player added event will fire, so you should test your ‘player added’ code there.

1 Like

The documentation for ProfileService states you should iterate through every player before connecting the PlayerAdded event to make sure you “initialize” their data.``

local RunService = game:GetService("RunService")

local DataTemplate = {
	Coins = 0,
	Pets = {},
	LastPlayed = os.time(),
	LoginCount = 0
}

local ProfileService  = require(script.Parent.ProfileService)
local PlayerProfileStore = ProfileService.GetProfileStore("Data", DataTemplate)
local Profiles = {}

local function PlayerAdded(Player)
	local Profile = PlayerProfileStore:LoadProfileAsync("Player_" .. Player.UserId, "ForceLoad")
	
	if Profile ~= nil then
		Profile:Reconcile() -- Fill in missing variables from ProfileTemplate (optional)
		Profile:ListenToRelease(function()
			Profiles[Player] = nil
			Player:Kick()
		end)
		if Player:IsDescendantOf(Players) == true then
			Profiles[Player] = Profile
			Profile.Data.LoginCount += 1
			print(Player.Name .. " has logged in " .. tostring(Profile.Data.LoginCount) .. " time" .. ((Profile.Data.LoginCount > 1) and "s" or ""))
		else
			Profile:Release()
		end
	else
		Player:Kick() 
	end
end

for _, Player in ipairs(Players:GetPlayers()) do
	coroutine.wrap(PlayerAdded)(Player)
end

Players.PlayerAdded:Connect(PlayerAdded)

Players.PlayerRemoving:Connect(function(Player)
	local Profile = Profiles[Player]
	if Profile ~= nil then
		Profile:Release()
	end
end)

return Profiles

This?[sorry bypasssssssssssssss]

Yes, that will make sure to call the function on all the players currently in game and that is the solution since normally, scripts run first before anything but in your case, they run a bit after when a player joins.

1 Like