Unexpected Behaviour With Server Scripts

Hello. I’m trying to make a game about cutting trees. I have a MainServer script inside my axe tool.
Everything is fine. But code works poorly with 2 players. I didn’t even test with more players.
Also my issue is when I try to cut second tree.
It says: 00:22:11.260 Players.LUPIN_OxyGeN.Backpack.Axe.MainServer:139: attempt to index nil with ‘Destroy’ - Server - MainServer:139.
But code continues to work completely fine.
Here is my full server code. I know It’s poorly coded.

local chopTree = game.ReplicatedStorage.ChoppingEvents.ChopTree  
local animationAssets = game.ReplicatedStorage.Animations
local tool = script.Parent




local playerAnimations = {} 

local function AnimationHandler(player, humanoid, num)
	local playerId = player.UserId

	if playerAnimations[playerId] then
		playerAnimations[playerId]:Stop()
		print(playerAnimations[playerId].Name .. " stopped")
	end

	local animator = humanoid:FindFirstChild("Animator") or humanoid:WaitForChild("Animator")
	local animation

	if num == 1 then
		animation = animator:LoadAnimation(animationAssets.anim1)
		print("anim1")
	elseif num == 2 then
		animation = animator:LoadAnimation(animationAssets.anim2)
		print("anim2")
	elseif num == 3 then
		animation = animator:LoadAnimation(animationAssets.anim3)
		print("anim3")
	elseif num == 98231109 then
		animation = animator:LoadAnimation(animationAssets.debug)
	elseif num == 3582 then
		if playerAnimations[playerId] then
			playerAnimations[playerId]:Stop()
		end
		return
	end

	if animation then
		playerAnimations[playerId] = animation 
		animation:Play()
	end
end


local function RotateTree(part, degrees, duration, offset)
	if not part or not part:IsA("BasePart") then
		warn("Invalid part for rotation")
		return
	end

	local increment = degrees / (duration * 60) 
	local currentAngle = 0 

	
	local originalCFrame = part.CFrame

	
	local pivotPoint = originalCFrame * CFrame.new(offset)

	for _ = 1, duration * 60 do  
		currentAngle += increment

		part.CFrame = pivotPoint 
			* CFrame.Angles(math.rad(currentAngle), 0, 0) 
			* CFrame.new(-offset)

		task.wait(1 / 60)  
	end


	part.CFrame = pivotPoint 
		* CFrame.Angles(math.rad(degrees), 0, 0) 
		* CFrame.new(-offset)

	warn("Rotation completed")
end





chopTree.OnServerEvent:Connect(function(plr, tree,chopOrPush)
	warn("CHOP TREE EVENT CONNECTED")
	local moveTo = tree:FindFirstChild("stand") 
	local hitCount = tree.trunk.hitCount
	local playerCutting = plr.Character:WaitForChild("playerCutting")
	
	warn("TREE NAME "..tree.Name.. " TİP: ")
	
	if chopOrPush == "Chop" then

		warn("ChopOrpush= "..chopOrPush)
		if moveTo and plr and plr.Character then
			local char = plr.Character
			local hum = char:FindFirstChild("Humanoid") 
			local rootPart = char:FindFirstChild("HumanoidRootPart") 

			if hum and rootPart then
				hum:MoveTo(moveTo.Position)

				print("char moving to stand position")
				hum.MoveToFinished:Wait()

				tree.trunk.ProximityPrompt.Enabled = false

				if playerCutting.Value then
					return
				end

				playerCutting.Value = true 
				hum.WalkSpeed = 0
				hum.JumpPower = 0


				
				local oppositeDirection = moveTo.CFrame.LookVector * -1
				local newCFrame = CFrame.lookAt(rootPart.Position, rootPart.Position + oppositeDirection)
				rootPart.CFrame = newCFrame

				AnimationHandler(plr,hum, 1) 
				warn("AnimationHandler(1) 1")
				game.ReplicatedStorage.ChoppingEvents.axe.OnServerEvent:Connect(function()
					if playerCutting.Value == true and chopOrPush=="Chop" then
						AnimationHandler(plr,hum,2)
						hitCount.Value+=1



						if hitCount.Value >= 3 then
							tree.breakPart:FindFirstChild("WeldConstraint"):Destroy()

							warn("tree falling")
							playerCutting.Value = false
							wait(1.85)
							tree.breakPart.Size = Vector3.new(tree.breakPart.Size.X - 0.4, tree.breakPart.Size.Y, tree.breakPart.Size.Z - 0.4)
							tool.hit:Play()
							game.ReplicatedStorage.ClientEvents.CamShake:FireClient(plr,1.5,0.3)
							wait(0.30)
							tool.breakWood:Play()

							wait(3.05)
							char:WaitForChild("ChopOrPush").Value = "Push"
							tree.trunk.ProximityPrompt.Enabled = true
							tree.trunk.ProximityPrompt.ObjectText = "Push"
							hum.WalkSpeed = 16
							hum.JumpPower = 50
							
							
							
							AnimationHandler(plr,hum,3582)
						else
							wait(1.85)
							game.ReplicatedStorage.ClientEvents.CamShake:FireClient(plr,1,0.2)
							tree.breakPart.Size = Vector3.new(tree.breakPart.Size.X - 0.2, tree.breakPart.Size.Y, tree.breakPart.Size.Z - 0.2)
							print(hitCount.Value)
							tool.hit:Play()
							wait(3.35)
							AnimationHandler(plr,hum,1)
							warn("AnimationHandler(1) 2")

						end


					else
						warn("use your axe in tree")
					end

				end)

			end
		end
	elseif chopOrPush == "Push" then
		warn("ChopOrPush = "..chopOrPush)
		playerCutting.Value = false
		tree.trunk.ProximityPrompt.Enabled = false
		-- Animasyonu durdur
		AnimationHandler(plr,plr.Character.Humanoid, 3582)

		local char = plr.Character
		local hum = char:FindFirstChild("Humanoid") 
		local rootPart = char:FindFirstChild("HumanoidRootPart") 
		local log1 = tree.log1
		local log2 = tree.log2

		local log3 = tree:FindFirstChild("log3")
		local log4 = tree:FindFirstChild("log4")

		if log3 and log4 then
			warn("big pine tree")
		else
			warn("small pine tree")
		end

		if hum and rootPart then
			hum:MoveTo(moveTo.Position)
			
			print("char moving to stand position")
			-- Wait until character reaches
			hum.MoveToFinished:Wait()

			hum.WalkSpeed = 0
			hum.JumpPower = 0
			tree.breakPart.Anchored = true
			AnimationHandler(plr,hum,98231109)
			wait(1)

			tool.fall:Play()
			char:WaitForChild("ChopOrPush").Value = "Chop"

			game.ReplicatedStorage.ClientEvents.CamShake:FireClient(plr,0.2,2)
			RotateTree(tree.breakPart, 90, 3, Vector3.new(0, -tree.breakPart.Size.Y / 1.5, 0))
			wait(0.3)
			tree.breakPart.Anchored = false
			hum.WalkSpeed = 16
			hum.JumpPower = 50
			task.delay(2, function()
				game.ReplicatedStorage.DataEvents.connectEventForStat:FireClient(plr,"Cash","+",math.random(3,5))
				wait(0.1)
				game.ReplicatedStorage.DataEvents.connectEventForStat:FireClient(plr,"TreesCutted","+",1)
				tree.leaves:Destroy()
				warn("Tree leaves destroyed")

				tree.breakPart:WaitForChild("ProximityPrompt").Enabled = true
				--log1
				log1:WaitForChild("WeldConstraint"):Destroy()
				log1:WaitForChild("ProximityPrompt").Enabled = true
				--log2
				log2:WaitForChild("WeldConstraint"):Destroy()
				log2:WaitForChild("ProximityPrompt").Enabled = true
				tree.trunk.hitCount:Destroy()
				if log3 and log4 then
					log3:FindFirstChild("WeldConstraint"):Destroy()
					log3:FindFirstChild("ProximityPrompt").Enabled = true
					--log2
					log4:FindFirstChild("WeldConstraint"):Destroy()
					log4:FindFirstChild("ProximityPrompt").Enabled = true
				end



			end)


		end


	end

end)

MainClient script inside tool:

local tool = script.Parent
local debounce = false 
local debounce2 = false
local debounceTime = 5.25 

local plr = game.Players.LocalPlayer

tool.Activated:Connect(function()
	if debounce then
		return 
	end

	debounce = true 
	if plr.Character:WaitForChild("playerCutting").Value == true then
		game.ReplicatedStorage.ChoppingEvents.axe:FireServer()
		print("tool activated")
	end

	task.wait(debounceTime)
	debounce = false
end)

Also here is my serverscript inside proximityPrompts. I use them to move char to position. then click with axe and cut trees.

local chop = game.ReplicatedStorage.ChoppingEvents.connect 
local tree = script.Parent.Parent.Parent  


script.Parent.Triggered:Connect(function(player)
	print("Proximity Prompt Triggered")
	if player.Character:WaitForChild("ChopOrPush").Value == "Chop" then
		chop:FireClient(player,tree,player.Character:WaitForChild("ChopOrPush").Value)
	elseif player.Character:WaitForChild("ChopOrPush").Value == "Push" then
		chop:FireClient(player,tree,player.Character:WaitForChild("ChopOrPush").Value)
	end
end)

connect localscript:

game.ReplicatedStorage.ChoppingEvents.connect.OnClientEvent:Connect(function(tree,val)
	game.ReplicatedStorage.ChoppingEvents.ChopTree:FireServer(tree,val)
end)

my whole log while trying to cut first tree:

00:33:26.786  Proximity Prompt Triggered  -  Server - chop:7
  00:33:26.802  CHOP TREE EVENT CONNECTED  -  Server - MainServer:84
  00:33:26.803  TREE NAME smallPineTree TİP:   -  Server - MainServer:89
  00:33:26.803  ChopOrpush= Chop  -  Server - MainServer:93
  00:33:26.803  char moving to stand position  -  Server - MainServer:102
  00:33:27.257  anim1  -  Server - MainServer:23
  00:33:27.257  AnimationHandler(1) 1  -  Server - MainServer:122
  00:33:28.251  tool activated  -  Client - MainClient:16
  00:33:28.269  anim1 stopped  -  Server - MainServer:15
  00:33:28.269  anim2  -  Server - MainServer:26
  00:33:30.120  1  -  Server - MainServer:156
  00:33:33.472  anim2 stopped  -  Server - MainServer:15
  00:33:33.472  anim1  -  Server - MainServer:23
  00:33:33.472  AnimationHandler(1) 2  -  Server - MainServer:160
  00:33:33.983  tool activated  -  Client - MainClient:16
  00:33:33.991  anim1 stopped  -  Server - MainServer:15
  00:33:33.991  anim2  -  Server - MainServer:26
  00:33:35.847  2  -  Server - MainServer:156
  00:33:39.197  anim2 stopped  -  Server - MainServer:15
  00:33:39.197  anim1  -  Server - MainServer:23
  00:33:39.197  AnimationHandler(1) 2  -  Server - MainServer:160
  00:33:39.598  tool activated  -  Client - MainClient:16
  00:33:39.610  anim1 stopped  -  Server - MainServer:15
  00:33:39.610  anim2  -  Server - MainServer:26
  00:33:39.610  tree falling  -  Server - MainServer:133
  00:33:44.817  anim2 stopped  -  Server - MainServer:15
  00:33:45.833  Proximity Prompt Triggered  -  Server - chop:7
  00:33:45.856  CHOP TREE EVENT CONNECTED  -  Server - MainServer:84
  00:33:45.856  TREE NAME smallPineTree TİP:   -  Server - MainServer:89
  00:33:45.856  ChopOrPush = Push  -  Server - MainServer:174
  00:33:45.856  anim2 stopped  -  Server - MainServer:15
  00:33:45.856  small pine tree  -  Server - MainServer:192
  00:33:45.856  char moving to stand position  -  Server - MainServer:198
  00:33:46.059  anim2 stopped  -  Server - MainServer:15
  00:33:50.467  Rotation completed  -  Server - MainServer:76
  00:33:52.800  LUPIN_OxyGeN için Cash değeri + 3 oldu. Yeni Değer: 243  -  Server - plrDB:90
  00:33:52.879  Tree leaves destroyed  -  Server - MainServer:222
  00:33:52.911  LUPIN_OxyGeN için TreesCutted değeri + 1 oldu. Yeni Değer: 37  -  Server - plrDB:90

and here is trying to cut second tree:

00:34:36.531  Proximity Prompt Triggered  -  Server - chop:7
  00:34:36.560  CHOP TREE EVENT CONNECTED  -  Server - MainServer:84
  00:34:36.560  TREE NAME smallPineTree TİP:   -  Server - MainServer:89
  00:34:36.560  ChopOrpush= Chop  -  Server - MainServer:93
  00:34:36.561  char moving to stand position  -  Server - MainServer:102
  00:34:37.206  debug stopped  -  Server - MainServer:15
  00:34:37.206  anim1  -  Server - MainServer:23
  00:34:37.206  AnimationHandler(1) 1  -  Server - MainServer:122
  00:34:37.757  tool activated  -  Client - MainClient:16
  00:34:37.766  anim1 stopped  -  Server - MainServer:15
  00:34:37.766  anim2  -  Server - MainServer:26
  00:34:37.766  anim2 stopped  -  Server - MainServer:15
  00:34:37.766  anim2  -  Server - MainServer:26
  00:34:37.766  Players.LUPIN_OxyGeN.Backpack.Axe.MainServer:131: attempt to index nil with 'Destroy'  -  Server - MainServer:131
  00:34:37.766  Stack Begin  -  Studio
  00:34:37.767  Script 'Players.LUPIN_OxyGeN.Backpack.Axe.MainServer', Line 131  -  Studio - MainServer:131
  00:34:37.767  Stack End  -  Studio
  00:34:39.616  1  -  Server - MainServer:156
  00:34:42.971  anim2 stopped  -  Server - MainServer:15
  00:34:42.972  anim1  -  Server - MainServer:23
  00:34:42.972  AnimationHandler(1) 2  -  Server - MainServer:160
  00:34:43.456  tool activated  -  Client - MainClient:16
  00:34:43.473  anim1 stopped  -  Server - MainServer:15
  00:34:43.473  anim2  -  Server - MainServer:26
  00:34:43.473  anim2 stopped  -  Server - MainServer:15
  00:34:43.473  anim2  -  Server - MainServer:26
  00:34:43.474  Players.LUPIN_OxyGeN.Backpack.Axe.MainServer:131: attempt to index nil with 'Destroy'  -  Server - MainServer:131
  00:34:43.474  Stack Begin  -  Studio
  00:34:43.474  Script 'Players.LUPIN_OxyGeN.Backpack.Axe.MainServer', Line 131  -  Studio - MainServer:131
  00:34:43.474  Stack End  -  Studio
  00:34:45.325  2  -  Server - MainServer:156
  00:34:48.678  anim2 stopped  -  Server - MainServer:15
  00:34:48.678  anim1  -  Server - MainServer:23
  00:34:48.678  AnimationHandler(1) 2  -  Server - MainServer:160
  00:34:48.964  tool activated  -  Client - MainClient:16
  00:34:48.977  anim1 stopped  -  Server - MainServer:15
  00:34:48.977  anim2  -  Server - MainServer:26
  00:34:48.977  tree falling  -  Server - MainServer:133
  00:34:48.978  use your axe in tree  -  Server - MainServer:166
  00:34:54.185  anim2 stopped  -  Server - MainServer:15
  00:34:55.206  Proximity Prompt Triggered  -  Server - chop:7
  00:34:55.236  CHOP TREE EVENT CONNECTED  -  Server - MainServer:84
  00:34:55.236  TREE NAME smallPineTree TİP:   -  Server - MainServer:89
  00:34:55.236  ChopOrPush = Push  -  Server - MainServer:174
  00:34:55.237  anim2 stopped  -  Server - MainServer:15
  00:34:55.237  small pine tree  -  Server - MainServer:192
  00:34:55.237  char moving to stand position  -  Server - MainServer:198
  00:34:55.490  anim2 stopped  -  Server - MainServer:15
  00:34:59.971  Rotation completed  -  Server - MainServer:76
  00:35:02.293  LUPIN_OxyGeN için Cash değeri + 4 oldu. Yeni Değer: 247  -  Server - plrDB:90
  00:35:02.379  Tree leaves destroyed  -  Server - MainServer:222
  00:35:02.397  LUPIN_OxyGeN için TreesCutted değeri + 1 oldu. Yeni Değer: 38  -  Server - plrDB:90
2 Likes

A nil error message means the item could not be found.

If you are typing a direct path to an item in your code, then the item needs to exist or you will get this error.

Try making sure the item exists before trying to access it.

Sorry for late respond.
When I try to chop second tree. It still tries to find Weld inside my previous tree. And It cant find of course because I destroy Welds after chopping trees. Script somehow stays in first tree.

It happens in this line:

tree.breakPart:FindFirstChild("WeldConstraint"):Destroy()

But my code still works fine.

My actual problem is Script works poorly with 2 or more players. I fixed most of parts but it still works poorly.
Like I cant start to chop trees for first a few seconds.

Instead of something like this:
tree.breakPart:FindFirstChild("WeldConstraint"):Destroy()

Use:

local weld = tree.breakPart:FindFirstChild("WeldConstraint")
if weld then 
    weld:Destroy() 
end

Although your script keeps working because you are wrapping this code in a task.delay function the failure will cause any lines of code after that not to execute as you expect them to.

Also I’d go through and reevaluate the wait statements you are using. It seems like a very long debounce delay on your axe to wait 5.25 seconds before resetting debounce. Usually debounce is very short like maybe task.wait(.1). Instead of doing a WaitForChild(“playerCutting”) inside your activated function you should be able to set that as a variable just below where you define plr and that way just check the value when activated fires.