In my game, I want projectiles to replicate smoothly across all clients. What I’m doing now is whenever the server wants to send a projectile, I tell the client where it starts, where it ends etc, and then the client creates that projectile based on that.
Is this a good system? How can I improve it?
This is a good system and is frequently used since it is an efficient way of replicating projectiles. You could also try to reduce replication lag by tracking each player’s latency and then taking that into consideration when locally simulating the projectile. (i.e. when you get a message from the server you know it was sent sometime in the past so you can put the projectile further ahead on its trajectory depending on the latency)
Good to know that other people use it. I kind of felt like something was missing, so yeah I will accommodate for latency.
I’m working on a projectile replicator right now, and from my testing it doesn’t seem that I need to give anything more than the start conditions.
Certain events are communicated from client to server as they happen, but as long as ping is consistent they should happen at the exact same time on the projectile’s timeline.
Of course, what the projectile hits depends on when the projectile was created, and I give client right of way in determining what the projectile hits.
The projectile replicator is for client to server, but it would be easy for me to reverse it.
Here’s how my rocket launcher behaves when using my entity replicator:
- Client rocket fired
- Server rocket fired
- Server rocket deleted clientside
- Client rocket hits positionA and creates an explosion at positionA, and creates tableA of the CFrames of things hit by the explosion
- Server rocket is at positionB(should be close to positionA) but creates an explosion at position A, and for everything in tableA has the explosion deal damage as if it was positioned at the CFrame in the table
Sure, there’s a lot of security holes, but they don’t matter for server-to-client replication.
Just swap “client” and “server” around and it should work perfectly.
Fire the projectile in a LocalScript and then communicate the root position of the projectile and player to the server so that when you fire it back to all clients you may exempt the initial player. Client receives that data and then fires it on their own
Always satisfy the client. The server is your remote.
That could be problematic. You don’t want the client to be able to say the projectile spawned in somebody else’s face if instead it should have spawned from a cannon.
That looks like it would end up being an infinite loop if there are multiple players. Also I think it is better to fire each client individually excluding the initial player to reduce network usage rather than fire all and have the client exclude itself.
Assuming there are restrictions on where the projectile should spawn such as from the barrel of a gun, you don’t want the client to decide where where the gun barrel is. The client could be out of sync with the server or be dishonest.
What I’m doing is giving it a start object rather than position(unless it matters where it starts exactly), so then it can infer the position from that and it looks much smoother. End point stays the same, and I use TweenService to tween the CFrame of the projectile between the 2 points.
The client fires the server, which then fires all clients but on the client which fired the projectile, it knows to ignore it because it has the “Origin” in the arguments, which is the player so it knows to ignore it if it comes from their own player.
Also, if the projectile hits something on it’s route, the server will tell the client and stop it early so it stays relatively accurate. Makes it easier to work with.