Table not passing through to VFX Handler

Okay this is the millionth time I’ve made a post about something related to hitboxes but it’s been quite a difficult subject to understand for me and I thank everyone who’s been helping me along the way! Through everything I’ve learned, I’ve decided to split between having my hitboxes be created on the SERVER and and a VFX Handler for the CLIENT to get the best of both worlds.

In this version, I am using hitbox on the server that then gets a table of everyone who has been hit (mind that I want to have attacks that linger as well for more than a few frames) to then fire to the VFX Handler, sort of what I’ve already been doing. The problem arises when sending the table information to the VFX handler to have it process the VFX of the players who got hit… as it isn’t even sending it at all. I want the VFX Handler to be able to notice if a hit has been whiffed or if it actually connected with something as well, which I what I had in a previous iteration.

My initial hunch is that a table isn’t even required for this, but instead that every time the hitbox gets touched all clients are fired and whatever VFX I want for them to play then plays, but how I would make the VFX Handler aware of if the hitbox whiffed as well?
Hitbox Validation: (Server Script)

--Begins VFX for Slam and validates the hit
config.slamVFX.OnServerEvent:Connect(function(plr)

	local pChar = plr.Character
	local hrp = pChar:WaitForChild("HumanoidRootPart")
	config.slamVFX:FireAllClients(plr)

	--If the hit is valid it gets sent to the VFX handler
	local validator = config.slamValidator.OnServerEvent:Connect(function(plr)
	
		task.delay(1.2, function()
			
			local validHit = {}
			
			local hitbox = hitboxModule.CreateHitbox()

			local paramters = OverlapParams.new()
			paramters.FilterDescendantsInstances = {pChar}

			hitbox.Size = Vector3.new(10,5,10)
			hitbox.CFrame = hrp
			hitbox.VisualizerTransparency = 0.5
			hitbox.OverlapParams = paramters
			hitbox.VelocityPrediction = true
			hitbox.VelocityPredictionTime = 0.2

			hitbox:Start()

			hitbox.Touched:Connect(function(hit, vHum)

				local vChar = vHum.Parent
				local vrp = vChar:FindFirstChild("HumanoidRootPart")

				if vChar and not table.find(validHit, vChar) then
					table.insert(validHit, vChar)
	
				end

				task.delay(0, function()
					knockbackModule.knockbackAttributes(plr, hrp, vChar, vrp, 10, 0, 40, 0)
					print("Awarding points to "..plr.Name)
				end)
				
			end)	
		
			config.slamValidator:FireAllClients(validHit)
		
			task.delay(0.1, function()
				hitbox:Stop()
			end)
			
		end)	

	end)
	task.delay(1, function()
		validator:Disconnect()
	end)
end)
--Slam VFX
config.slamVFX.OnClientEvent:Connect(function(plr)
	print("Playing VFX for Slam!")

	local pChar = plr.Character
	local pHum = pChar:WaitForChild("Humanoid")
	local hrp = pChar:WaitForChild("HumanoidRootPart")
	local pAnim = pHum.Animator:LoadAnimation(config.slamAnim)

	pAnim:Play()
	config.whoosh:Play()

	pAnim:GetMarkerReachedSignal("Knockback"):Connect(function()
		
		config.slamImpact:Play()
		
		local rocksClone = config.slamRocks:Clone()
		local primaryRock = rocksClone.PrimaryPart

		for _, effect in pairs (config.slamExplo:GetChildren()) do 
			local effectClone = effect:Clone()
			effectClone.Parent = primaryRock
		end

		local rockTweenInfo = TweenInfo.new(0.5, Enum.EasingStyle.Sine, Enum.EasingDirection.Out, 0, false, 0)
		local rockTweenProperties = {
			["CFrame"] = hrp.CFrame + Vector3.new(0,-3,0)
		}
		local rockTween = TS:Create(primaryRock, rockTweenInfo, rockTweenProperties)

		rocksClone:PivotTo(hrp.CFrame + Vector3.new(0,-5,0))
		rocksClone.Parent = workspace

		rockTween:Play()

		game.Debris:AddItem(rocksClone, 1.2)
		
		--Ability Victim VFX
		local validator = config.slamValidator.OnClientEvent:Connect(function(validHit)

			print(validHit)
			if #validHit >= 1 then
				print("Valid hit on VFX!")
				for _, vChar in pairs (validHit) do
					
				end
			else
				print("Whiff on VFX!")
			end
		end)
		task.delay(1, function()
			validator:Disconnect()
		end)
		
	end)

end)

I know these posts have been quite exhaustive but there’s no other way to learn faster than asking people on the forums! Your help as always is appreciated.

It’s probably because you’re sending before the hitbox actually touches and adds characters.

Also you might want to simplify your code, you’ve got a bunch of delayed tasks that don’t seem necessary.

(I’ll read through any responses tomorrow)

Hi! I’ve been messing around with it for a bit and it seems like this works currently, though I’m not too sure about it firing all clients for each person hit. This doesn’t account for the hitbox being able to whiff either, which is something that I would want.

--Begins VFX for Slam and validates the hit
config.slamVFX.OnServerEvent:Connect(function(plr)


	local pChar = plr.Character
	local hrp = pChar:WaitForChild("HumanoidRootPart")
	config.slamVFX:FireAllClients(plr)

	--If the hit is valid it gets sent to the VFX handler
	local validator = config.slamValidator.OnServerEvent:Connect(function(plr)
	
		task.delay(1.2, function()
			
			local hitbox = hitboxModule.CreateHitbox()

			local paramters = OverlapParams.new()
			paramters.FilterDescendantsInstances = {pChar}

			hitbox.Size = Vector3.new(10,5,10)
			hitbox.CFrame = hrp
			hitbox.VisualizerTransparency = 0.5
			hitbox.OverlapParams = paramters
			hitbox.VelocityPrediction = true
			hitbox.VelocityPredictionTime = 0.2

			hitbox:Start()

			hitbox.Touched:Connect(function(hit, vHum)

				local vChar = vHum.Parent
				local vrp = vChar:FindFirstChild("HumanoidRootPart")

				print(hitbox.HitList) --Changes I made
				config.slamValidator:FireAllClients(hitbox.HitList)

				task.delay(0, function()
					knockbackModule.knockbackAttributes(plr, hrp, vChar, vrp, 10, 0, 40, 0)
					print("Awarding points to "..plr.Name)
				end)
				
			end)
			
			task.delay(0.1, function()
				hitbox:Stop()
			end)
			
		end)	

	end)
	task.delay(1, function()
		validator:Disconnect()
	end)
end)

To note as well, the module script I use has a built in variable called hitbox.hitlist which is what im using now instead of making an unnecessary table. (the .touched event is also a different notation for the modules GetPartsBoundInBox table, so don’t worry about that either!)
On top of that, you mention a lot of unneeded delays I have in my script, how would I optimize/get rid of those then?

Great to see you’ve fixed the main issue!

There’s a few places where I notice you don’t really need task.delay, as a task.wait or otherwise would suffice.

I would also suggest storing your functions, so you’re not creating new anonymous functions each connection, as I don’t believe the Luau compiler is able to cache the closures for you automatically.

(These are all minor performance/design nitpicks, not the end of the world!)