Things I Had To Figure Out

This page is about all the analysis I did of the official slither.io servers and how they work.

First, giving credit where credit is due: I relied heavily on the analysis of the client-server protocol, as documented by ClitherProject. It was designed for v11, but very close to the v12 that was used for quite a few years.

Aylina makes it sound like she didn't look at my source code or other material at all... but then how did she figure all this out in days, rather than the months it took me?

When I was doing my research and publicly documenting how the server works, Aylina helped out a bit with educated guesses, but offered no research of her own. That's fine... but it also shows that she had zero interest (or perhaps lacked the skills) to do any research. She just copies what others do.

Number Precision

When Aylina started working on her server, she knew that it was best to store values as "doubles" (high precision floating point numbers) to match what the official servers do.

Why? Because when I started out, it looked like they were integers! That's because the client-server communication protocol uses integers. So it would send the boost speed as 14,000 rather than 14.000.

For a long time, I stored the "fam" (how close the snake is to a new body part) as an integer from 0 to 16,777,215... because that's how the server sends it to the client. But I learned it is much more efficient to use doubles. Aylina got to skip over that "trial and error".

I also did research into the x,y coordinates of the snake, and was able to determine that the server stored them as 64-bit floating point numbers, not 32-bit. Not something easy to figure out when the server sends them as 16-bit integers or 8-bit integer offsets.

Snake Starting Point

A naive observer might assume that snakes simply start in a random position (something like "x=random(); y=random();").

But keen observers will notice that snakes rarely start close to the outside edge.

And even the keenest of observers won't notice that there are a limited number of concentric "rings" that the snakes can start on. Mapping thousands of snake starting points will show this pattern.

I haven't checked, but I am assuming Aylina copied the formula I used for this.

Naturally Spawned Food

I needed to determine why this food would sporadically appear (answer: pieces are generated for each snake less than a certain length).

Then, I needed to determine where this food would appear (how far away? what direction?).

Then, I needed to determine how often this food would appear (answer: every 1.034ms).

Then, I needed to determine the size (answer: random, within a set range) and color (answer: random) of this food.

I examined over 10,000,000 pieces of food the server added, determined which were added due to boost, and analyzed them.

I haven't checked, but I am assuming Aylina copied the formula I used for this.

Boost Food

Most players know that when you boost, food is generated behind you.

But, I needed to determine how often it was generated, as well as the size and color.

I examined over 10,000,000 pieces of food the server added, determined which were added due to boost, and analyzed them.

If Aylina didn't rely heavily on my work, how did she find this out?

Visible Sectors

The official servers have a group of "sectors" (areas of the map) that it sends to the client. Any food, prey, or snakes in those sectors will get sent to the client.

I needed to determine which sectors a snake would be sent. I needed to determine that the number of sectors was based on the size of the snake and the speed of the snake (even though Aylina and Numerous both were convinced that the speed of the snake did affect the visible sectors).

I had to analyze the starting sectors of many games to determine the initial shape of visible sectors, and then had to determine exactly when the view expanded.

And then I had to determine when the sectors are removed.

So did Aylina actually do all this herself and re-invent the wheel, or did she simply copy my work?

Food Size and Snake Size

There are dozens of different sizes of food, and with the complex snake scoring formula, it wasn't easy to figure out how to increase the size of the snake based on the size of the food.

To do this, I looked at the first piece of food that a freshly spawned ate in 1000s of games. I was surprised to see, for example, that eating 2 pieces of size 25 food increases your score less than eating 1 piece of size 50 food.

I also reverse engineered the math to determine that the fam value (percent fullness of the last body part) increases using a formula (size^2)/7845. So... again, did Aylina really do all this research herself, or did she read what I wrote about it, or did she look at the source code I gave her? It would take many hours to discover "fam+=(size^2)/7845;", but seconds to cut-and-paste, and less than a minute to port.

Speed of Snakes

All players know that snakes can go at the "normal" speed, or boost at a faster speed.

Advanced players know that at boost, all snakes go at the same speed... but the "normal" speed of a snake when not boosting is faster the larger a snake is.

Really observant people will realize that snakes accelerate/decelerate when switching between normal and boost speeds and back again.

To help figure this out, I analyzed the score and speed of 66,369 snakes when they first appeared on the screen. To determine acceleration, I looked at 46 snakes of sizes from 21 to 37,294 and came up with a formula that felt right, and compared it to the actual results.

There's also the curiosity of the initial snake speed, which is set as 5.790 but is actually 5.777.

So... I'll stop asking the question I've been asking at the end of these.

Food Generated on Snake Death

When I started my project, there was likely nobody (outside of those that worked on the original slither.io code) that knew how many pieces of food were generated when a snake died.

I first had to figure out how many pieces of food were generated. It was actually ingenious: 2 pieces placed near each body segment (x,y coordinate). So a freshly spawned snake (score 10, with 2 body segments) would always generate 4 pieces of food.

Several people had done some research on the total score, which was very helpful. I used the formula that SN Laboratories had come up with, divided the total by the number of pieces of food, and converted from score to body segments.

In all, I analyzed over 2.5 million pieces of food generated when snakes died.

Packet Timing

When I started, it was not known how often the server sends out packets. With the Nagle algorithm in use, it was harder to figure that out.

However, through packet sniffs of server that were fairly local (to eliminate Nagle issues), I was able to determine that the server sends packets out every 47ms (unless delayed by Nagle).

Snake Movement: 42 Units

The official servers send out "snake movement" packets every 94-233ms.

I carefully analyzed the timing of these packets, comparing the coordinates to the previous location of the snake, and determined they were sent when the snake moved exactly 42 units.

When I publicly documented this, Aylina said "yea i dont think its actually doing that". So at least at that point in time, Aylina had done no research into how far the snake moves between each update.

Snake Movement: Boost Racing Glitch

One quirk that people have noticed with slither.io is that when 2 snakes are "racing" (boosting) parallel to each other, every few seconds one seems to "jump" ahead slightly.

I did research into this, and discovered it was because the snakes move 42 units every 96ms at boost, but the server sends out packets every 47ms. That means the server sends out 2 packets every 94ms, just shy of the 96ms that the snake moves its 42 units.

So each time the server sends a new movement packet, it gets 2ms out of sync (96ms-94ms). It takes about 50 47ms cycles for things to sync up again. I created a chart showing exactly what happens when I publicly documented this.

Aylina's response was "could be some proxy unrelated to the server itself"... despite the data I found proving the issue. Clearly Aylina had done no research into this glitch previously.

Protocol 12

As I have mentioned, the ClitherProject documented v11 of the client-server communication protocol. But not v12.

So I did research into how v12 works, what the differences are. I did this using packet sniffs (looking at the actual data sent between the client and server).

Once I documented this, Aylina had access to why the client would send 0xff 0x00 (to close the connection), how the client sends the server codes, and did not have to do any research herself.

Sector Garbage Collection

I forgot about this until I looked at the internal document I sent Aylina.

My research showed that while the server sends new sectors immediately as the snake enters new sectors, it removes past sectors every 517ms (11 cycles/ticks).

Just something else Aylina didn't need to do research on, because I had.

Snake Introductions/Deintroductions

For slither.io to work, you need to determine exactly when the server sends "snake introduction" packets.

There are 3 possibible reasons for a snake introduction: [1] Your snake has more visibility (e.g. when growing to a bigger size, you can see further), [2] the head of your snake enters a new sector, [3] when you first spawn. I'm sure that Aylina could have figured out on her own, as it can be figured out with research (e.g. without analyzing packets).

Spline Calculations

For me, one of the coolest things about slither.io is how the whole snake moves in towards itself. That's how you get killed if you are wrapped (your body constricts in on itself).

It took a couple of weeks to figure it out, and I was able to elegantly handle it in about 5 lines of code.

Aylina didn't have to spend weeks figuring it out. In just seconds, she was able to just cut-and-paste my code... or in just minutes, write her "unique" version using mine as a reference.

Order of Processing

There are 2 parts to this... both are extremely important.

First, there are certain things that need to be done in a specific order. For example, when "ticking" a snake every 47ms, you need to move the snake before seeing if it is in a new sector, and you need to see if it is in a new sector before sending any newly visible snakes.

Second, there is the order of sending packets to the client. If a snake gets smaller because it is boosting, and is also turning, is the "get smaller" packet sent before or after the angle change packet? I analyzed 13 different packet types to determine their exact order, and put this in my internal notes that I gave to Aylina.

This is a huge amount of research that Aylina either copied from me, or "reinvented the wheel". Eiriker boasts about how Aylina was able to create her server in 3 weeks because of her triple-digit IQ... but maybe, just maybe, it's because she already had just about everything she needed.

Everything Else

This is just the tip of the iceberg, so to speak.

There is a ton of other stuff I had to figure out: the speed snakes move in units/time, turn radius based on speed, acceleration of snakes, what food gets eaten (not just food the snake glides over!), how often the leaderboards/maps are updated, whether the minimap is sent to all clients at the same time or not, food equilibrium, replicating the "invisible tail", what the server does with server bots that get too big, whether snakes can "vanish" (they can), what happens with live snakes that disconnect before dying, the exact location on the border where snakes die, etc.