PlayerRemoving is not being fired before Teleport

Reproduction Steps

1) Open this project in Studio and publish it to Roblox:
test.rbxl (36.5 KB)

Server Script
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RemoteEvent 	= ReplicatedStorage:WaitForChild("RemoteEvent")
local TeleportService = game:GetService("TeleportService")

Players.PlayerRemoving:Connect(function()
	print('1 - PlayerRemoving')
end)

RemoteEvent.OnServerEvent:Connect(function(Player)
	print('2 - Teleport')
	TeleportService:TeleportAsync(9611251184, {Player})
end)
LocalScript
local Player = game.Players.LocalPlayer
local PlayerGui = Player:WaitForChild("PlayerGui")
local Gui 	= PlayerGui:WaitForChild("ScreenGui")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RemoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")

Gui.TP.MouseButton1Click:Connect(function()
	RemoteEvent:FireServer()
end)
  1. Run
  2. Click on the button to teleport (Studio will through an error because it can’t teleport, but it’s not the case)
  3. Will you see 2 - Teleport print, but not the 1 - PlayerRemoving print.
  4. Stop the project and now you’ll see 1 - PlayerRemoving

Dc8DNtQhac

Expected Behavior

Once the player is teleported to another place, PlayerRemoving should be run BEFORE the Teleport.

Actual Behavior

The player is being teleported without running PlayerRemoving before.

Workaround

I have to manually call a function to do the same as PlayerRemoving before teleporting.

Issue Area: Engine
Issue Type: Other
Impact: Moderate
Frequency: Constantly

3 Likes

You are teleporting in Studio so it probably gives you the error since you aren’t in Roblox Player.
So if the teleport fails then the player is still in the game and you just printed that they’ve teleported. Try putting this

TeleportService:TeleportAsync(9611251184, {Player})
print('2 - Teleport')

to see if the script errors before the print statement.

Of course, when you stop testing you’ll get the 1-PlayerRemoving message.

I assume you haven’t tested it.
This is independent of Studio or Roblox Player.
As I said in the OP, the problem is that I save data to the DataStore within PlayerRemoving and I noticed that this data was not being saved when I Teleported.
This test proves that PlayerRemoving is not running BEFORE the Teleport.

Here is the same project running on Roblox Player. If PlayerRemoving was fired before, it would appear on the console log:

1 Like

I’m not sure why this’d be considered a bug. Isn’t PlayerRemoving supposed to fire once a player’s removed, not when they teleport? Running it when the player starts teleporting would essentially break all teleportation failure mitigation, since it’d run immediately regardless of if the teleport failed or not.

1 Like

Did you implement the game:BindToClose(func) callback? I usually add a wait statement in there to give the data handler time to save the player’s data prior to the server shutting down.

It would make sense as to why calling a function directly to save the player’s data would work instead, as data store methods are asynchronous and I would assume you’re not wrapping them in a coroutine.

As far as I understand, when a player is teleported, he leaves from one place to another, so he leaves one server and enters another. Therefore, PlayerRemoving should be run.

Did you test?
It makes no difference.

I’ve had no issues with TeleportService.

It would appear to be your implementation. I can’t see how you handle saving player data, as in the repro you only included the teleport code.

Not sure why that matters any ways. Just implement BindToClose to assure the PlayerRemoving event is able to finish saving the player’s data. Yes, it does work. Not sure how you’re supposed to see it output anything as it fires right before the player leaves the game.

I appreciate your cooperation, but I ask you to test the file I sent, which proves what I’m talking about.

I don’t think this is a bug, when you teleport since you are the only player the server shuts down therefore the PlayerRemoving event won’t be fired. As mentioned by others you would have to use BindToClose to avoid this.

Yes I tested this with the code you provided, I joined with my alt and teleported my alt and it printed it perfectly fine.

It seems like you’re more concerned about people testing your code than actually fixing it yourself lol

Source: I did too, with 2 accounts, works fine

Are you meaning that 1 - PlayerRemoving was printed before 2 - Teleport?

1 - PlayerRemoving will not print before 2 - Teleport because 2-Teleport is printed before you call the function TeleportAsync it takes some time for the player to be teleported so it won’t print first.

1 Like

What I’m trying to say is that, as I understand it, TeleportAsync should do the following:

  1. Before starting teleporting, first it should call PlayerRemoving
  2. Only after returning from PlayerRemoving, it should do the teleport

In this case, the correct thing would be to appear:
1-PlayerRemoving
2-Teleport

This doesn’t seem right, why should PlayerRemoving fire before the player is actually leaving the server? Teleport calls can take time, or they can just fail completely. They may also need to be retried and that is something the developer should be able to handle.

I do not want PlayerRemoving firing and all of my code thinking the player has left when they’re still in the game & can still play. If the teleport succeeds and the player then leaves because of it, only then will PlayerRemoving fire. It is the correct behavior and no documentation suggests otherwise.

5 Likes

PlayerRemoving still fires when they leave you just need to bind a function to the game closing i think

binding a function to the game closing should prevent it from stopping till the code its running is done allowing PlayerRemoving to do its thing

1 Like

This topic was automatically closed after 12 hours. New replies are no longer allowed.