I have been coding games for over 10 years, and to this day, I find out that some code in my main game loop can break due to characters no longer existing while within a if Player.Character then statement. Obviously code takes time to execute, so anything within that statement becomes subject to the original statement no longer being true.
Line 94, the original statement to make sure the Character exists
The error, line 118 (after it had already executed the same if statement on line 114) The error implying the player left in-between these if statements running; therefore, plr.Character is no longer a valid object to refer to, thus breaking the FindFirstChild call.
I could make a if plr.Character statement each and every time I try to reference it.
I could wrap this in a spawn to avoid it stopping the break from killing the entire game loop, as this is a module attached to the game loop, however, I’d like to see if there’s any other solutions. What do you think?
In this situation I would recommend using pcall() in order to handle the errors if they occur. This way, you would not have an errors, and you would not have to use a spawn statement. Also, you could reformat your if statements to look like:
if plr.Character and plr.Character:FindFirstChild("Whatever") then
end
local character = plr.Character
if character then
local jetpackTool = character:FindFirstChild("JetpackTool")
if jetpackTool then
-- Do your thing
end
end
I am assuming all of these objects that you are :Destroy()ing are tool objects, and of course a character can only have one tool parented to it at a time, meaning you don’t necessarily have to check for each object, just :Destroy() the first plr.Character:FindFirstChildOfClass("Tool").
As for the message to pass to .AwardBadge(), it can be simply achieved using some string manipulating, and I also assume that this is the reason why you did the if statements in the first place. You would need an if statement to check if the object’s name is UltimatePath since that doesn’t get awarded a badge for.
if plr.Character then
local tool = plr.Character:FindFirstChildOfClass("Tool")
if tool then
if tool.Name ~= "UltimatePath" then
BadgeAwardModule.AwardBadge(plr, "Badge"..tool.Name:gsub("Tool", "").."Survive")
end
tool:Destroy()
end
end
This is surely guaranteed to not error, since there is no way a player would leave between these two lines
and plr.Character is not used anywhere else. Only problem I would think of is .AwardBadge causing issues if the player left before the program’s flow got there.