How to check if a player Dies/Resets or leaves the game mid function

Hi, I have a AI check-in system for an airline, it runs through a whole process and works fine. However obviously if a player resets or leaves the game mid function that the system would break preventing any other players from using it.

We’re looking at 80-130+ passengers so its quite important that I can take into consideration any situations which could break the system. It communicates between a local script for the GUI elements and then a server script for the ensuring stuff is visible to all players.

Tired PlayerRemoving but couldn’t get it to work or unsure how to structure it.

It sounds like the issue is that the reference to a character in your script becomes nil. I’m not sure what your system looks like exactly, but I can suggest checking if the character exists before using it.

if character ~= nil then
	-- Run code using the character --
end

You might also need to listen in to the Player’s CharacterAdded event and link the new character back into your main code if the player resets.

player.CharacterAdded:Connect(function(newCharacter)
	-- Link new character into main code --
end)

It’s hard to say what might work without seeing the code, but I hope this helps!

We need more infos to know how to help you, but a way to maybe fix your issue is like you tried with PlayerRemoving but you have to make like a reset function for the check in so on removing, it gets resetted. But yeah, cant say more if we havent anything to base on

Maybe you can do a while loop and do checks to see if the player is alive or still in the game. You could also disable the reset button.

Ok well here’s the code for the serverscript. Player interaction done through the localscript within our dialog UI

local main = script.Parent.Parent
local AI = main.NPC
local Events = main.Events
local Dialog = main.Dialog.ChatDialog
local Animations = main.Animations
local Detector = script.Parent.Detector.Value
local Conv = script.Parent.Parent.Conveyor
local TP = script.Parent.Parent.TP
local begone = script.Parent.Parent.begone
local Sensor = script.Parent.Parent.Sensor

local ReplicatedStorage = game:GetService("ReplicatedStorage")

-- ATTACHMENTS
local StartInteract = main.InterationPoints.Start.Interact
local PassportAInteract = main.InterationPoints.PassportAttachGive.Interact
local TakeItems = main.InterationPoints.TakeItems.Interact -- (Passport & Printed Boarding Pass)
local PlaceBag = main.InterationPoints.PlaceBaggage


activeuser = ""
sensoractive = false

-- START UP ---------------------------------------------------------------------

-- Trigger
StartInteract.Triggered:Connect(function(Player)
	Player.Character.HumanoidRootPart.CFrame = TP.CFrame
	Player.Character.HumanoidRootPart.Anchored = true
	activeuser = Player.Name
	sensoractive = true
	local gui = Dialog:Clone()
	gui.Frame.HandlerLocal.Enabled = true
	gui.Parent = Player.PlayerGui
	StartInteract.MaxActivationDistance = 0
	Events.Startup:FireClient(Player)
	Conv.Buffer.CanCollide = true
end)

-- Go Away Sensor (no pedos)
Sensor.Touched:Connect(function(hit)
	local player = game.Players:GetPlayerFromCharacter(hit.Parent)
	if sensoractive == true then	
		if player.Name ~= activeuser then	
			player.Character.HumanoidRootPart.CFrame = begone.CFrame
		end
	end
end)

-- CHECK IN ---------------------------------------------------------------------

-- Passport Show/Hide
Events.Passport.OnServerEvent:Connect(function(Player, Passport, Show)	
	if Show == true then	
		Passport.Cover.Transparency = 0
		Passport.Page.Transparency = 0			
	elseif Show == false then 	
		Passport.Cover.Transparency = 1
		Passport.Page.Transparency = 1		
	end
end)

-- Boarding Pass Show/Hide
Events.BoardingPass.OnServerEvent:Connect(function(Player, Passport, Show)
	if Show == true then	
		Passport.Transparency = 0	
	elseif Show == false then	
		Passport.Transparency = 1	
	end
end)


-- Baggage Tag Show/Hide
Events.BagTag.OnServerEvent:Connect(function(Player, Passport, Show)
	if Show == true then
		Passport.Part1.Transparency = 0
		Passport.Part2.Transparency = 0	
	elseif Show == false then	
		Passport.Part1.Transparency = 1
		Passport.Part2.Transparency = 1	
	end
end)


-- Player Tools (Give / Remove)
Events.Tools.OnServerEvent:Connect(function(Player, ToolItem, Show)
	if Show == true then -- Gives Tool

		local Tool = ReplicatedStorage.CheckInSystem.Tools:FindFirstChild(ToolItem):Clone()
		Tool.Parent = Player.Backpack
		
	elseif Show == false then -- Removes Tool
		
		local Tool = Player.Backpack:FindFirstChild(ToolItem):Destroy()
		
	end
end)


-- Baggage Handling

local Slot = script.Parent.Parent.Detector

-- Places Bag on belt
Events.BaggagePlace.OnServerEvent:Connect(function(Player)
	
	print("triggered place bag")

	local SuitcaseModule = require(game.ServerScriptService.BaggageServer.Components.Suitcase)
	
	   Player.Character.Humanoid:UnequipTools()
	
	   Player.Backpack:FindFirstChild("Suitcase")
		
		local tool = Player.Backpack:FindFirstChild("Suitcase")
		local NewSuitcase = SuitcaseModule.New(tool)

		NewSuitcase:SetAttribute("Color3", color3Value)


		NewSuitcase.Parent = Slot
		NewSuitcase:SetPrimaryPartCFrame(Slot.CFrame)

		local tool = Player.Backpack:FindFirstChild("Suitcase"):Destroy()
		
		wait(8)

		NewSuitcase:SetAttribute("IsTagged", true)
	NewSuitcase:SetAttribute("Name", Player.Name)
	
end)

--Sends Suitcase
Events.SendBaggage.OnServerEvent:Connect(function(Player)
	for i,v in pairs(Slot.Suitcase:GetDescendants()) do
		if (v:IsA("MeshPart") or v:IsA("BasePart")) then
			v.Anchored = false
		end
	end
	Slot.Suitcase.Parent = workspace.BaggageSystemV3.System.Suitcases
	Conv.Buffer.CanCollide = false
	wait(2)
	Conv.Buffer.CanCollide = true

end)

-- Resets System
Events.Reset.OnServerEvent:Connect(function(Player)
	print("Resettting System, Please Wait...")
	Player.Character.HumanoidRootPart.Anchored = false
	StartInteract.MaxActivationDistance = 10
	activeuser = ""
	sensoractive = false
end)

And the Reset System is not working?

It works fine, however that’s only ran when the whole process is finished. And If the player were to die or leave the game midway through the check in process or mid function then it breaks. The issue is I don’t know how to get it to to-do something if the player were to leave or die.

Although I suppose I can do it if they just leave the game, as reset should be disabled regardless.

When you say:

Do you get an error in the output, or does the code continue to run but with undesirable behavior? If you’re not getting any errors in your output, what’s the undesirable behavior that’s occurring and breaking your system?

It’s very interactive with the player. Soon as it can’t find the activeuser when trying to run something relating to the camera, or giving a tool etc. The script then breaks at that point.

And even If they left/died during a point between functions when say waiting for the player to place their suitcase, it has no idea the player has left so isn’t able to reset itself to allow the next player to come and use the system.

I’ll see if I can spot something that might be causing issues in the code

Edit: @MsBasicallySoft On line 118, the color3Value does not exist:

Edit2: I’d also personally recommend to set the activeuser to the player’s UserId instead of their name, just in case

Thanks, but the code in itself is working fine as intended. I get no issues in normal operation. However this system is for roaviation airline usage where we get 80-130+ passengers so to put it simply, our systems need to be robust and idiot proof for lack of a better word.

We can disable reset & ensure our staff are not refreshing passengers that are using the machines which fixes that issue. However we still need some function to monitor ingame players, if a player leaves that matches the ‘activeuser’ value then the system can then initiate a reset to be ready for the next player that wishes to checkin.

1 Like

The suitcase stuff is talking to data for a tech group baggage system to allow integration with my system. All the modules and such are in the game on start up via their obscured loader.

1 Like

I’ve checked the code and I wasn’t able to spot anything else that looked out-of-place

I’m able to make an example system for you if you wish, but I’ll need to know the exact step-by-step process you’d like the system to perform

It’s quite complex with voicelines & both facial and body animations (complex by roav standards). What I’ve sent is only half the code as a lot of stuff is done client side on the players dialog gui.

All I need is a way to monitor ingame players and if the player that is using the system leaves the game then it resets, which sets everything it needs todo first like prompts, clears the baggage belt, etc, destroy the current server script then clone & parent a fresh copy from replicated storage into the system before enabling it.

I tried doing this however it doesn’t work.

local Players = game:GetService('Players')

local ActiveUser = script.Parent.ActiveUser.Value

Players.PlayerRemoving:Connect(function(Player)
    if Player.UserID == ActiveUser then
        print("Player has left the game, resetting machine")
        -- Does resetty system stuff
        ActiveUser = nil
    end
end)

I also added this line into the trigger on the serverscript, which when printed shows the correct user id.

	ActiveUserV = Player.UserId

I tested this already with the players username and it didn’t work.

Bit complicated sure, but its only on the occasion a player leaves, crashes or whatever mid using it. Under normal usage the system is able to reset itself just fine.

1 Like

Coroutines or the task library might be able to allow you to cancel the system once a player leaves. I’ve made an example that shows a per-player thread which cancels after the player leaves the game:

local Players = game:GetService("Players")

local threads = {}

local function onPlayerAdded(player)
	threads[player] = task.spawn(function()
		-- Initiate the system for the player in here
	end)
end

local function onPlayerRemoving(player)
	if threads[player] then
		task.cancel(threads[player])
		threads[player] = nil

		-- Then reset the system
	end
end

Players.PlayerAdded:Connect(onPlayerAdded)
Players.PlayerRemoving:Connect(onPlayerRemoving)

No idea what that is, but the system has to start with the proximity prompt at the check in desk. I can try get a video of it in operation which might clarify some things.

1 Like

Bit of an older version but then general idea is the same.

1 Like

Tasks would be ideal to cancel this, I’ll write an example

Edit: @MissBasicallySoft Sorry for the late reply because a parcel got delivered, but this is esentially what you need to do:

local Players = game:GetService("Players")

local prompt = -- Where the prompt is located

local threads = {}

local function onPromptTrigger(player)
	threads[player] = task.spawn(function()
		-- Initiate the dialog system in here
	end)
end

local function onPlayerRemoving(player)
	if threads[player] then
		task.cancel(threads[player])
		threads[player] = nil
	end
end

prompt.Triggered:Connect(onPromptTrigger)
Players.PlayerRemoving:Connect(onPlayerRemoving)

Although do note that canceling a thread does not disconnect connections created within it, in that case you’ll need to do something like this:

local Players = game:GetService("Players")

local prompt = -- Where the prompt is located

local threads = {}
local connections = {}

local function onPromptTrigger(player)
	connections[player] = {}

	threads[player] = task.spawn(function()
		-- Initiate the dialog system in here

		table.insert(connections[player], exampleEvent:Connect(function()
			
		end))
	end)
end

local function onPlayerRemoving(player)
	if threads[player] then
		task.cancel(threads[player])
		threads[player] = nil

		for _, connection in connections[player] do connection:Disconnect() end
		connections[player] = nil
	end
end

prompt.Triggered:Connect(onPromptTrigger)
Players.PlayerRemoving:Connect(onPlayerRemoving)
1 Like

:pray: ty so much for you help, all working now. I owe you big time

1 Like