Hi again.
Working on ways to sync projectile spawning for weapons. I have things more or less figured out for how the client will tell the server that it fired (incrementing a sequence number), but I've got a few options for how to relay the projectile being spawned to all of the other nearby players.
First, some constants:
- Think multiplayer bullet hell arena shooter, though with not quite so many bullets.
- 50Hz tick, 25Hz packet send rate (so 40ms between packets)
- To spawn a projectile, the client needs to know what server tick it happened on, what entity shot it, and what the position/orientation/velocity of the entity was at the time (technically we could infer this but I want to be as precise as possible).
Right now I have two schemes for sending events:
1) Reliable Ordered. Recipient keeps a sequence ID of its last processed event. For every event received, if the event's ID is one more than the sequence Id (not just greater than, but the exact next event), increment the sequence Id and process the event. Send the sequence ID to the sender so the sender can delete old pending outgoing events and resend unreceived ones.
2) Unreliable with optional redundancy. Sender keeps outgoing events in a list. Each event is resent N times (set on a per-event basis). No acking or feedback from the recipient. Recipient keeps an expiring hash set of received events to avoid re-processing duplicate events. Sender has no way of knowing the recipient has received a particular event, so we always resend N times even if the event was received on the first send.
I'm torn between using (1) or (2) (with a long expiration time) for spawning projectiles. In both cases I'm worried about clogging up the pipe if there are a lot of players in one area shooting at each other, and wondering if there's a better way to do it.
One thing I've thought about is a variant of (2) where the recipient sends back the last N (10?) received event IDs so the sender can clean out some of its unreliable events if they have a long expiration timer. I would love to just have the recipient send back the highest event ID it's received for (2) and use that to clean, but that means if the recipient receives packets out of order it may skip some events. The reason I'm hesitant about using (1) is that if the message queue gets really backed up, we could be trying to spawn projectiles that have long since expired.
Just curious if anyone has any suggestions or could share experience about how they handled it themselves.