Which approach is the best for a Multiplayer game?

Hey everyone,

I was wondering which approach is the best in Multiplayer games. Here’s the question and the solutions I am thinking of.

How to spawn a projectile in Multiplayer from an auto-fire rifle?

  • When the player presses the button, I setup a timer for auto-fire on the client. When a function is called from the timer, I create a fake projectile on the client and send the fire event to the server, then the server spawns the real projectile. In this case, if a weapon has rate of fire of 600 RPM; the weapon spawns a projectile in 0.1 seconds which means the RPC function will be called in every 0.1 seconds. It looks like it may cause a bottleneck in the network in my opinion. (There can be more than 1 player.)

  • When the player presses the button, I setup a timer on the client and call an RPC function to setup another timer on the server. When the functions are called from the timers, I create a fake projectile on the client and a real projectile on the server. In this case, only one calling RPC function will be enough; however, stopping fire might be a problem. When the player releases the button, I need to call an RPC function to tell the server that the player has stopped shooting. If that package arrives lately due to a latency, the player will continue to shoot on the server.

Which one is the best? If there’s any solutions better than these, I would like to hear that.

You don’t want to flood your upstream from the client to server that way as your downstream is already not light. 10 rounds per second means 10 actor creations per second with the replication overhead/etc. Your second approach is much better but I’d go even further. I’d make the server and the owning client follow the exact same firing path. For example:

Owning client receives a request to fire (client-side). Calls ServerBeginFire() then immediately calls BeginFire(). When ServerBeginFire() executes on the server, the server calls BeginFire(). Both client and server execute the same path (using role checks when needed) to spawn projectiles.

When the owning client receives a request to stop firing (client-side) it calls ServerStopFire() then immediately calls StopFire(). When ServerStopFire() executes on the server it calls StopFire(). Just like above it follows the same path.

Yes, you can have an errant shot fired on the server before it receives it’s ServerStopFire() but in practice this won’t happen often (though it’s far more likely with a high rate of fire weapon). There are a couple of ways to mitigate against this. Which option is best for you depends on your game, the accuracy need, implementation, etc.

Thank you for the reply. I’ll try the second approach and see if there will be an extra shooting by using fake latency.

It’s not really extra shots per say, it’s really just latency in releasing the trigger :slight_smile:

Exactly. Unless your ping increased between the button press and button release, there can’t be a rogue projectile on the client-side.

I tried my second approach and it works same as the first approach (and less number of calling RPC funstions). Thank you for the replies.