Hit Detection On Different Clients

Should I make the client do hit effects or should it depend on the original fire-er?

For example, when one client fires their gun it fires a remote event to the server which fires a remote event to all the other clients to create their own version of the bullet (given the speed, position, etc. etc.).

This creates an “out-of-sync” effect due to latency. That means that the original client who fired can see their bullet hit things and make blood effects, etc, etc but that doesn’t necessarily mean the other clients see the same thing because the effects are dependent on their version of the bullet instead.

How would I go about fixing this? I know I can use extra firing on remote events to ensure that everyone sees the same effect but I don’t want to create extra lag on an issue that seems rather petty.

Keep track of each client’s ping and only send the bullet if they have a good enough one to display the bullet + fx in time. Also make sure to account for the distance of the bullet. You really shouldn’t be telling anyone to draw a bullet that’s only gonna travel ~10 studs.

Edit: Sorry, I’m tired and I entirely missed your point. I’ve never field tested this myself, but it should be leniently server checked. The client should fire and raycast the bullet, check if it hit a player, then send the Ray and the player to the server. The server should then check to see if the Ray contact point is within a reasonable range of the target player, and deal appropriate damage.


In my rewrite of Rocket Arena, what I did to solve this was:

  • Client makes request to fire a Rocket
  • Client immediately renders LocalRocket Part then send request to Server
  • Server determines if request is possible (If rejected, inform Client and Client deletes LocalRocket)
  • If approved, Server will create an invisible ServerRocket Part which replicates to all Clients and gives it a unique name as an Id, returning it to the Clients.
  • The firing Client will wait for the Server to return the uniqueId for the ServerRocket, wait for it to replicate into workspace, then position the LocalRocket to the ServerRocket, make Server part visible and LocalRocket invisible, then destroy LocalRocket.
  • The other Clients will wait for the Server to give them a uniqueId, wait for the ServerRocket to replicate to Workspace on itself, attach listeners to handle effects locally, then make the ServerPart visible on itself.

This has helped keep syncing issues to the minimal cause it doesn’t show to other clients until it’s verified, then has the Server take over the movement of the part once it’s ready.


When you mean clients you mean all clients, even the fire-er, correct?

So this means even the person who fires the rocket has a little bit of a delay since it has to check with the server first, correct? All for the benefit of having everyone in sync?

And the rocket is moved by the server too?

Oh, my bad of course it is; didnt get the last line sorry lol.

I’m not quite understanding some of the terminology you’re using here. Is LocalPart and LocalRocket the same thing?

And if the spawns the LocalRocket immediately for the fire-er, but gets rejected by the server, wouldn’t the client see the Rocket for a split second before it gets deleted?

Apologies on the late response.

Yes, I mean all clients, including the firer. You will need to replicate an ID to all clients so they can wait for the Server part and replace the Local part with the Server one.

No, that’s why you render the Local part. If the Client is “abiding” to how it’s supposed to run, it’ll give the appearance of no sync issues. Other Clients will also be in sync as they won’t receive anything until the Server verifies, creates the Server part, and informs the Clients of the Server part via a unique name.

Yes, the Server handles the movement of the actual Part. This will ensure you can trust your hit detection logic as it’s ran all on the Server where you are in “true control”. You can then render effects by using a LocalScript to listen on the Server part for that Client.

Yes, LocalPart is a typo and is supposed to be LocalRocket, my mistake.

Yes, if rejected the client will see it if a split second. This is why you also do validation checks on the client on top of the server so “abiding” players will never see that split second. If they do see it, they’re probably cheating since you’ve implemented checks on the client too.

1 Like

The rocket is roblox’s physics though right?

If so, how would I make it in sync with a custom physics projectile system using raycast?

Would the detection and “movement calculation” also be done on the server? But then how would this be replicated to the client?