The reason why I missed it the first time is because this information is introduced in the second half of a paragraph, where the first half is about a different topic. This is a bad way to divide paragraphs.
> The encoding/decoding is done with printf/scanf like functions with a format string and a variable number of arguments. However, no actual string formatting is done, the payload is a binary representation of arguments.
Seems to encapsulate the complexity of having a string formatting interface to a binary protocol reasonably clearly, but is not crafted to withstand speed reading or skipping over sentences.
- bindings to other languages: I'm seeing C/C++ and Python supported. I could, hypothetically, use anything with a C-native interface to wrap that C library and bind to other languages, but that's work I'll have to do. And that binding is going to be as easy-to-use as a wrapper around a C-native library.
- versioning (or some other way to deal with drift between serialization and deserialization). In practice, protocol buffers are often used to do both long-term storage serialization and short-term on-wire transmission. Both use cases always eventually involve two services that cannot be kept in lockstep sync on releases (either because you have to read older files or because you needed to release your backend before your frontend, do a rolling release, whatever).
This is simpler than protobuf, which is cool (and I'd recommend looking over its implementation to figure out how to write something like this), but if you put it into implementation in a non-toy distributed-system project it will not scale. It may have other applications though; I can definitely see it as the backbone for a simple videogame messaging protocol.
Still, no harm in writing a thing and putting it out there; I'm happy it exists even if I won't use it.
Plenty of distributed systems don't have the requirements you outline or need to scale. Distributed systems are not necessarily large, cross organizational lines, or require rolling releases. Sometimes the tradeoff in complexity by, for example, introducing a dependency on protoc et. al., is not worth it. I've built several systems that this would've been a perfectly fine choice for.
I'd also point out that because it's so simple, adding implementations in new languages should be fairly straightforward, but I think this really shines in C codebases where complexity must be mostly dealt with by hand (for better or worse).
(But fwiw, if you did want to inspect this traffic as human-readable, it would be insanely easy to create either a packet sniffer for this or add support to tcpdump/wireguard. It's just dumping a printf format code and some raw data onto the wire, so you just pick up a new frame, read the format code, snip the data from the frame, pass it to printf() with the format code and the data. It's like 12 lines of code, no library needed other than libc. As a hacker I find this way more exciting than using a bloated standard to pass utf-8 strings)