playerService.PlayerAdded not firing intermittently

I have a weird one.

I have a situation where the PlayerAdded event does not fire at times on the LIVE server. It works every time in Studio.

local playerService = game:GetService("Players")
local dataStoreService = game:GetService("DataStoreService")

-- A bunch of function definitions.

-- Event Handler for when a player joins the game.
playerService.PlayerAdded:Connect(function(player)
	print("Player Added:", player)
	-- Create the leaderboard
	leaderBoardMod.create(player, defaultDataMod.getSessionData())

	-- Load player data
	setupSessionData(player)
	setupRoundData(player)
	print("Player Added Done")
end)

Sometimes the print statements print and sometimes they don’t. When it doesn’t fire, the player is unable to do anything as their data isn’t loaded from the datastore, and the script errors out with nil values. Not even default data is loaded like you would with a new player.

::EDIT::

One thing that I thought about doing is if any of the functions in the script get called, have it check if the data was loaded. If it wasn’t, then load it then. Not sure what’s causing this. Could this be a timing issue? After all, the data is loaded (thread yielded) during an event handler operation.

2 Likes

Sometimes (most of the time, actually), this event doesn’t fire within Studio.

This could potentially be the issue!

Theres a great video by @sleitnick explaining why this happens and how you can fix it!
Heres my version of that code for reference:

local function handlePlayer(Player : Player)
    -- preload data here
end

for _, Player in pairs(game.Players:GetPlayers()) do
    handlePlayer(Player);
end

game.Players.PlayerAdded:Connect(handlePlayer);
7 Likes
local playerService = game:GetService("Players")
local dataStoreService = game:GetService("DataStoreService")

-- A bunch of function definitions.

-- Event Handler for when a player joins the game.
local function handlePlayer(player)
	print("Player Added:", player)
	-- Create the leaderboard
	leaderBoardMod.create(player, defaultDataMod.getSessionData())

	-- Load player data
	setupSessionData(player)
	setupRoundData(player)
	print("Player Added Done")
end)

for _, Player in pairs(game.Players:GetPlayers()) do
    handlePlayer(Player);
end

game.Players.PlayerAdded:Connect(handlePlayer);

Try moving the bunch of functions inside the player added.

local playerService = game:GetService(“Players”)
local dataStoreService = game:GetService(“DataStoreService”)

– Event Handler for when a player joins the game.
playerService.PlayerAdded:Connect(function(player)

– A bunch of function definitions. *** move the functions here!!!

print("Player Added:", player)
-- Create the leaderboard
leaderBoardMod.create(player, defaultDataMod.getSessionData())

-- Load player data
setupSessionData(player)
setupRoundData(player)
print("Player Added Done")

end)

1 Like

I have watched the video and it makes sense. So I have implemented your solution to the problem with modifications. I will test it for awhile and see how it does.

–EDIT–

That corrected the problem. The problem only manifests itself when the server first spins up, which makes sense. So it’s basically a race condition. Now the code that I have will check to see if the player’s data has been loaded. If not, it will load it. The code is at the very end of the script to make sure that the event is connected first before the check.

2 Likes

To give a quick rundown you likely have yielding code prior to when PlayerAdded's connection is made.

1 Like

Actually, no. There is no yielding code before the event connection is made. If the character spawns before the scripts have finished their initialization procedures, then you get the error. If the players spawns afterwards, you don’t. That’s the classic race condition. I see it in the server log messages in the developer’s console when I go into the live server. Sometimes it automatically loads up, sometimes the solution code runs. The printouts are different depending on which method gets used.