STRANGE behaviour!

Try saving a data store of all player names when leaving, and then receive them when u next join, and test this with Roblox studio and an actual game.

Players:GetPlayers() just gets every child of Players that is of ClassName “Player”. Players:GetChildren() would return the same thing if you didn’t add other instances into Players.

I tried this in studio:

local Players = game:GetService("Players")

Players.PlayerRemoving:Connect(function(player)
	local t = time()
	print(t)
end)

game:BindToClose(function()
	local t = time()
	print(t)
end)

It printed out this:

12:19:47.793  2.7291668141260743  -  Server - Script:10
12:19:47.788  Disconnect from ::ffff:127.0.0.1|51020  -  Studio
12:19:47.792  2.7291668141260743  -  Server

Edit: I just noticed the order of the output is off! Look at the timestamp!

I’m not looking for a workaround. I’m trying to address this type of behaviour. I expected BindToClose to run the bound function upon server shutdown. In some cases, this can involve multiple players, whom haven’t voluntarily left the game. In most cases - in the case of Studio - this is due to the sole player leaving the game. Server shutdown, in this case, would happen once all players are gone.

TL;DR:
Expected Behaviour: Only 0 ever prints from the function bound to game shutdown using BindToClose.

**Actual Result: Sometimes, with the second repro code I sent in my original post in this thread, 1 will print.

This, along with 0 being printed prior to Bye, KFP_Chimkin, indicates that the function inside BindToClose runs before Player.PlayerRemoving fires.**

oops, mistake, will quickly edit original post

You should read @MSYGamingTV first post in this thread as it explains what’s actually happening when you run this in studio.

1 Like

This might be because the player’s instance leaving is yielded by a wait(1).

No, you can’t halt/yield the Player Instance from leaving.

In studio it seems to happen randomly.


But this makes absolutely no logical sense whatsoever.

1 Like

It could also be caused by the finnicky behaviour of game:BindToClose on studio though, as explained by @MSYGamingTV

It would be impossible to test for this outside of Studio, as server shutdown means that no console logs are kept. Even if BindToClose were a bit unpredictable, why would it fire after Player.PlayerRemoved fired, and still not be able to index the player list?

You can still use webhooks to send a string everytime LogService.MessageOut is fired to your server. In that way you can see what it prints.

Y’know what, screw it.
Here’s a workaround:

Okay, so first, make a Folder in ReplicatedStorage, and name it Players.

Then, add this Script into ServerScriptService:

local playersfolder = game.ReplicatedStorage:WaitForChild("Players")
game.Players.PlayerAdded:Connect(function(player)
	local plrtoken = Instance.new("Folder", playersfolder)
	plrtoken.Name = player.Name
	print("Token added for", player.Name)
end)

game:BindToClose(function()
	print(#playersfolder:GetChildren())
	for _, player in pairs(playersfolder:GetChildren()) do
		print("Player ", player)
	end
end)

I did something like this in a game where i made a player token to save data. Mabye it will work for you.

I ran a test using DataStores on a studio test and an actual server, and the bug still occurs, which means it doesn’t have anything to do with the fact that studio isn’t working. Strange.

1 Like

I’m not looking for a workaround, as I’ve stated.

Perhaps I should report it as a bug?

Why do you need to create instances instead of just using a table?

--//Services
local Players = game:GetService("Players")

--//Tables
local playerTable = {}

--//Functions
Players.PlayerAdded:Connect(function(player)
	table.insert(playerTable, player.Name)
end)

Players.PlayerRemoving:Connect(function(player)
	table.remove(playerTable, table.find(playerTable, player.Name))
end)

game:BindToClose(function()
	print(#playerTable)
end)

That is another way, but I made instances for a game that saved data with them.

Honestly I don’t know how I can help then. From what it seems, game:BindToClose() runs after Player.PlayerRemoving(), so there is no way to get the player instance when it’s gone.

Hence the reason why I made a player token instead. I had this issue before where I tried to access player instances that didn’t exist when I ran game:BindToClose()!

For the final time, I am NOT looking for a workaround. Read the title.