It's 2026 and I'm still defining my own messaging and wire protocols.
Plain C structs that fit in a UDP datagram that you can reinterpret_cast from is still best. You can still provide schemas and UUIDs for that, and dynamically transcode to JSON or whatever.
If you decide to use UDP, do you ignore the transmission errors or write the handling layer on your own?