Can't debug Players.PlayerRemoving

Reproduction Steps

  1. Put this in a Script:
local Players = game:GetService("Players")
Players.PlayerRemoving:Connect(function(Player)
	print("SERVER PlayerRemoving", Player)
end)
  1. Set a breakpoint on the print line
  2. Run
  3. Stop (the only way to force PlayerRemoving in Studio)

Expected Behavior
I should be able to debug the entire code inside PlayerRemoving before Studio stopped.

Actual Behavior
The breakpoint is not respected.

Issue Area: Studio
Issue Type: Other
Impact: High
Frequency: Constantly

1 Like

The breakpoint gets reached if I kick myself from the server view in Play Solo. If I use the stop button it results in Studio temporarily hanging for a few seconds, reproducible 100% of the time. Accompanying the end of the hang is the error message “Not running script because past shutdown deadline” sent 24 times to the console. Local server does not preserve the breakpoints so it can’t be tested there.

Wonder if this provides any information for engineers or a clue for someone else who’s more knowledgeable about Studio issues.

1 Like

I wonder if this is caused by Studio unloading the server datamodel straight after the event is processed, which is preventing the breakpoint from being raised to the developer.

The thread is getting yielded by the breakpoint and Studio suddenly thinks it can unload the DataModel, not respecting the breakpoint.

Another theory I could recommend doing is throwing a wait call in there and seeing what happens.

@colbert2677 The Not running script because past shutdown deadline makes me think the above is true.

EDIT: This code will never print if you press Stop. So my initial theory is correct

local Players = game:GetService("Players")

Players.PlayerRemoving:Connect(function()
	wait()
	print("boop!")
end)

The reason it’ll hit the breakpoint if you LocalPlayer:Kick is because the DataModel isn’t being stopped, the server and client models are still alive. Remember that it prompts you with a “Disconnected” window instead of shutting down the active datamodels.

1 Like

you could try running a local server with 2 players and then let one leave while the server should keep running.

@colbert2677

This is because of another bug, reported by me over a year ago and so far it has not been resolved.

If you put the following code in BindToClose, Studio will run the PlayerRemoving:

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

Players.PlayerRemoving:Connect(function()
	wait()
	print("boop!")
end)

game:BindToClose(function() -- <<<<<<<<<<<<<
	--  if the Stop button is pressed, "IsRunning()" will be false...
	-- ... so the wait(3) bellow will not be executed, avoiding the 30 seconds problem
	if RunService:IsRunning() and RunService:IsStudio() then
		-- this will force Studio to wait 3 seconds to complete SetAsync in PlayerRemoving
		wait(3)
	end
end)

However, even if you put a breakpoint inside BindToClose, Studio still won’t respect this breakpoint, not allowing code debugging…

So, that’s the reason I created this bug report because I need to be able to debug the code even when a player leaves the game…

The debugger clearly cant raise on any code thats being run just as the game is being shutdown. It would be easier to raise that into the Edit datamodel when Studio has returned to it.

As colbert mentioned above, a temporary workaround would be to kick the LocalPlayer from the command bar instead of shutting down the game.

Further tests: Just wrote some DebuggerManager code to see if the breakpoint is being hit.

It isn’t, so likely Studio is programmed to not hit breakpoints when the game is being closed.

1 Like

Thanks for the report! We’ve filed a ticket to our internal database and we’ll follow up when we have an update for you.

2 Likes

To debug PlayerRemoving, use the following from the Command Line:

local p = game.Players.LocalPlayer; p:Kick()

From the docs: Player | Roblox Creator Documentation
“The Kick Player method allows a game to gracefully disconnect a client from the game and optionally provide a message to the disconnected player.”
This doesn’t require to shut down the debugging and wait for 30 seconds.

Using Kick() the debugger will break in the PlayerRemoved event handler.

You can also try to maybe decrease the timeout in Studio / Script Timeout Length.

8 Likes

This topic was automatically closed after 7 days. New replies are no longer allowed.