⬆️ ⬇️

Creating a multiplayer realtime game on node.js





A few months ago, my colleagues and I decided to make a multiplayer realtime game that could work on the web. We decided to use node.js for our server. This decision led to a very convincing success - our server worked for several months without a single crash or process restart.



We decided to write our game on node.js, because we heard a lot of good things about this platform and really wanted to play a little with it. And it was amazing - we quickly entered the topic. For node.js there are many interesting libraries that can solve completely different tasks. A side benefit of using node for the server part is, in fact, javascript - a very easy to use language. This allowed us to focus on the problems that occur in all real-time games, without too much fuss, restrictions and the need to compile code, as happens when using less dynamic languages.

')

Also, node.js has proven to be a very lightweight language, even at peak times. For our game, the node.js process used only one thread and consumed only about 3-4% CPU while simultaneously running 8-10 copies of the game, each with its own collision detection engine.





Initial approach



The initial (naive) approach when writing a multiplayer realtime game looks like this:



var info = {}; info.position = {x:10, y:15}; info.velocity = {x:0.5,y: 0.2}; info.currentWeapon = 1; info.radius = 10; this.netChannel.send( info ); 


The server forwards all received data packets to each connected client:



 function broadcastInfo( sendingClient, messageInfo ) { for(var aClient in allClients) { if(aClient != sendingClient) { aClient.connection.send( messageInfo ); } } } 


Main problem


With this approach, you can not trust the information about the location of the user, which he sends to you. The user will always report that he is there, where he needs to, gets into all opponents with one hundred percent accuracy and has a full stock of health.



Another problem with this approach is that you can never truly display a moving object.


Sometimes this effect is called a bouncing ball. It is connected with the need to extrapolate the position of the object until the next packet arrives, based on the speed of the object, and further “adjusting” the position, etc ... When the ball is at the top of the parabola along which it moves, the speed is zero. Therefore, predicting its movement based on speed, we will get exactly the same point in which it is located, and the ball will hang in the air until it suddenly collapses sharply down.







Finally, another major problem is packet loss. If one of the packets shown in the figure with a dashed line does not reach the recipient, the object will follow an incorrect trajectory. And the further - the worse. Of course, time is measured in milliseconds, and this is not the end of the world. However, in fact, it looks very unnatural, since the objects of the real world can not move instantly.



Another approach is client-server model.



In the process of developing the game, we decided to find out how to solve this problem in practice. After all, someone has already done multiplayer realtime games. We found several interesting sources of information, in particular, the free source code of Quakeworld and some technical descriptions from Valve employees.







In this model, there is a single authoritative server that simulates the game. As well as customers sending only their input data. For example, I send only information that my space bar was pressed, and the server determines what it means in terms of the game. Thanks to this model, we are freed from the many problems of the previous implementation.



Rendering world


Our nervous system can adapt to the delay. If we use the same short delay time to draw an object, the person easily adjusts to it and stops noticing the delay at all. The key to resolving our problem is that we are rendering the world to all customers in the past tense, the way it was N milliseconds ago. The number N is chosen arbitrarily. For example, we used 75 milliseconds.



Basic procedure








RealtimeMultiplayerNodeJS



We faithfully believe in open-source, so we decided at the end of development to clean up the code a bit and put it as an open-source project. Since we didn’t really succeed in choosing good names, we called it RealtimeMultiplayerNodeJS.



RealtimeMultiplayerNodeJS is a framework designed specifically for creating multiplayer realtime games using HTML5 and a client-server model. In this model, users send only input data, and the game itself is modeled on the server. Clients interpolate the world between its two states based on the current rendering time.



How to use the project


  1. Download repository
  2. Start the server “node js / DemoHelloWorld / server.js” in the terminal
  3. Open the "/DemoHelloWorld.html" page (Note that the file must be visible from the server so that you can connect using websockets)


Physics Demonstration


This demo is made in order to show the idea of ​​synchronized physical processes when all modeling takes place on the server. To create the world used Box2D.js. It also shows the synchronization of the interaction of several users, as well as an example of sending a message to the server with its subsequent interpretation again on the client side.







DemoHelloWorld


The most simple but interesting demo that we were able to come up with. Objects move from left to right.







DemoCircle


Demonstration of a simple CircleCollision collision engine, which provides the simplest information about collisions and generates an event when two objects collide. This demo also shows the implementation of a special type of object that is controlled by a connected user using the keyboard.







Finally, just to emphasize the main idea - an entity interpolation diagram made in the ASCII technique:


  (actual time) (snapshot interval) | | | _ (rendered time) | / \ | / vv / | ------|-----|----v|---|----|----|--v---------> 0.0sec 0.1sec 0.2sec 0.3sec time | | \ / \------\/----/ | | (interpolation time) 

Source: https://habr.com/ru/post/182678/



All Articles