Thursday, February 19, 2015

First Footage


It’s time to make our dreams come true. We have been writing some tech entries about how to do a multiplayer game. Now, you can see how  we have implemented this ideas . Look at the following video: 4 players/snakes online trying to survive:






You can detect easily some client time tick corrections (just notice that client tick is not always the same). In the other hand, it’s not easy to detect that there is one correction at client side. During the game, one movement arrives late to the server so when the consolidated server movements gets back to the client, he’s forced to correct the initial prediction and moves based on server movements. As a user, you will see how an initial movement is quickly modified(our head changes his position).

The best of all is that everything works in a smooth way.

Thursday, February 12, 2015

Cheating Latency



In our last posts we have been dedicating our efforts to reduce the client perceived latency. Let’s check what   we have  focused:
-          We have configured TCP to flush data as soon as it has been generated.
-          We decided to mix TCP & UDP whenever is possible.
-          We create control layers to sync client and server to get a smooth gameplay.
-          We made our own Object Serialization .
All points above are about  technical issues. Now, let’s turn inside our app and let's check if we can enhance its performance.
Summarizing how the server works  will show us some clues about which point can be improved. Let’s look inside:
-        The server and the remote clients wait, initially,  the same gap of time (tick) for each turn.
-          The server wakes up each time tick and consolidates the players movements sent previously by the remote clients.
-        The server sends back a message containing the consolidated movements and tells every client if they have advanced or delayed related to the objective lag between them.
-          The remote clients make some adjustments on the client side to compensate changing latency related to the server.
-          In order to make this work, clients begin their tick before the server in order to compensate each own latency plus certain buffer.
Now, let’s think what we can do to improve this algorithm:

First Enhancement: Try to send  consolidated movements once all player movements have arrived.
As we have seen, the  server  waits until the end of the tick to send back consolidated movements to the client. That’s how it should be, you may think. Sure? Is it strictly mandatory to wait until the end of the server tick if we already have all movements?
Let’ see... We have nothing to do once all movements are received, at server side, except waiting to the conclusion of the tick. So, if we advance the message containing the consolidated movements,  remote  clients will receive sooner that movements and they will paint non own movements before.
As a result, remote clients will see a more fluid and dynamically game and that’s one of our main goals.
            Risks? If the end client  tick time is so close  to the server end tick , we will be in risk of arriving late for the following movements. That’s where our algorithm, described in our last post, works. The following client tick will be shorter than usual in order to keep the same gap related to the server. If it happens very often  we will only feel a faster game and, in fact, this is what we want. Anyway, we always can wait a minimum of time before sending back consolidated movements. In our case, Snake the Net, we have not implemented this guarantee, except at LAN modes,  because we want a fast game and unfortunately, the latency itself introduces more time that we wanted at minimum.
We implemented this approach with sensible results and I recommend to apply similar strategies wherever  is possible.

Second Enhancements: Extra time for the lazy clients
  Let’s think in the opposite way. What if we have lazy clients? What if we add some extra milliseconds to the server tick and then we tell him to recover that time by reducing his tick client? By doing this, we avoid to correct our clients despite he is a really lazy client. We make him to do a fast tick but, in the other hand, we avoid to correct him. In our case this enhancement  help  us by reducing corrections and improving stability. Of course, you have to control if a lazy client is actually a disconnected client. Again, sense common. If he is late several consecutive times, we will disconnect him and replaced by a bot, that they always arrive at time ;-)

Thursday, February 5, 2015

Getting a Smooth Multiplayer Gameplay



As we wrote in our latest  entries our main goal is to get a smooth multiplayer gameplay. This means that we have to guarantee the perfect sync between server and remote players. In an ideal world, we would have to implement the following algorithm:

1.      The server  calculates the maximum client latency and send it back to the client.
2.      Once received the Go command from the server, the client  will wait for the maximum latency minus his own latency (plus a fixed security buffer).
3.      Every client will keep this gap  for the rest of the game by mantaining, clients and server,  the same tick duration.

So, let’s end this post… everything is OK ;-)
…but latency is variable and changes every time for uncontrollable reasons (network congestion, router processor time, etc…). So, if we can’t control something, don’t waste time about it, just try to deal with this.  We know that some movements are going to arrive late at some rate, that’s for sure. We have previously  explained (lasts posts) how we made an algorithm to get back movements and replay real movements sent by the server. This is our seatbelt and it always be there because, above all,  we want to have an stable game. Anyway, we can’t control the changing latency but we can try to mitigate his variation:

 Take for example a distant race… If the leader accelerates, the persecutors tend to do the same whereas if he slows down  the followers tend to also slow down. They tend  to maintain the  distance. At the end, they are keeping the same distance by adding or removing some distance.
If we think in terms of our game there are some parallelisms. The gap  between the end of the client tick and the server tick should keep stable and close to the maximum latency out the remote players (plus an additional buffer).

How to do this? Consider the following guidelines:

1. The server should inform every client about the  advance time that his movements have arrived related the end server tick. That’s an absolute measurement than shows us if we are in danger of arriving late or too soon. For every client, we will write down if the distance has increased or decreased related to the last tick. Send back to the client the info about their relative increase/decrease related to last tick. Once the client has this info, he has to compensate the variation by adding or reducing milliseconds to the server tick, in order to maintain always the same gap.

2. We can use some tricks for reduce the variability of the client tick game. A good practice is to  adjust  this delay by multiplying by a constant (between 0 and 1) because latency variability may compensate by himself. There are no mandatory strategies to handle this. Just try yourself what adjusts better to your scenario.

As a result of this combined approach, we finally got a smooth and interactive gameplay!

Monday, February 2, 2015

About the game: Snake The Net



We have focused on tech issues and specialized  details about multiplayer games and we have not explained anything about "Snake the net", the game that we are designing.

It's all about several snakes that try to kill the other ones while avoiding other obstacles. Does it sound familiar? Yeah, i agree... we are not reinventing the wheel...or maybe we are. Le me explain.
We won't convince no one that this is an original game. Of course, tens of games are based on the same idea. But, do you know any snake multiplayer game? Even Better. Do you know any snake multiplayer game fast enough to deserve be played?  I don't think so.


Our challenge is to make a multiplayer game with ticks (turns) below 500 ms. I think 300 ms will be such a challenging objective. Consider this: Players around the world will play at the same time and they have to see, obviously, the same game.

About the game itself we have made some new variations.  Several basic rules:

We are a snake ;-) Nothing new. Isn't it?

This is a piece of wall. We can't move inside a wall. If we do, we die and we become also a sequence of walls. Thrilling.


And, we have designed some magic cells that you can eat:

Get Bigger. We grow as much as the number displayed at the toolbar


Go Fast. If we eat this cell, we start moving twice as normal. We only move several ticks, depending on the number displayed at the toolbar.



Stop Other Players. We freeze the other players while we move smoothly. As usual, it depends on the number displayed at the toolbar.



Decrease Rivals size. The reverse of the last cell. If you eat it, the other players will decrease their size .




The game implementation is quite advanced  but we are facing now the exhausting  duty of testing it. The hardest part, as you can imagine, is related to networking issues, since this game shines by the multiplayer layer.

Of course, if no one connects at a time, you still would play because the server will create some bots... At the moment they are not so intelligent, but they will be... soon.



Anyway, you can see the first screenshots published. In the following posts, it will be available a video where you will see the gameplay.


Enjoy it!