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.
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.
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.
Ok so I found something: I force shut down a server I was in and it saved the number of players PROPERLY. This means that :BindToClose()
will run either when all players leave the game, or when a server is shut down
When it’s called via all players leaving, there are no players left.
When it’s called via shutdown, it still has instances of the players.
Exactly what I thought too. I don’t have the Regular role, so I cannot submit a bug report. I will ask others.
But there is nothing but a workaround! As @MSYGamingTV said, player instances are preserved ONLY on force shutdown! Also, I don’t know if this is a bug. But, you can submit it somehow anyways.
Also, I find that in the primary post, there is nothing stating about no workarounds. Yes, you did put it in a post, but that still doesn’t mean it’s in the title.
tbh I dont think this is a bug. BindToClose is designed to carry out any extra procedures when a server shuts down, which purposely only occurs when all players are removed or a shutdown occurs. This function is mainly designed to, for example, save everyone’s progress incase of a shutdown.
Didn’t he just say it was intended behaviour?
The problem is that Player.PlayerRemoved fires after the bound function finishes executing, meaning that the player list should still be intact. Its not - in the case of single-player leaving.