Currently, I have guns that raycast on the client. I would like to have raycasts on the server to prevent people from bringing others to themselves clientsidedly and killing them. This method did not work out for me however as 7/10 times the raycast misses and the user does not get damaged. Can anyone help me out with this?
Send the origin of the ray, the hit position and the part that got hit. Check that the origin isn’t too far from the player and that the part in question isn’t too far from the hit.
An exploiter can control what to send to the server and they may choose to send values which would comply being “Not too far” but that would hardly change anything.
Latency also comes in play, if you have a very high ping, the server would get the values after a prolonged delay and it could result in inaccuracy and false positives.
You would either have to:
Let the client handle the visuals and detection and let the server verify.
Pros: Smoother gameplay and highly responsive
Cons: Being more vulnerable to exploits
Let the server handle the detections and visuals
Pros: Less vulnerable to exploits
Cons: Latency decides everything and sadly be the factor on who wins, players with high ping will suffer to lag and unresponsiveness
For this reason, hit detection and visuals should always be done on client and the server should only act as a verifier of whether it is valid or not. There however are some other reliable ways to cope with this.
You can also look for other reliable methods such as FastCast which is an open source module for handling projectiles and hit detection
As you said in your first point, it hardly changes anything. The worst they could do is shoot from behind a corner, but that can be countered by casting a 2nd ray and checking for static objects on the server.
The lag part actually works in your favor as it ends acting as a cheap anti-lag-switch.
FastCast isn’t required here as its main purpose is to simplify bullet drop, which this post doesn’t have.
Another advantage I would like to add for hit detection client side is that the server is essentially free of load and only has to deal with reverse constructing rays to verify the shots and damaging. If every player sends a remote event to the server for every bullet no matter if it hit or not, it will severely affect the server performance and it will underperform
Events coming in too late should be dropped anyways. A 1 second threshold is a reasonable value. This means that you lag argument is invalid. Lag switches forcefully prolong your ping and having the system detect it as a too big of a distance works in your favor.
I know how FastCast works and had a very similar system set up in multiple abandoned projects 5 years ago. It is nice, but it only solves the problem of hit detection and validation with curved trajectories, which is not the case here.
What is being affected here is user experience, especially when you are moving all the time in a Fast Paced FPS. Rays being casted 1 or 2 seconds later is a major flaw in this case. Theres a huge difference experience wise if you shoot someone and they dont take damage even with a 100 ms ping if you are running all over the map and shooting someone and getting damaged later after verification (since the measurements and detection has already been done)
--get the distance between the hitpos and the part, then subtract its diagonal to avoid false positives with large parts
local (dist = hitpos - part.Position).Magnitude - part.Size.Magnitude/2
--set up the threshold
local thres = part.Velocity.Magnitude*2+2
if dist>thres then
--invalidate shot
end
it adds up to the latency, even if you dont do anything, a call is being made and the server has to actually get the ping making the round call before it can actually continue with the damage. The load is not what im talking about
Not if you properly schedule your code. Invokes yield your current thread, but not others, meaning you can just run a thread that loops invokes the entire time and yields while waiting for response. That’s actually how I handle input from my server sided characters I’m working on.
[SERVER]
local indexPlayerExists = {}
--events fire on a separate thread
servicePlayers.PlayerAdded:Connect(function(plyr)
indexPlayerExists[plyr] = true
while indexPlayerExists[plyr] do
local inputdata = remfuncInput:InvokeClient(plyr)
--handle input
end
end)
[CLIENT]
remfuncInput.OnClientInvoke = function()
local olddata = inputdata
inputdata = {}
return olddata
end