So I have an auto rejoin system in my game that works through a “marco, polo” system where a client sends a ping to the server and the server sends one back and if the client dosent receive one within 6 seconds or so itll assume that client is disconnected and initiates the recovery process, I’ve tested the grace period roblox gives to clients before fully kicking them out and disabling the engine and it seems to be around 20 seconds sometimes being as low as 10 so its not very stable, if the grace period ends before the recovery system starts the client will be completely lost so i was wondering if there was someway to detect when a client fully disconnects and fire an event before that happens instead of using a not 100% reliable system, I tried playeremoving but that only fires if the player closes roblox not disconnects from it and I tried running a connection and detecting if it is halted for too long but it seems the connection just gets terminated.
Every once in a while send a message to the server as a client. If the server doesn’t respond with it’s own message. Make the client initiate a rejoin.
( if teleports are allowed on client, since im pretty sure you have to initiate a teleport through server )
If the player still has no connection while being teleported, the game will just instantly reject the join with the obvious reason of no internet connection.
that would work the problem is if you send the messsage too frequently you will wear out the server or you can falsely reconnect players over server lag spikes and if you send it not frequently enough the player might get fully disconnected before you can detect a faulty connection and by then youve aleady lost them what i need is some way to detect when exactly roblox fully discconnects the player and gives them the disconnection pop
The server only considers a client gone after a built-in ~10-20 second grace window, and that moment is exactly when PlayerRemoving fires. That’s the earliest point you can react, everything prior must be done with your own heartbeat system
Your best bet is something like this:
Ping every second from the client - use a RemoteEvent called Ping so you only ever send a tiny payload
Record the last-seen timestamp on the server
Heartbeat-check for stale entries - When the timestamp gap exceeds a set timeout (e.g. 6 seconds) treat the client as lost and start your recovery
Let PlayerRemoving clean up later - you can safely save data here
FYI: A small ping for every player on the server every second wont affect the server much at all.
To get technical:
A RemoteEvent adds ~9 bytes` of protocol overhead. A simple “ping” that only passes the player object (which is implicit) or a tiny boolean/number ends up around 15-20 bytes total
Roblox’s soft cap is ~50 kB/s per cleint. One 20 byte ping every second uses 0.02 kB/s. Even with 100 players you’re still under 2 kB/s server-side, which is negligible
The call rate limit throttle only kicks in when a single remote exceeds ~20 calls/s, or you push the 50 kB/s budget, so you’re very much below both thresholds
Example client script:
local Ping = game.ReplicatedStorage:WaitForChild("Ping")
while task.wait(1) do
Ping:FireServer()
end
Example server script:
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local PingEvent = game.ReplicatedStorage:WaitForChild("Ping")
local TIMEOUT = 6 -- seconds
local lastSeen = {}
PingEvent.OnServerEvent:Connect(function(plr)
lastSeen[plr] = os.clock()
end)
Players.PlayerAdded:Connect(function(plr)
lastSeen[plr] = os.clock()
end)
Players.PlayerRemoving:Connect(function(plr)
lastSeen[plr] = nil
end)
RunService.Heartbeat:Connect(function()
local now = os.clock()
for plr, t in pairs(lastSeen) do
if now - t > TIMEOUT then
-- client considered lost; trigger your recovery
-- e.g. TeleportService:TeleportAsync/place re-join logic
lastSeen[plr] = now -- optional: stop repeats
end
end
end)
shame roblox is very restrictive with error message access but i guess it makes sense and i suppose if a client dosent send a signal for atleast 5 seconds its safe to assume they wont be reconnecting anytime soon this helped alot thanks