I’m trying to make a raycast based system to simulate projectiles and its working well so far.
The projectiles are all synchronised since I’m using a quadratic equation with respect to time. (ie. At any time t, the same projectiles across all clients would be at the same position)
If you’re curious what I did this, feel free to ask.
However, eventually I will get to a point where it comes to replicate hit detection for other clients.
Ideally, the best method should have:
- Low latency for the firer and other clients (delays in hit detection are not/barely noticeable),
- Avoid sending data unnecessarily (avoid sending data back and fourth between the same clients),
Based on my own experimentation and suggestions from fellow devs, there are a few methods of doing this that I’m familiar with;
1. Purely from the firer’s client
Any hits that are registered by the firer are sent to the server and broadcasted to the rest of the connected clients (with little to no interpretation by the server).
Hits by the client’s copy of the projectile are not registered on all clients except the firer, and instead relies on the broadcast of the firer’s hit.
Suffers from relatively high latency for other clients since the message has to be sent from the firer —> server —> other clients.
Lowest latency for the client, since it is handles locally and doesn’t suffer the latency associated with client-server connections.
2. Purely from the server
The client sends the details of the projectile for the server to carry out its own simulation and hit detection, and the server transmits the hits to all connected clients.
Hits are not registered on all clients and instead rely on the server for any hit info.
This would cut the latency (compared to method 1) by about half since the message only has to be sent from the server —> all clients (as compared to client —> server —> other clients)
3. From all clients
Since the projectile is already being simulated on all clients, all clients can do their own hit detection.
Completely unsynchronised since all the clients are doing their own thing.
Almost no latency since theres no dependency on client-server connections.
Important note for method 3:
When implementing this, I kept a dictionary of the projectiles that were fired, indexed to a unique key that was generated by string.pack().
If a client detected a hit, it would not act on it, and instead just transmit the hit and the projectile’s to the server.
If the projectile’s index existed then it would be removed from the dictionary and the hit information would then be transmitted to all clients.
Subsequently, if any other client tried to register its own hit, the projectile wouldn’t exist in the dictionary and the hit would be disregarded.
This works similar to method 1.
However, this implementation has a lot more redundant data being sent.