Combat works in studio but not in the actual game; can't detect players?

Okay, so this may be a reoccurring topic on the devforum, but I’ve looked through many threads and still can’t really find the solution to my problem.

I made a combat system that works fine in studio, but when it’s used in the actual game, it doesn’t work most of the time. Players are unable to hit each other. The issue revolves around the hitbox, yet when I hit a dummy both in studio and in-game the hitbox works perfectly, so I know the issue itself isn’t the hitbox (at least I strongly believe it isn’t). I’ve also tried team testing in studio and it works there too.

Before you ask, I have published the game, committed and applied scripts, used numerous different locations to store my scripts to see if it’d make a difference, and a majority of the basic solution you’d think of.

My server and module script is located in ServerScriptService and my local script is located in StarterPlayerScripts.

Here’s a GIF if you’d like to know what it currently looks like in the actual game:
https://gyazo.com/3835fd3c2ab873ca9522f85d06a0bae0

I’ll be happy to post the code if need be, but if you can think of any other reason as to why this is happening, please inform me!

I cannot help you without scripts relevant to your issue.

Here’s the click function of the combat on the client:


local enabled = true
mouse.Button1Down:Connect(function()
	
	if enabled == true then
		
		RS.Events.CombatEvent:FireServer("Combat", character.HumanoidRootPart.CFrame*CFrame.new(0,0,-2).p, "Left")
	end
end)

mouse.Button2Down:Connect(function()

	if enabled == true then

		RS.Events.CombatEvent:FireServer("Combat", character.HumanoidRootPart.CFrame*CFrame.new(0,0,-2).p, "Right")
	end
end)

Here’s the hitbox function of the combat located on the server:

local function Hitbox(percent, knockback, velocity, boolean)
		
		local region = Region3.new(V1 - Vector3.new(2,2,2), V1 + Vector3.new(2,2,2))
		local rtable = workspace:FindPartsInRegion3(region, nil, 20)
		
		for i,v in pairs(rtable) do
			
			if v.Parent:FindFirstChild("Humanoid") and v.Parent:FindFirstChild("Debounce") == nil and v.Parent ~= character then
				
				local debounce = Instance.new("BoolValue", v.Parent)
				debounce.Name = "Debounce"
				local stun = Instance.new("BoolValue", v.Parent)
				stun.Name = "Stun"
				
				game.Debris:AddItem(stun, 0.8)
				game.Debris:AddItem(debounce, 0.2)
				
				local enemypercent = v.Parent:FindFirstChild("Percentage")
				
				local BV = Instance.new("BodyVelocity",v.Parent.HumanoidRootPart)
				
				if v.Parent:FindFirstChild("Substitution") then
					
					local Sound = Instance.new("Sound")
					Sound.SoundId = "rbxassetid://147722098"
					local Log = Assets:FindFirstChild("Log"):Clone()
					Log.CFrame = v.Parent:FindFirstChild("HumanoidRootPart").CFrame
					Sound.Parent = Log
					local HRP = v.Parent:FindFirstChild("HumanoidRootPart")
					HRP.CFrame = player.Character:FindFirstChild("HumanoidRootPart").CFrame * CFrame.new(0,0,5)
					Log.Anchored = false
					Log.CanCollide = true
					Log.Parent = game.Workspace
					Sound:Play()
					Debris:AddItem(Log,1)
				elseif v.Parent:FindFirstChild("Blocking") then
				
					enemypercent.Value = enemypercent.Value + math.floor(percent/3 * 100)/100
					
					BV.MaxForce = Vector3.new(25000,25000,25000)
					BV.Velocity = character.HumanoidRootPart.CFrame.LookVector * (knockback/2)

					local blockvalue = v.Parent:FindFirstChild("Blocking")
					blockvalue.Value = blockvalue.Value - 4

					local effect = v.Parent.Torso:WaitForChild("BlockEffect")
					effect.Color = Color3.fromRGB(255,255,255)

					local info = TweenInfo.new(1, Enum.EasingStyle.Quint, Enum.EasingDirection.Out)
					local goals = {Color = Color3.fromRGB(255,0,0)}

					local tween = TS:Create(effect, info, goals)
					tween:Play()

					BlockSFX.Parent = v.Parent.HumanoidRootPart
					BlockSFX:Play()

					combatmodule.DamageVisual(v.Parent, math.floor(percent/3 * 100)/100)
				elseif v.Parent:FindFirstChild("PerfectBlock") then
					
					enemypercent.Value = enemypercent.Value

					local perfectstun = Instance.new("BoolValue", character)
					perfectstun.Name = "Stun"
					game.Debris:AddItem(perfectstun, 2)

					PerfectBlockSFX.Parent = v.Parent.HumanoidRootPart
					PerfectBlockSFX:Play()
				else
					
					enemypercent.Value += percent
					
					HitSFX.Parent = character.HumanoidRootPart
					HitSFX:Play()
					Debris:AddItem(HitSFX, 1)
					
					if not v.Parent:FindFirstChild("Blocking") or not v.Parent:FindFirstChild("PerfectBlock") then

						cloudfx.Parent = v.Parent.Torso
						cloudfx.Enabled = boolean
					end
					
					BV.MaxForce = Vector3.new(25000,25000,25000)
					
					if enemypercent.Value < 25 then
						BV.Velocity = character.HumanoidRootPart.CFrame.LookVector * knockback + Vector3.new(0,velocity,0)
					elseif enemypercent.Value < 50 then
						BV.Velocity = character.HumanoidRootPart.CFrame.LookVector * (knockback * 1.5) + Vector3.new(0,velocity,0)
					elseif enemypercent.Value < 75 then
						BV.Velocity = character.HumanoidRootPart.CFrame.LookVector * (knockback * 2) + Vector3.new(0,(velocity * 2),0)
					elseif enemypercent.Value < 100 then
						BV.Velocity = character.HumanoidRootPart.CFrame.LookVector * (knockback * 2.5) + Vector3.new(0,(velocity * 3),0)
					elseif enemypercent.Value < 125 then
						BV.Velocity = character.HumanoidRootPart.CFrame.LookVector * (knockback * 3) + Vector3.new(0,(velocity * 4),0)
					elseif enemypercent.Value < 150 then
						BV.Velocity = character.HumanoidRootPart.CFrame.LookVector * (knockback * 3.5) + Vector3.new(0,(velocity * 5),0)
					elseif enemypercent.Value < 175 then
						BV.Velocity = character.HumanoidRootPart.CFrame.LookVector * (knockback * 4) + Vector3.new(0,(velocity * 6),0)
					end
					
					combatmodule.ComboUI(combonumber, combotext, 1)
					combatmodule.HitEffect(v.Parent, ParticleFolder.HeavyEffect)
					combatmodule.DamageVisual(v.Parent, percent)
				
					coroutine.wrap(function()
						wait(0.7)
						cloudfx.Enabled = false

						game.Debris:AddItem(cloudfx, 1.3)
					end)()
					
					local hiteffect = {

						"rbxassetid://6198422351",
						"rbxassetid://6198425884",
						"rbxassetid://6198427665"

					}

					local value = math.random(1, #hiteffect)
					local chosen = hiteffect[value]

					local anim = CombatAnimFolder.HitEffectChosen
					anim.AnimationId = chosen
					local track = v.Parent.Humanoid:LoadAnimation(anim)
					track:Play()
					
					LastHitSFX.Parent = character.HumanoidRootPart
					LastHitSFX.Playing = boolean
					Debris:AddItem(LastHitSFX, 1)
				end
				
				game.Debris:AddItem(BV, 0.3)
			end
		end
	end

If you’re wanting to look at the entire server-sided code, then here’s that:

local RS = game:GetService("ReplicatedStorage")
local Debris = game:GetService("Debris")
local SS = game:GetService("ServerStorage")
local TS = game:GetService("TweenService")
local SSS = game:GetService("ServerScriptService")

local Assets = SS:WaitForChild("Assets")
local combatmodule = require(SSS.ServerModules.CombatModule)

local SFXFolder = RS.Music.SFX
local CombatAnimFolder = RS.Animations.Combat
local GeneralAnimFolder = RS.Animations.General
local ParticleFolder = RS.ParticleFX
local PartFX = RS.PartFX

RS.Events.CombatEvent.OnServerEvent:Connect(function(player, action, V1, V2, Duration)

	local character = player.Character
	local humanoid = character:WaitForChild("Humanoid")
	local cloudfx = ParticleFolder.Cloud:Clone()
	
	local enable = character:FindFirstChild("Enabled")
	
	local combo = character:FindFirstChild("Combo")
	
	local combonumber = player.PlayerGui.ComboUI.ComboNumber
	local combotext = player.PlayerGui.ComboUI.ComboText
	
	local HitSFX = RS.Music.SFX.HitSFX:Clone()
	local HitSwingSFX = RS.Music.SFX.HitSwing:Clone()
	local BlockSFX = RS.Music.SFX.BlockSFX:Clone()
	local PerfectBlockSFX = RS.Music.SFX.PerfectBlockSFX:Clone()
	local LastHitSFX = RS.Music.SFX.LastHitSFX:Clone()
	local SoundChosenSFX = RS.Music.SFX.SoundChosen:Clone()
	
	local id1 = RS.Music.SFX.Sound1.SoundId
	local id2 = RS.Music.SFX.Sound2.SoundId
	local id3 = RS.Music.SFX.Sound3.SoundId

	local damagetable = {

		["Punch"] = math.random(500, 700)/100,
		["Kick"] = math.random(600, 800)/100,
		["Sweep"] = math.random(300, 500)/100,
		["BlockM1"] = math.random(200, 300)/100,
		["BlockM2"] = math.random(300, 400)/100,
		["BlockSweep"] = math.random(100, 300)/100

	}

	local function Sound()

		local soundeffect = {

			id1,
			id2,
			id3

		}

		local soundvalue = math.random(1, #soundeffect)
		local soundchosen = soundeffect[soundvalue]

		SoundChosenSFX.Parent = character.HumanoidRootPart
		SoundChosenSFX.SoundId = soundchosen
		if soundchosen == id1 then
			SoundChosenSFX.TimePosition = 0.2
		elseif soundchosen == id2 then
			SoundChosenSFX.TimePosition = 0.1
		elseif soundchosen == id3 then
			SoundChosenSFX.TimePosition = 0.2
		end
		SoundChosenSFX:Play()

		HitSwingSFX.Parent = character.HumanoidRootPart
		HitSwingSFX:Play()
		
		Debris:AddItem(SoundChosenSFX, 1)
		Debris:AddItem(HitSwingSFX, 1)
	end
	
	local function Hitbox(percent, knockback, velocity, boolean)
		
		local region = Region3.new(V1 - Vector3.new(2,2,2), V1 + Vector3.new(2,2,2))
		local rtable = workspace:FindPartsInRegion3(region, nil, 20)
		
		for i,v in pairs(rtable) do
			
			if v.Parent:FindFirstChild("Humanoid") and v.Parent:FindFirstChild("Debounce") == nil and v.Parent ~= character then
				
				local debounce = Instance.new("BoolValue", v.Parent)
				debounce.Name = "Debounce"
				local stun = Instance.new("BoolValue", v.Parent)
				stun.Name = "Stun"
				
				game.Debris:AddItem(stun, 0.8)
				game.Debris:AddItem(debounce, 0.2)
				
				local enemypercent = v.Parent:FindFirstChild("Percentage")
				
				local BV = Instance.new("BodyVelocity",v.Parent.HumanoidRootPart)
				
				if v.Parent:FindFirstChild("Substitution") then
					
					local Sound = Instance.new("Sound")
					Sound.SoundId = "rbxassetid://147722098"
					local Log = Assets:FindFirstChild("Log"):Clone()
					Log.CFrame = v.Parent:FindFirstChild("HumanoidRootPart").CFrame
					Sound.Parent = Log
					local HRP = v.Parent:FindFirstChild("HumanoidRootPart")
					HRP.CFrame = player.Character:FindFirstChild("HumanoidRootPart").CFrame * CFrame.new(0,0,5)
					Log.Anchored = false
					Log.CanCollide = true
					Log.Parent = game.Workspace
					Sound:Play()
					Debris:AddItem(Log,1)
				elseif v.Parent:FindFirstChild("Blocking") then
				
					enemypercent.Value = enemypercent.Value + math.floor(percent/3 * 100)/100
					
					BV.MaxForce = Vector3.new(25000,25000,25000)
					BV.Velocity = character.HumanoidRootPart.CFrame.LookVector * (knockback/2)

					local blockvalue = v.Parent:FindFirstChild("Blocking")
					blockvalue.Value = blockvalue.Value - 4

					local effect = v.Parent.Torso:WaitForChild("BlockEffect")
					effect.Color = Color3.fromRGB(255,255,255)

					local info = TweenInfo.new(1, Enum.EasingStyle.Quint, Enum.EasingDirection.Out)
					local goals = {Color = Color3.fromRGB(255,0,0)}

					local tween = TS:Create(effect, info, goals)
					tween:Play()

					BlockSFX.Parent = v.Parent.HumanoidRootPart
					BlockSFX:Play()

					combatmodule.DamageVisual(v.Parent, math.floor(percent/3 * 100)/100)
				elseif v.Parent:FindFirstChild("PerfectBlock") then
					
					enemypercent.Value = enemypercent.Value

					local perfectstun = Instance.new("BoolValue", character)
					perfectstun.Name = "Stun"
					game.Debris:AddItem(perfectstun, 2)

					PerfectBlockSFX.Parent = v.Parent.HumanoidRootPart
					PerfectBlockSFX:Play()
				else
					
					enemypercent.Value += percent
					
					HitSFX.Parent = character.HumanoidRootPart
					HitSFX:Play()
					Debris:AddItem(HitSFX, 1)
					
					if not v.Parent:FindFirstChild("Blocking") or not v.Parent:FindFirstChild("PerfectBlock") then

						cloudfx.Parent = v.Parent.Torso
						cloudfx.Enabled = boolean
					end
					
					BV.MaxForce = Vector3.new(25000,25000,25000)
					
					if enemypercent.Value < 25 then
						BV.Velocity = character.HumanoidRootPart.CFrame.LookVector * knockback + Vector3.new(0,velocity,0)
					elseif enemypercent.Value < 50 then
						BV.Velocity = character.HumanoidRootPart.CFrame.LookVector * (knockback * 1.5) + Vector3.new(0,velocity,0)
					elseif enemypercent.Value < 75 then
						BV.Velocity = character.HumanoidRootPart.CFrame.LookVector * (knockback * 2) + Vector3.new(0,(velocity * 2),0)
					elseif enemypercent.Value < 100 then
						BV.Velocity = character.HumanoidRootPart.CFrame.LookVector * (knockback * 2.5) + Vector3.new(0,(velocity * 3),0)
					elseif enemypercent.Value < 125 then
						BV.Velocity = character.HumanoidRootPart.CFrame.LookVector * (knockback * 3) + Vector3.new(0,(velocity * 4),0)
					elseif enemypercent.Value < 150 then
						BV.Velocity = character.HumanoidRootPart.CFrame.LookVector * (knockback * 3.5) + Vector3.new(0,(velocity * 5),0)
					elseif enemypercent.Value < 175 then
						BV.Velocity = character.HumanoidRootPart.CFrame.LookVector * (knockback * 4) + Vector3.new(0,(velocity * 6),0)
					end
					
					combatmodule.ComboUI(combonumber, combotext, 1)
					combatmodule.HitEffect(v.Parent, ParticleFolder.HeavyEffect)
					combatmodule.DamageVisual(v.Parent, percent)
				
					coroutine.wrap(function()
						wait(0.7)
						cloudfx.Enabled = false

						game.Debris:AddItem(cloudfx, 1.3)
					end)()
					
					local hiteffect = {

						"rbxassetid://6198422351",
						"rbxassetid://6198425884",
						"rbxassetid://6198427665"

					}

					local value = math.random(1, #hiteffect)
					local chosen = hiteffect[value]

					local anim = CombatAnimFolder.HitEffectChosen
					anim.AnimationId = chosen
					local track = v.Parent.Humanoid:LoadAnimation(anim)
					track:Play()
					
					LastHitSFX.Parent = character.HumanoidRootPart
					LastHitSFX.Playing = boolean
					Debris:AddItem(LastHitSFX, 1)
				end
				
				game.Debris:AddItem(BV, 0.3)
			end
		end
	end
	
	if enable.Value == false then return end
	if action == "Combat" and character:FindFirstChild("Stun") == nil then
		
		enable.Value = false
		
		local selfstun = Instance.new("BoolValue", character)
		selfstun.Name = "SelfStun"
		Debris:AddItem(selfstun, 0.6)
		
		if V2 == "Left" then
			combo.Value = combo.Value.."L"
			coroutine.wrap(function()
				wait(0.25)
				combonumber.Text = combo.Value
			end)()	

		elseif V2 == "Right" then
			combo.Value = combo.Value.."R"
			coroutine.wrap(function()
				wait(0.25)
				combonumber.Text = combo.Value
			end)()
		end
		
		if combo.Value == "L" then
			combatmodule.AttackAnimation(character, CombatAnimFolder.Punch1)
			Hitbox(damagetable["Punch"], 0, 0)
			Sound()
		elseif combo.Value == "LL" then
			combatmodule.AttackAnimation(character, CombatAnimFolder.Punch2)
			Hitbox(damagetable["Punch"], 0, 0)
			Sound()
		elseif combo.Value == "LLL" then
			combatmodule.AttackAnimation(character, CombatAnimFolder.Punch3)
			Hitbox(damagetable["Punch"], 50, 10, true)
			Sound()
		elseif combo.Value == "R" then
			if character:FindFirstChild("Crouch") then
				local anim = Instance.new("Animation")
				anim.AnimationId = "rbxassetid://6676763764"
				local track = character.Humanoid:LoadAnimation(anim)
				track:Play()
				wait(0.25)
				Hitbox(damagetable["Sweep"], 0, 0)
				Sound()
			else
				combatmodule.AttackAnimation(character, CombatAnimFolder.Kick1)
				Hitbox(damagetable["Kick"], 0, 0)
				Sound()
			end
		elseif combo.Value == "RR" then
			if character:FindFirstChild("Crouch") then
				local anim = Instance.new("Animation")
				anim.AnimationId = "rbxassetid://6676765913"
				local track = character.Humanoid:LoadAnimation(anim)
				track:Play()
				wait(0.25)
				Hitbox(damagetable["Sweep"], 55, 20)
				Sound()
			else
				combatmodule.AttackAnimation(character, CombatAnimFolder.Kick2)
				Hitbox(damagetable["Kick"], 0, 0)
				Sound()
			end
		elseif combo.Value == "RRR" then
			combatmodule.AttackAnimation(character, CombatAnimFolder.Kick3)
			Hitbox(damagetable["Kick"], 50, 10, true)
			Sound()
		elseif combo.Value == "LR" then
			combatmodule.AttackAnimation(character, CombatAnimFolder.Kick1)
			Hitbox(damagetable["Kick"], 0, 0)
			Sound()
		elseif combo.Value == "LLR" then
			combatmodule.AttackAnimation(character, CombatAnimFolder.Kick3)
			Hitbox(damagetable["Kick"], 50, 10, true)
			Sound()
		elseif combo.Value == "LRR" then
			combatmodule.AttackAnimation(character, CombatAnimFolder.Kick3)
			Hitbox(damagetable["Kick"], 50, 10, true)
			Sound()
		elseif combo.Value == "RL" then
			combatmodule.AttackAnimation(character, CombatAnimFolder.Punch2)
			Hitbox(damagetable["Punch"], 0, 0)
			Sound()
		elseif combo.Value == "RLL" then
			combatmodule.AttackAnimation(character, CombatAnimFolder.Punch3)
			Hitbox(damagetable["Punch"], 50, 10, true)
			Sound()
		elseif combo.Value == "RRL" then
			combatmodule.AttackAnimation(character, CombatAnimFolder.Punch3)
			Hitbox(damagetable["Punch"], 50, 10, true)
			Sound()
		elseif combo.Value == "LRL" then
			combatmodule.AttackAnimation(character, CombatAnimFolder.Punch3)
			Hitbox(damagetable["Punch"], 50, 10, true)
			Sound()
		elseif combo.Value == "RLR" then
			combatmodule.AttackAnimation(character, CombatAnimFolder.Kick3)
			Hitbox(damagetable["Kick"], 50, 10, true)
			Sound()
		else
			local cooldown = Instance.new("BoolValue", character)
			cooldown.Name = "Cooldown"
			game.Debris:AddItem(cooldown, 1)

			combo.Value = ""
		end
		
		coroutine.wrap(function()
			local oldcombo = combo.Value

			wait(0.8)
			if combo.Value == oldcombo then
				combo.Value = ""
				combonumber.Text = ""
				combotext.Transparency = 1
				combonumber.Transparency = 1
			end
		end)()
		
		wait(0.2)
		enable.Value = true
	end
end

Have you tried simple debugging with prints or breakpoints?

Yes, I’ve tried multiple prints in different areas, although this is rewritten code so I’ve already gotten rid of them all. I believe the hitbox isn’t detecting the player for some odd reason. Everything else such as sounds and animations play and work when I click, just not the hitbox.