TimonPost / laminar

A simple semi-reliable UDP protocol for multiplayer games
821 stars 66 forks source link

Ack header only sent with reliable packets #293

Open RJ opened 3 years ago

RJ commented 3 years ago

If you send reliable packets from A -> B, and only unreliables from B -> A, the reliable packet acks will never be sent from B -> A, because the acknowledge header is only added to outbound Reliable packets (and only the first packet of fragments).

Without a regular stream of reliable packets going both ways, you don't have acks, and all packets still appear to be in-flight. So you don't have any reliability.

Caught me out. I was expecting acks to piggyback on any outbound packet with available space, even heartbeats.

Perhaps a concious choice(?), but wasn't clear to me from the docs.

TimonPost commented 3 years ago

That is the correct way it should work, unreliable is not acknowledged and reliable is.

Jacob-JB commented 1 year ago

I think this issue needs to be looked at more if this project is ever contributed to again, or at least be understood by those that want to use it in it's current state.

What RJ is trying to say is that the acknowledgements for reliable packets are only sent in returning reliable packets that aren't generated on their own. This means that if you set up a purely one way protocol then there will be no acknowledgements ever.

After I ran into this problem myself I found that it's also not just as simple as sending a few empty reliable packets. You need to send enough of them. So if your server sends more than 32 times as many reliable messages as the client then the number of unacknowledged packets will slowly increase until failure. So you can be using laminar for a good while, then make a change to your protocol and suddenly clients are randomly disconnecting, without an indication as to why.

RJ commented 1 year ago

it's quite common that the server sends occasional reliable packets to the client, especially during the initial joining and setup phase.

it's also common the clients mostly send unreliable packets to the server, for example just player inputs.

so yeah, it's a fairly serious oversight imo 🤷‍♂️

i've not looked at the laminar code in a couple of years, but sending an ack header for reliables along with any outbound packet would probably solve it. there's no reason an unreliable packet can't also deliver some acks for any reliable packets you received.