I’m currently working on a game that features many different abilities. While making the first one, which has you clap and shoot a beam of blood from in-between your hands, on occasion and mainly when jumping, the blood doesn’t always appear from the middle of your hand. I position the beam by offsetting it from the HRP which it could be the cause, but I don’t know.
I have a high suspicion that the cause is due to the client and server not always being synced, the position of the character can be different on the client than the server, etc. So the solution to this would be to do the visuals on the client so that the visuals are accurate for everyone. The issue with this is that I would need to do hit detection on the client that used the ability so that it’s responsive and the ability hits what the player sees it hit.
So something like that would look like:
Player uses ability, fire to the server and do validation, if valid, continue
Fire to all clients, do ability visuals and do hit detection on the client that used the ability
If the ability hits something, fire to the server and do validation, if valid, damage
But I’m not really sure what validation checks I can do other than magnitude checks which isn’t always going to be useful. What other checks could I do?
Another solution is that I just do everything on the server - the abilities aren’t anything special, mostly just basic ranged and melee attacks. But like I mentioned at the start, I might have issues with abilities feeling responsive if the server and client aren’t synced up.
To end this post, what is the best way to handle abilities so that they’re responsive and secure?
For abilities you should really have 2 client scripts > 1 would handle the key press and detection > the other would handle the effects. Now you mentioned fire to all clients > and the do ability visuals after. You shouldn’t do this and a better solution would be to have a folder in the workspace > this is where you can insert your skill parts > then in your client script you can have it wait for things to enter into this folder. As parts enter you can simply check the name of the part then start set effect > you could even push this to a module for better readability. Your server script should handle the inserting,removing, and damage parts of the skill. Now how I set this up is I usually will go client key press > server insert skill > fireclient and start detection > if something is found send to server > if nothing is found > delete part server side and send fireclient to stop detection.
Now talking about detection specifically > I always do aoe skills with magnitude, because it just makes more sense since magnitude is more of this ring, opposed to my second option where its raycasting because I wont need the extra coverage. On a side note you could potentially do everything with magnitude thats perfectly fine and all, but if you have very specific conditions that happen with a skill you should use raycasting. I do also use region3, but region3 is more for like my teleportation skills. Region3 is really nice for creating those door like effect skills.
When starting detection you’ll obviously loop it > Id suggest a while loop with a heartbeat wait time > if you don’t understand its like this.
local rs = game:GetService('RunService')
while true do
rs.Heartbeat:Wait()
end
^ this will make it run just as it would if you were doing a heartbeat loop thing, the only thing about this is its easier to set up. I can’t speak on the performance aspect, but this runs perfectly fine and honestly I personally believe it runs better. I don’t know if its true, but I’m biased.
Uh there’s a lot more to cover, but I can’t think of anything hopefully this helps. If not then sorry I wasn’t any help. Best of luck either way.
Oh Ps > never create skills client side, theres so many issues. It’s really not worth it. it might be nice on performance, but you’ll have so many errors trying to perfect that skill that in the long run its just not worth the effort. The performance isn’t even that much better than doing it the way I’m suggesting above anyways.