Need Help with fireball destroying too early

I have a fireball projectile script, and I’m running into a problem with how it gets destroyed. It seems like the fireball is being destroyed before it actually hits the target. I think this might just be a visual issue due to network latency.

I tried using SetNetworkOwner , but that made it worse—it ended up delaying the destruction instead, making the fireball fly for about a second longer before being destroyed.

I’m not sure which behavior is better, or how to properly fix the issue so that the destruction feels accurate and consistent across the network. Any advice or suggestions for improving this would be appreciated.

local rem = script.Parent:WaitForChild("LetGoEvent")
local playerHandToggle = {}

rem.OnServerEvent:Connect(function(player, targetPosition)
	local character = player.Character
	if not character then return end

	local leftHand = character:FindFirstChild("LeftHand") or character:FindFirstChild("Left Arm")
	local rightHand = character:FindFirstChild("RightHand") or character:FindFirstChild("Right Arm")
	if not leftHand or not rightHand then return end

	local useRightHand = playerHandToggle[player] or false
	playerHandToggle[player] = not useRightHand
	local firingPart = useRightHand and rightHand or leftHand

	local fb = game.ReplicatedStorage.Assets.Magic:Clone()
	fb.Parent = workspace
	fb.CFrame = firingPart.CFrame


	local fireDirection = (targetPosition - fb.Position).Unit
	fb.CFrame = CFrame.new(fb.Position, fb.Position + fireDirection)

	local bodyVelocity = Instance.new("BodyVelocity")
	bodyVelocity.Velocity = fireDirection * 70
	bodyVelocity.MaxForce = Vector3.new(1e5, 1e5, 1e5)
	bodyVelocity.Parent = fb

	local touched = false


	fb.Touched:Connect(function(hit)
		if touched then return end
		if hit:IsDescendantOf(player.Character) then return end

		touched = true

		-- Stop movement
		if fb:FindFirstChild("BodyVelocity") then
			fb.BodyVelocity:Destroy()
		end

	
		fb.Anchored = true


		task.delay(0.1, function()
			if fb then fb:Destroy() end
		end)
	end)


	task.delay(5, function()
		if fb and not touched then
			fb:Destroy()
		end
	end)
end)

i already tried to fix it but it didnt change anything

Hey!
Setting Network Owner for the player does fix the fireball getting destroyed early, but it creates a delayed destruction.
The reason is because you are handling the .Touched event on the server.
Ideally you should register .Touched on client, and then invoke the server in that touched event function, so that the server can validate that request and everything.
Yes, this does create room for exploiters, but as long as you are validating stuff correctly, you shouldn’t have to worry too much.

You may have to use 2 remotes functions, or 1 remote function, and 1 remote event.
For example, on client side like normally, invoke the server to create the fireball and set up BodyVelocity and such, then it can return that fireball, and then with that returned fireball, register a .Touched on client. Then like I said above, send a remote event (or remote function) to the server to validate it.

This may or may not work, I can’t really test it, but lmk.

1 Like

why not just use game.DebrisAddItem?