Pretty much what the title says. I am using RaycastHitbox module for my melee system, and I play animations on the client side of player. If the hit registers, it sends a remote event to a server with a humanoid that was hit.
Below is logic to check if the hit was truly valid, or if it should be ignored. I don’t have experience with melee weapon systems, so was wondering if what I have is sufficient.
local RepStorage = game:GetService("ReplicatedStorage")
local onHitEvent = RepStorage:WaitForChild("onHitEvent")
-- Table to track per-player cooldowns
local playerCooldowns = {}
local HIT_DISTANCE_THRESHOLD = 8
local ATTACK_COOLDOWN_TIME = 0.5
onHitEvent.OnServerEvent:Connect(function(player, hitHum)
-- Step 1: Basic checks
if not player or not hitHum then return end
local char = player.Character
if not char then return end
local playerHum = char:FindFirstChildOfClass("Humanoid")
if not playerHum or playerHum.Health <= 0 then return end
-- Step 2: Check that the tool is actually equipped in the player’s character
local tool = char:FindFirstChildOfClass("Tool")
if not tool then return end
-- Tool must have a Hitbox part or a Handle part
local toolPart = tool:FindFirstChild("Hitbox") or tool:FindFirstChild("Handle")
if not toolPart then return end
-- Step 3: Ensure the hit target’s Humanoid is not the attacker’s
if hitHum == playerHum then return end
-- Step 4: Check distance between tool’s part and the hit player’s HumanoidRootPart
local hrp = hitHum.Parent:FindFirstChild("HumanoidRootPart")
if not hrp then return end
local distance = (toolPart.Position - hrp.Position).Magnitude
print(distance)
if distance > HIT_DISTANCE_THRESHOLD then
-- The target is too far away; possible exploit or lag
return
end
-- Step 5: Check for attack cooldown
local now = tick()
if playerCooldowns[player] and (now - playerCooldowns[player]) < ATTACK_COOLDOWN_TIME then
-- Still in cooldown
return
end
-- Update last attack time
playerCooldowns[player] = now
-- If all checks pass, deal damage
print("Verified Hit: ", hitHum)
hitHum:TakeDamage(10)
end)```
It looks fine. Though if you’re using a raycast hitbox system, you may want to use that system for this check or at least a simple version of it. From the looks of things, it appears an exploiter could hit someone else through walls, and that raycast module might not be able to because it’s based on raycasts.
Anything done on the server is secured to begin with.
Remove remote event, and make animations play on server.
Removing the remote event will make sure an exploiter can’t access it and potentially use it to also access anything with .OnServerEvent & that remote event.
Replace raycast hitbox system because an exploiter could just… create a ray that goes through a wall, given they know about the system.
How is a client supposed to communicate a signal to hit without a remote event?
Also, I personally think playing animations on the client is better, because it begins instantly on the client’s screen which makes things feel much more responsive.
You can also just add it to the server script instead.
Well, Raycast Hitbox doesn’t have any verification built in as far as I know. You can build it either on Client, or on Server - if built on server, I suspect it would lead to decreased user experience due to it not being as responsive. Also I don’t think it works as well, it would require a very complex system to be introduced and probably make the game lag. Honestly, client sided logic seems like the only feasible solution here.
But if built purely on the client, it is very vulnerable to exploits, and even ping making hits register that shouldn’t have.
Therefore, it seems like the only solution is client sided animation, and server verifying all of that.
I am a bit confused about what you wrote about walls. It’s impossible to hit through walls with this module because a weapon will touch the wall first, and therefore stop the hitbox before it reaches the humanoid. There is an option to only listen for humanoid hits, but I won’t go with it.
And lastly, I don’t know how big of an issue is hitting through walls. It might be worth it to accept the fact that player can hit through walls, that logic is kind of expected by players on Roblox, and I doubt it’s that big of an issue.
Thank you for your reply, I appreciate your time looking into my code
Like I wrote in previous reply, playing animations on servers most likely will lead to game feeling very unresponsive, and clunky. In a fast paced environment where you time combos, it would destroy the feel of the game, and make it annoying. I would also be scared to do so much logic with raycasts on my server, seems like delegating it to clients is worth it to split the load. Thank you for the reply, your idea is the first one I tried, but I quickly stopped when I began facing issues with getting it to work, but that’s probably a skill issue more than anything
An exploiter could send a remote event for a nearby humanoid through a wall. Any client sided raycast checks would be bypassed and then the hit would count as valid on the server. If repeating the raycast hitbox system on the server is impossible, you could add a single raycast check for walls between both humanoids. You don’t have to of course, if you’re fine with hitting through walls
My bad. I have very little experience in melee weapons, but the animation playing on client seems to be just preference based on what the animation is used for.
And for the remoteevent, yeah it seems important now that you bring up it’s supposed to signal a hit (of which I had no idea would be needed since it’s been years since I ever made a melee weapon, and that for the most part was just a retextured linked sword with slightly different values.)
And yeah, raycast can definitely be server-sided, and if he ever tries to make it serversided, he definitely should.
My new suggestions are redundant and not worth sharing, since those solutions are similar to yours.