Help with Server-Client Hitbox System

I am really stumped.
So I’m trying to create a reliable hitbox system utilising a server-client system for an asymmetrical game. Today I recreated my hitbox script (which was server-sided before) to generate (workspace:GetPartBoundsInBox) boxes and detect hits on the client, and I still have yet to implement the server checks and damage to validate the hit itself. But I feel like I hit a wall. When I tested the game with a friend (who has 200ms ping mind you), it just seemed like the hitboxes were reaching farther than they should because he is closer to me than the server sees.

Now this makes the hitboxes seem more sided towards the killers rather than the survivors since they have the more accurate hitboxes. To add on, I heard Jujutsu Shenanigan’s hitboxes are very effective as they use this server-client system too. I want to get to that level of effectiveness.

I just need help on how to:

  1. Make the hitboxes seem fair and accurate for both sides
  2. Fix any manipulable values (hitbox position, cooldown, etc)
  3. Fix any latency issues that would be present with fully server-sided hitboxes

Thanks for reading! :​D

1 Like

A bit confused on what exactly you did here, so:

  1. Is the “part” itself still ultimately created by the server?
  2. Who’s calculating the actual hit detection? Is it the client (upon the part being detected)?

Also, from what I know, you may have misunderstood the way JJS hitboxes work? Now, I’m not entirely sure as I had never played the game, but I believe they manually replicate each character’s CFrame from client to server (as Roblox’s physics replication is slow & doesn’t work well for such scenarios), and then perform hit detection on the server directly.

1 Like

Probably should’ve attached my script, I forgot to do that :sob:

local function m1()
	if not oncd.Value then
		if oncd.Value or not plr.Character:FindFirstChild("Humanoid") then return end
		oncd.Value = true

		local humsHit = {}
		local hitboxStopped = false
		
		--visuals and sfx
		local anim = plr.Character.Humanoid.Animator:LoadAnimation(char.Animations.M1)
		anim.Priority = Enum.AnimationPriority.Action4
		anim.Looped = false
		anim:Play()
		abilitySound:FireServer(plr.Character.HumanoidRootPart.AbilitySounds.M1)

		task.spawn(function()
			cooldown(cd, m1button)
			task.wait(statsF.Abilities.M1.HitboxLinger.Value)
			hitboxStopped = true
		end)
		task.spawn(function()
			task.wait(statsF.Abilities.M1.Cooldown.Value)
			oncd.Value = false --yes i know cooldowns shouldn't be handled on the client but this is simply to test my system first
		end)

		while hitboxStopped == false do
			local pos = direct(plr.Character.Humanoid, plr.Character.HumanoidRootPart, statsF)
			local size = Vector3.new(statsF.Abilities.M1.HitboxX.Value, statsF.Abilities.M1.HitboxY.Value, statsF.Abilities.M1.HitboxZ.Value)
			local createHitbox = workspace:GetPartBoundsInBox(pos, size) --ACTUAL HITBOX DETECTION
			hitboxVis:FireServer(pos, size, false) --VISUALISES HITBOXES, NOT THE HITBOX DETECTION ITSELF
			for i,v in pairs(createHitbox) do
				if v.Parent:FindFirstChild("Humanoid") and not humsHit[v.Parent.Name] and v.Parent:FindFirstChild("Humanoid").Health > 0 and v.Parent ~= char then
					humsHit[v.Parent.Name] = true
					hitboxVis:FireServer(pos, size, true)
					abilitySound:FireServer(plr.Character.HumanoidRootPart.AbilitySounds.M1, "OnHit")
				end
			end
			task.wait(0.035)
		end
	end
end

Anyway to answer your questions, the hitbox part is created by the server as a visual, and the detection runs on the client. Now I was going to just add a second layer where the server checks if the hit was valid, but now I realise having detection on the server might be a better idea.

And from what I’ve heard from a friend, JJS uses client-spawned hitboxes while detecting hits on the server. Really I’m just trying to make a reliable hitbox system. I don’t need to completely replicate JJS’s hitboxes, I just want the hitboxes to feel like they do.

hit detection and anything involving the functionality of hitboxes should always be server sided or else you get biggg issues especially in asymm

As for this issue, you could look toward other methods of replication that could decrease the amount of time it takes to send data. Chrono is a pretty good option for this:

Yeah I’ll move the detection system over to the server instead.
Also, what I was referring to with that specific “hitbox reach” issue, I’m pretty sure it is caused if, for example, someone had 200 ping and were right behind someone on their screen, since the hitboxes are spawned on the client, they use the client character’s position to position the hitbox in front of the character. This makes the hitbox reach farther than it seems it would. But chrono seems like a useful system I could use regardless.

Edit: I’d figure a good system is to let the client send a hitbox CFrame, then the server validates that the hitbox seems possible, spawn it, then do all detecting and damaging.

You’ll have to be careful with that, since someone with high ping could just have all of their hits rejected by the server

Ah, so what system would you suggest to make smoother-feeling hitboxes than exclusively server-sided ones?

1 Like

server-sided hitboxes are the only way you should go about it, but some people use ping detection to determine where the hitbox will be with some prediction based math.

1 Like