Search Unity

Do I have RUDP right?

Discussion in 'Multiplayer' started by allencook200, May 21, 2021.

  1. allencook200

    allencook200

    Joined:
    Oct 2, 2020
    Posts:
    178
    Hi, so I'm planning on building my own RUDP protocol built on top of the udpclient.

    so to make rudp, Everytime I send a packet from server, I store a new object that contains the sequence number, byte contents, and the time it was sent. Whenever an ack comes in to server from client, check against stored objects and delete the object containing that sequence number. and also check every n milliseconds to see which packets havent gotten a response in n milliseconds since they were sent, update the timestamp on those objects to present, and resend them?

    Sound about right?

    obviously i'd have an object pool so im not allocating memory on each send

    and for the sequence #, do I just iterate on every sent message?
     
  2. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    I'm confused whether the "n milliseconds" you mention twice, is referring to the same value. I check every frame to see which packets haven't gotten a response within a timeout period. I use 1 second, but you could tighten that up. Whatever value you choose, that's essentially the max ping time your protocol will ever support, but the higher the value the longer the delay in resending a lost message.

    I assign a unique ID to each outgoing message on that connection (or per channel, I forget). I just use a ulong which I increment. When I send reliably I just set a timestamp when it was sent and throw it in a list of messages awaiting an ack. When the other side sends an ack, it just includes that same unique ID for the original message. When an ack is received, I just remove the message with the corresponding unique ID from the list.

    Like I said, every frame I iterate the list and check if any messages have timed out. If one is found, I resend it with its original message ID. I then update the sent timestamp so it will wait another timeout period to resend again. So sounds pretty similar to what you're doing.

    There are other solutions which send an ack less frequently, using a window system where a single ack covers multiple messages. I'm not sure that's needed. You should only be sending messages reliably which need to be, and that is probably a minority of your game's overall network traffic. In many games the majority of what you're sending are things like position updates at high frequency, and that data is outdated as soon as it hits the wire. No need to be sent reliably, and in fact it probably hurts the game to do so. YMMV, good luck

    Slightly related, I also use the message's unique ID for message ordering and duplicate detection. With a reliable UDP system you will be causing duplicates. This occurs whenever the message was successfully received, but the ack response is lost. So you'll need to deal with them. On the receiving end, my approach is to just enforce message ordering by message ID, and track the last message ID processed. For an unreliable channel, I throw out any older message received after a newer one has already been processed. For a reliable channel I stop all processing until a missing message ID has been received.
     
    Last edited: May 22, 2021