Hello. I’m doing a server-side rewind algorithm for a multiplayer shooter. I would like a couple of the automatic weapons to fire quite quickly, potentially faster than the net update. I’m sending an RPC when the fire button is pressed and released, but in between that time, cosmetic automatic fire effects happen locally client-side and server-side, based on a fire timer that resets with each shot. The hit target destination (an FVector_NetQuantize) is sent from client to server via an unreliable RPC each shot as well. I’m not too concerned with the shots being 100% accurate between these updates, as they’re purely cosmetic and I’m server-side rewinding when the client sends a score request after hitting a player on their side.
However, since some of the weapons are firing quickly, if lots of shots are scored, there could be a lot of score request RPCs headed serverward. So I had the idea of only sending an RPC each net update. The first time a player gets a hit, the client would send the first score request, with the hit target (FVector_NetQuantize), a pointer to the hit character (ACharacter*), and the server-synced hit time (float), for the server-side rewind algorithm. Then the client could wait for the server to respond (the server’s sending a multicast RPC in return anyway, to inform the other clients about the shot and play fire effects). Until the server’s multicast RPC comes back, rather than spamming the server with more score request RPCs, any score hits could be cached, and once the multicast RPC gets back, send an array of hit requests. A hit request looks like:
USTRUCT(BlueprintType)
struct FHitScanHit
{
GENERATED_BODY()
FVector_NetQuantize100 HitLocation{};
float HitTime{};
ACharacter* HitCharacter;
};
Now I know that the net amount of data sent is the same, if not more since it’s now a TArray of USTRUCTS, and the bandwidth is really what matters. If you send too much data, you send too much data, right? My question here is a matter of timing. Which is better, if either? Spam lots of RPCs to the server faster than it can receive them, and leave it to catch up when the player stops firing, or send fewer RPCs that contain potentially more data. If I cache the hits and send them in batches, I could at least throttle the amount of data sent by capping off the array (3 or 4 hits, for example). If you need to cache too many hits, you’re too laggy to get scores anyway, and at least you’d get credit for the first 3 or 4 shots you made between net updates.
Anyway, I appreciate any input. If anyone thinks this is viable or knows of a better way to handle rapid-firing weapons, I’d be grateful if you shared some insight. Is there a lesser of two evils between too many RPCs too rapidly and less RPCs that are bigger?
Thanks.