Understanding how your server ticks underneath can be helpful when diagnosing problems regarding slow performance. We’ll cover several topics.
- An overview of the game logic loop
- How this all applies to modded servers
- An explanation of transient problems
- A guide to profiling your server
- A macro-view of improving performance
The game logic loop
The most important part of Minecraft is the game loop. In there is a clock keeping everything synchronized, going tick-tock at an ideally constant rate: twenty times per second, with each tick or tock lasting hopefully at most 50 milliseconds. During each cycle, game elements have to do their work — skeletons have to figure out where to walk, minecarts have to travel forward, grass has to spread, and light problems have to be checked. That’s a lengthy to-do list, considering how many blocks and entities are on a loaded world at at time (thousands). This tick-tock interval is called the tick rate or “TPS,” and you can get some mod or plugin to give you your server’s rate.
Quite a few things are on the to-do list, but as far as the “main game elements” go, those items are blocks, entities, and tile entities. Blocks include simple things such as sandstone, cobble, sugar cane, and things of that nature. Entities are your standard animals and monsters, in addition to paintings, item drops, and “objects that don’t fit perfectly on a grid.” Tile entities are a special kind of block, as they can hold any type of data (think storing an inventory, something sugar cane doesn’t have to do), and sometimes they must think separately. As previously mentioned, each loop has a budget of 50ms and each portion consumes some part of this pie. Any leftover time is considered idle.
There’s this interesting exploit in Minecraft that lets you login under someone’s name without ever needing to know the person’s password. All the attacker needs to do is get you to join his/her server once. This client-side fix patches your game so that it won’t let your server tell you to authenticate against a “blank” server ID. Lymia and I reported it to Mojang a while ago, and while Jeb just put a fix in 1.8, there’s a mistake with the fix. You can download a ZIP to install it like any other mod (put the files into minecraft.jar), or Windows users can use the setup program to automatically install the fix:
A server-side fix has recently made it into a Bukkit, but your account can still be abused to join unpatched servers. This client-side patch prevents any server from exploiting your account. To understand how the exploit works, here’s a review of how Minecraft would authenticate for “Frank”:
- Client->Server: Your game tells the server that it wants to join as “Frank”
- Server->Client: The server responds with the ID “afe93b31c” (randomized)
- Your game tells Minecraft.net that “Frank” is joining “afe93b31c”
- Client->Server: The client tells the server that it’s ready
- The server asks Minecraft.net to see if “Frank” has joined “afe93b31c” (if not, then the real Frank never joined the server)
Here’s how the exploit works: You get your victim to join your custom server that sends a blank ID. Frank’s game tells Minecraft.net that Frank is joining “” (a blank ID). Frank joins your server, plays around, and has no clue about what’s going on. You then join Frank’s server where Frank is an administrator, but you immediately skip to step #4: You tell the server that you already did step #3 and you get in. Why does this work? On the server, the server ID is blank if you never complete step 1, so in step #5, Frank’s server asks Minecraft.net if “Frank” has joined “”, which Frank did earlier but on your server.
From a more technical perspective, the hacked client never sends the initial handshake packet. The server ID starts out as a blank string, and it’s only initialized if you send the handshake packet. If you skip the handshake packet and just jump to the login packet, then the server ID stays as a blank string. Before 1.8, your client would freely accept a blank server ID. 1.8 prevents a server from giving you a blank server ID, but Lymia noticed that the game doesn’t URL-escape the server ID, so a server ID of “&” is essentially blank. The patch makes the routine URL-escapes the ID.
Addendum: Someone mentioned a “man-in-the-middle” attack that allows for name spoofing, but that’s a different issue that can only be fixed with significant changes to how Minecraft handles authentication. (A MITM is also more difficult to pull off well.)