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:
Make the hitboxes seem fair and accurate for both sides
Fix any manipulable values (hitbox position, cooldown, etc)
Fix any latency issues that would be present with fully server-sided hitboxes
Is the “part” itself still ultimately created by the server?
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.
Probably should’ve attached my script, I forgot to do that
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.
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.
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.