MidLevel / Ruffles

Lightweight and fully managed reliable UDP library.
MIT License
212 stars 28 forks source link

New Channel: UnreliableSequenced #28

Open cakeslice opened 3 years ago

cakeslice commented 3 years ago

Is your feature request related to a problem? Please describe. The problem with UnreliableOrdered is that it drops older messages even if the game didn't read the pending ones yet. This is a waste of information that is useful to the game and unnecessary packet loss.

Describe the solution you'd like The solution is to implement a UnreliableSequenced channel that keeps older messages and sorts them until the game/MLAPI performs a read on them. After the read, older packets are dropped.

Additional context A good example of this in practice is this post from the Lead Networking Programmer of Epic Games where they had to implement this in Fortnite to fix the packet loss problem: https://www.reddit.com/r/FortNiteBR/comments/awagpo/packet_reordering_technical_post/

TwoTenPvP commented 3 years ago

This actually requires quite a bit of changes into Ruffles since Channels are usually not aware of any reads.

This addition will probably have an impact scaling aswell

cakeslice commented 3 years ago

Even if it has an impact scaling, it would be optional (a new channel) and still useful for some games/apps that don't require large scaling.

I'm trying to implement it and I was able to discard only the packets older than the last polling time by storing the current _incomingLowestAckedSequence in another variable inside the Channel whenever I poll (I used UnreliableOrdered as a starting point).

Right now the only thing left is to do is sort them right before polling or to keep sorting as they are inserted into the ConcurrentCircularQueue.

Do you think it's possible or a good idea to add a Sort() method in the ConcurrentCircularQueue based on the sequence number?

Thank you