MOTD Player Stats

A minecraft server called General. The message of the day is: 78865 jumps and counting!
Release - 22/09/2025

Display live player statistics in a Minecraft server's message of the day.

Code Repo


I run a Minecraft server for some of my friends and I wanted to make the message of the day (MOTD) more fun than just some static text, so I had the idea of using it to display some interesting player stats that Minecraft keeps track of. Now, I know that there are several server mods that process MOTDs that I could fork and update to read the player statistics, but I don't like to go too modded in my solutions (ironic right?). So instead I decided to implement it as a proxy, inspecting each packet to see if it contains the MOTD, modifying it if it does.

Minecraft servers communicate two things before moving to encrypted communication: the server status and a ping request. The MOTD is included in the status packet, so it was relatively simple to identify the MOTD inside the JSON and replace it. Minecraft also stores player stats in JSON files, meaning it was possible to just read from the files on request, which gives the most up-to-date statistics. I decided to only implement the values as a total across all players, as this just makes the most sense for most statistics.

I initially developed this program to the point that it was a barely-functioning prototype, but I don't like to see my work stay unreleased when it may be useful. So I gathered myself together a month later and fixed up some glaring issues with the early revisions, to prepare it for release.

One of the things that eluded me when making the prototype was keeping the ping counter functional when the proxy was active. This was the main issue that held me back from releasing this earlier. I eventually figured out that I'd simply forgotten to continue listening for further packets after receiving a status packet. I also updated the code to correctly generate the packet header, instead of carefully making sure to not change the length of the packet so the header would stay the same. The structure of a status packet is:

[length of packet][length of string][JSON string]

The header here is not only somewhat redundant, but also inconvenient to parse, as the lengths are stored in Minecraft's special flavour of varints. Fortunately there was already a crate available to convert between them, because I wasn't looking for a reason to get sidetracked from this project. By implementing correct header generation, I also fixed a bug that I didn't encounter in my testing where the whole program would fail if a certain number of players were online at the same time.

Finally, I added some more configuration options, such as randomised messages and I allowed statistics to be fetched by path from the message, so they were no longer hardcoded, making the program a lot more user-friendly.

When testing the effect this has on the server's performance, I found that the latency increases by 2ms on average, and the MSPT seems to stay the same. I think a key part of this is the fact that most packets sent by Minecraft during gameplay are very small, making them very easy to identify as not the status packet, preventing more expensive computations are performed on them.

Overall, I'm happy with this solution, especially given the approach I took, and I'm very glad it doesn't impose a significant amount of overhead. It was definitely worth the time to polish up the prototype into a proper release.