If you're writing some kind of networked program (such as a game) in a "native" language (like C++, C, Rust) or "native-interfacing" language (like Java, C#, Python) then you'll want to make your network messages be reasonably easy to transfer to/from the buffers you need to send on the wire.
Typically, you use some form of serialization. Unfortunately, the serialization packages that come with most frameworks, focus more on version robustness and dealing with networks of connected objects, than on storage efficiency, and are not appropriate for game networking. Instead, you need a simpler mechanism. Luckily, these are fairly easy to implement.
This article will assume that you're working in C++. Additionally, it will assume that you communicate between systems of equal byte order (e g, in the modern world, all the CPUs that communicate are little endian.) See footnote at the end if that's not the case. Also, dealing with low-level byte representations is where most of the terrible networking "zero day" bugs come from -- if your code gets some buffer size wrong, or fails to check errors, then running the code on a machine may make that machine susceptible to remote attack. I'm assuming that you will very carefully study and debug your program until it is water tight.
Further, I'm going to assume that your game sends updates from a server to all the clients on some timer (such as 30 times a second) and from the client to the server on some similar timer (such as 30 times a second.) I'm not going to go into details as for why this is generally the preferred way to structure a game -- this article is simply about formatting messages efficiently for reading/writing.