STRANGE behaviour!

This is an IMPOSSIBLE bug.

To keep it short, there’s some incredibly strange behaviour, causing me to go 2 nights without good sleep. I’ve done some tests, you can easily repro these:

local Players = game:GetService("Players")

Players.PlayerRemoving:Connect(function (player)
    print("Bye", player)
end)

game:BindToClose(function()
    print(#Players:GetPlayers())
end)

The above will execute the code bound to server shutdown using BindToClose prior to Player.PlayerRemoving.

This suggests that the player is removed after the function bound fires and the print is executed. However, this does NOT seem to be the case, since 0 is printed, instead of 1 - in a solo Studio test session.

local Players = game:GetService("Players")

game:BindToClose(function()
    print(#Players:GetPlayers())
end)

The above usually works as expected, and prints 0. On multiple occasions, it had printed 1.

local Players = game:GetService("Players")

Players.PlayerRemoving:Connect(function (player)
    wait(1)
end)

game:BindToClose(function()
    print(#Players:GetPlayers())
end)

The above acts exactly the same as the second code snippet I have posted in this post. It has printed 1, once. Unlike the first snippet, which has always printed 0.

This issue has stumped many a scripter. I have had a bad dream yesterday about this. I woke up feeling angry. I am still angry. This is an extremely hard problem to solve. Please, guidance would be appreciated.

1 Like

So, correct me if I’m wrong but,
Upon shutdown, you want the list of all players that was in the server prior to the shutdown, right?

2 Likes

So, let me get this straight. The print statement is not printing with BindToClose?

Yep. I’d appreciate other solutions of doing so - not that I think there are any - but I’m mainly focused on this irradical behaviour.

I’ve actually managed to replicate this and this does indeed work. Could you show your repro place for it? It seems to work on my end.

If you want the list then:

local Players = game:GetService("Players")

game:BindToClose(function()
    -- // "#" only gets the number of players, not the list.
    print(Players:GetPlayers())
end)

image

So, this is so confusing. Let me see if I can find a workaround.

This is pretty interesting. I’ve just had someone else send me a repro file, and it worked as expected apart from for two occasions. Those two occasions, 1 was printed.

What else is odd is that this does not prevent it from printing “Bye”

local Players = game:GetService("Players")

local serverIsClosed = false

Players.PlayerRemoving:Connect(function(player)
	if serverIsClosed then return end
	print("Bye", player)
end)

game:BindToClose(function()
	serverIsClosed = true
	print(#Players:GetPlayers())
end)

the world will end in a few days because of it…

0 will be printed because it’s run in studio though. Try doing a team test in an actual Roblox game with some people and see if it prints the amount of people.

Maybe it has something to do with Roblox Studio tests ending server sessions at different times compared to actual experience servers?

1 Like

Did you run this on studio or on an actual game?

I ran it in studio. I’m not sure what happens in the actual game.

From what I know, Players:GetPlayers() gets the currently connected players. I don’t know if this will work, but try replacing it with Players:GetChildren().

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