RPC, RaiseEvent and OnPhotonSerialize in relation to SendRate and SerializationRate

Options
TL;DR: I want to create a system that can handle any type of weapon, and make it so that every bullet VFX and impact, as well as placements of mounted or throwable weapons always is the same on all clients, without exhausting the 500msg/s limit or the bandwidth limit regardless of the amount of players in the game. If I want to have 20 or 30 or even 50 players in the game, it should scale correctly and not cause any issues with the Photon Cloud.

An OnPremise Server solution is not applicable here.



The Story:

I want to have a multitude of weapons in a game, like guns, rocket launchers, grenades etc. But I quickly found out that this was not an easy task at all.

The problem comes from the way that Photon handles RPC and RaiseEvents.

When I have a weapon with a Rate of Fire of lets say 10 shots per second, and the player holds the firing button, I would assume that the best way to go about this would be to send an RPC for every shot that fires from the gun with the position and rotation of the firing point of the weapon.
However I quickly realized that this was a very bad idea, especially if I have more than two players in the game. The msg/s rate skyrockets and does not adhere to things like serialization rate and send rate, and the traffic rises significantly. The problem here was that I can't send every single bullet firing over the network, it costs too much.

My next idea was to have a bool and set it to true when firing and send it via OnPhotonSerialize. If the bool is true the weapon fires, and when it is false it stops firing. This syncs over the network and it works and only costs as much as the SerializationRate and SendRate, and the traffic cost is 2 bytes per send because it is only a bool.

However there is a problem with this solution, and that problem is precision. If someone is lagging behind just a tiny amount then my gun on my client, and my gun on every other client wont be on the exact same spot. This would make it so that if I fire my gun on my client while moving and rotating, The other clients would see me move and rotate but the bullets would not fly in the same direction and would not hit the same point in the world.

My solution to this was to make it so that the one who fires the weapon has the authority on what was hit or not, disregarding the VFX of the bullets and impacts. However a wild problem appears:

If multiple players fire and hit something at the same time, then the traffic would be clogged again, as every hit would have to be sent over the network. The msg/s rate would spike and Traffic would rise with it.

Remember: The gun fires 10 shots per second, and if you have say 10 players firing and hitting 10 times a second. That is 100 hits per second, which means 100 msg/s.

Now I do not believe that all players would just move around in circles and hold the fire-button indefinitely, but this takes a toll on the network nonetheless.
There was also a problem with syncing regarding the VFX system. If I shoot on my client and sync the bool over the network, the other clients would see bullets flying, however they would see the bullet miss, but still take damage. This is because I would have hit the other player on my client, but because of lag, the other player would see it as a miss. This causes frustration.

To solve the issue with hitting other players and traffic, I would have to make it so that when I hit a player, only that player gets notified. And the player that was hit could then apply damage and send an updated health value via OnPhotonSerialize. This greatly reduced the traffic but still, the problem with precision remains.



The Problem at hand:

Because of the way we are limited my msg/s and traffic. We can't have too many players in the game, but we also can't send too much traffic or too many msg/s. If I want the bullet VFX to start from the same point and travel and hit the same object, I would have to send the origin point, the direction and the hit over the network, which costs way too much.

Now I could get by with not having precise VFX effects on my bullets, but things like grenades or claymores / mines / mountable weapons have to be positioned on the exact same place over the network. Sending a bool to register that I've fired wont be enough in this case. I need to send more.

But I do not want to fragment the codebase with weapons that adhere to the bool, and weapons that has to behave differently. I want a solution that would work for any and all weapons regardless if they shoot projectiles, or get placed on the ground, or work as melee weapons etc.

What would be the best way to create a solution which would work for any type of weapon, that has both the precision and costs as little as possible in regard to msg/s rate and bandwidth traffic, which would scale nicely with 10 or 20 or even 50 players in the game?

Also, I can't use an OnPremise Server solution for this, I need to go through the Photon Cloud.

Answers

  • sdsdink
    sdsdink
    edited March 2021
    Options
    Edited after re reading your post. Sorry I don't have a solution for you at the moment.

    If someone with indepth knowledge could answer this with detailed (within reason) info, this would highly benefit the community here. I wouldn't mind understanding the Pun system a little better.
  • FadiB
    FadiB
    edited March 2021
    Options
    sdsdink wrote: »
    Edited after re reading your post. Sorry I don't have a solution for you at the moment.

    The thing that I am talking about is the fact the issue at hand, e.g. having to spawn a bullet at a specific Vector3 position, with a Vector3 direction, would create bandwidth issues in my game as they cost 16 bytes each, in a total of 32 bytes per call over the network. If I have 20 players firing their guns, I would have to send 32 bytes per shot per player to all other players to mimic the effect on all clients. (Which would add upp to 20 * 32 bytes = 640 bytes every time all players shoot at the same time) This creates a huge problem in bandwidth usage. Currently I have a system implemented that just sends a byte that corresponds to the selected weapon index on the client that shoots their weapon and have the clients handle all logic by themselves, because the bullet is only "armed" on the local client and just mirrored on the other clients. The problem with this solution is that the bullets never travel in the exact same direciton and never impact the same point on the world.