Video games tend to use UDP for the same reason everyone else mentioned does: timeliness. You want the most recent position of the various game objects now, and you don't give a shit about where they were 100ms ago.
The proposed solution of segmenting data into QUIC streams and mucking with priorities should work just fine for a game.
> Is that even supported across all the various gaming platforms?
QUIC itself is implemented in terms of datagrams, so if you have datagrams, you can have QUIC.
Let me rephrase the problem here for a simple FPS game:
The entire world state (or, the subset that the client is supposed to know about) is provided in each packet sent from the server. The last few actions with timestamps are in each packet sent from the client. You always want to have the latest of each, with lowest possible latency. Both sides send one packet per tick.
You do not want retransmission based on the knowledge that a packet was lost (the RTT is way too long for the information that a packet was lost to ever be useful, you just retransmit everything every tick), you do not want congestion control (total bandwidth is negligible, and if there is too much packet loss to maintain what is required, there is no possible solution to maintain sufficient performance and you shouldn't even try), and none of the other features talked about in the post add anything of value, either.
It reads like someone really likes QUIC, it fit well into their problems, and they are a bit too enthusiastic about evangelizing it.
You’re right that a custom reliable UDP solution is going to wind up QUIC-like. On the other hand it’s what games have been doing for over 20 years. It’s not particularly difficult to write a custom layer that does exactly what a given project needs.
I don’t enough about QUIC to know if it adds unnecessary complexity or not.
You also don't want to share the routing performance, congestion treatment, OS queue, and probably a lot of other stuff.
This is only true for games that can replicate their entire state in each packet.
There are many situations where this is infeasible and so you may be replicating diffs of the state, partial state, or even replicating the player inputs instead of any state at all.
In those cases the "latest" packet is not necessarily enough, the "timliness" property does not quite cover the requirements, and like with most things, it's a "it depends".
QUIC optionally promises you that, you are free to opt out. For example, take a look at the QUIC_SEND_FLAG_CANCEL_ON_LOSS flag on Microsoft's QUIC implementation.