Server script crashing when checking for items

I want to make sure that when players aren’t holding a “Sword” item, the server checks it. However, it causes the server script to crash.

Server script:

while (true) do
    for _, v in pairs(game.Players:GetChildren()) do
        if v.Character:FindFirstChild("Sword") == nil then -- Crashes here
            hideSwordEffects(v)
        end
    end
    RunService.Heartbeat:Wait()
end
2 Likes

Looks like a typo to me, use ~= to check if the sword isn’t nil

- if v.Character:FindFirstChild("Sword") == nil then
+ if v.Character:FindFirstChild("Sword") ~= nil then

Well. I want to make sure that the player has the Sword. If not, then it should return nil right?

Error message: attempt to index nil with 'FindFirstChild'

I don’t know much of what you’re trying to do but I assume its because you are using Character:FindFirstChild
If the sword your looking for is a tool then search the backpack instead
(v = player, right?)
Try this

while (true) do
    for _, v in pairs(game.Players:GetChildren()) do
        if v.Backpack:FindFirstChild("Sword") ~= nil then
            hideSwordEffects(v)
        end
    end
    RunService.Heartbeat:Wait()
end
--//Services
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

--//Loops
while true do
	for i, Player in ipairs(Players:GetPlayers()) do
		if Player.Character and not Player.Character:FindFirstChild("Sword") then
			hideSwordEffects(v)
		end
	end

	RunService.Heartbeat:Wait()
end
  1. You can just use :GetPlayers() instead of :GetChildren() when getting players in the Players service.

  2. You should make sure the character exists by using

 if v.Character then
  1. You do not need to check if the sword is nil if you are already checking if the sword is found.
if not  v.Character:FindFirstChild("Sword") then

I would give an example but @Katrist Has given you a good example of all three points in his post. above

If it still crashes try adding a wait.

Alternatively you can also just use .ChildAdded or .ChildRemoved instead of a loop.
example:

Player.Character.ChildRemoved:Connect(function(Object)
	if Object.Name == ("Sword") then
		hideSwordEffects(Player)
	end
end)

It’s a tool instance so it’d be better to just use its Equipped RBXScriptSignal object.

local players = game:GetService("Players")

players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		local backpack = player:WaitForChild("Backpack")
		local sword = backpack:WaitForChild("Sword")
		sword.Equipped:Connect(function()
			--Do code.
		end)
	end)
end)
1 Like

Try this:

local Time = 10

function checkItemState(Player: Player, Item)
    if Player.Character:FindFirstChild(Item.Name) ~= nil then
        return "Item state: Item isn't nil!"
    else
        hideSwordEffects(Player)
        return "Item state: Item is nil!"
    end
end

while task.wait(Time / 2) do
    task.spawn(function()
        for _, Index in ipairs(game.Players:GetPlayers()) do
            local ItemState = checkItemState(Index, "Sword")
            print(ItemState)
        end
    end)
end

Hopefully this helps! :smile:

I assumed he had a reason, like some big server script that handles everything, and he wanted to know when something named sword was removed from the character.

But he was satisfied with your answer so it must have inspired him to go a different direction entirely. Best of luck to him, and thanks.