Best practice about multiplayer game with nodejs - node.js

i search the "best practice" to create a simple multiplayer browser game. i have choose nodejs for the backend and maybe Phaser for the front. But i have a question about the algorithm.
In each tutorial the server respond after a client event. But a lot of generic article speak about a loop which send world data at regular interval to all client (for example the valve article).
So what is true ? What is the correct procedure ? It depends of the game type ?
For your information i want to do a simple twin stick shooter with a little world where we must survive as long as possible. And i want to do a cooperative game.
Thanks for help.

You need to distinguish between
updates directly affecting your player which are triggered by actions of other players
and updates which are triggered by actions of your player
If you build your app using Node.js, I assume you are going to work with one web socket connect per client.
You can send data over the web socket connection any time in both directions. There is no restriction at all, as long as the amount of data is moderate.
The server actively sending world data in a loop (implemented using setInterval in JavaScript) is definitely a good choice for informing players if they are affected by actions of other players. You can also use the loop to let the server respond to actions of your player.
If you assume the loop always informs the clients in the same order (e.g. client #1, client #2, client #3, client #1,... and so on), you could optimize performance by preferring clients that are active right now, and are doing heavy activity (that is "the server responds after a client event"). Particularly if you have many players in the game, this could improve user experience.

Related

What's the best approach to allow 2 user's browsers to communicate to each other

I want to make an browser based chess game. Where 2 users take turns making moves on the same board.
At the moment I've set in motion a tomcat server with spring that picks up rest calls made by the node server.
However I'm making a rest call every time any user makes a move. Although the response happens very quickly as there is very little to be done on the server side.
But I feel this may not be the best approach. Is there a better alternative or would rest calls be sufficient in this scenario?
You can use the websocket.io with nodejs for the real-time communication between users.
If you don't want to use the server at all then you can use the webrtc that uses peer to peer connection.
Here are few useful references:
https://dev.to/rynobax_7/creating-a-multiplayer-game-with-webrtc
https://rynobax.github.io/jump-game
https://github.com/jwagner/webrtc-pong
https://www.webrtc-experiment.com/#featured
For Nodejs and socket.io
https://github.com/fbaiodias/phaser-multiplayer-game
Thanks

Unity3D Socket.IO Basic Movement Latency

I'm trying to make a server using with Node.JS and Socket.IO. I want to make an online game that just has simple movement event. I wrote some code, but it doesn't work very well. I have tonnes of latencies. You can check the video in below. By the way, I test it on my DigitalOcean servers or even in my LocalHost. What is the trick about my problem? I really would like to learn Network programming but I always get stuck.
Latency GAMEPLAY YouTube Link -- Especially check 13th seconds
Project GitHub link
I will explain all of my works on below. But If you want to check details codes. You can visit GitHub project link.
On the client side, I used Unity3D. If user key press to any arrow keys like upArrow, rightArrow than I send this information to the Server. By doing so the server knows which direction I would like to go.
if (Input.GetKey(KeyCode.UpArrow))
{
Movement = Vector3.up;
JSONObject data = new JSONObject();
data.AddField("x", Movement.x);
data.AddField("y", Movement.y);
socket.Emit("move", data);
}
// if Input.GetKey(KeyCode.RightArrow)
// if Input.GetKey(KeyCode.RightArrow) .. etc
On the server side, I just used Node JS and Socket.IO. I create an interval function that only sends all players to clients. This interval function fires 60 times every 1 seconds. You can see the code in below.
setInterval(function() {
io.emit('state', players);
}, 1000 / 60);
By the way, when the server receives any move event it does this:
socket.on('move', function(data) {
var player =players[socket.id] ||{};
player.x =player.x+(data.x*0.1);
player.y =player.y+(data.y*0.1);
});
You need to move also locally. So when emitting the "move" command on client side also start moving the player on client side. If you receive new information from the server, merge them. The keyword is interpolation.
First off, you do not need an interval, unless you are doing real time physic simulations on the server in node.
Second think of node.js more in an event driven manner. I.E. only send update to other players when a player makes an action nearby them.
Third use client side prediction. I.E. go ahead and move the player on the client even though the server hasn't received it yet. Then interpolate based on the last position that the server said was valid. A simple linear interpolation will work just fine if you send a time stamp from server.
Fourth, ditch socket io. Socket io is notoriously slow when it comes to websockets. If you want to use websockets then I recommend using just the node library WS. The WS library is efficient and fast. Or if you want an event driven library like socket io but based on WS library. Then you can try my custom library that I use and has been tested in multiple online based games: https://github.com/Metric/data.io. I still actively maintain it and will be pushing out an update to the c# client in a couple of weeks. The update to the c# client fixes some issues that I found while using it in a new project recently.
However, tcp would be more efficient than websockets. Websockets have an increased overhead compared to just a raw tcp or udp connection. Yes, you will still get a delay and will still need client side prediction.
For further info on networking and prediction see: http://gafferongames.com/networking-for-game-programmers/
He covers all the concepts with some code examples as well.
Also see: https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking

Is possible integrate Nodejs with Cakephp?

I want to monitor in real time the data that users enter in comments table.
I have an Apache server running, and suppose that has a node server on port 1337.
How would I do that every time someone save new data, eg return me the total number of table rows in comment and show it in a view?
Maybe way is to make the $this->Comment->save($this->request->data); using a different port using Httpsockect?
Yes, it is possible.
You have multiple ways of solving this, let me give you my ideas
You can simply use long-polling and don't use Node.js at all. It's a suitable solution if there won't be too much traffic there, otherwise you will have a bad time.
You can use websockets and don't use Node.js at all. Here you have a basic guide about websockets and PHP. Although, I am almost sure you won't be able to create "rooms", that is, sending notifications for specific comments.
You can also use Ratchet. This is a more sophisticated library to handle websockets and it supports rooms.
Lastly, if you want to full dive in with Node.js and CakePHP, I would suggest start by watching this talk given on Cakefest 2012 which exactly describe your scenario.
After you have watched that, you might want to learn a little about Socket.io. This is a more complex solution, but it's what I have used when integrating CakePHP and Node.js to create real time applications.
The strategy here is to have the users join a room when they visit /article/view/123, let's say the room name is the articleID, then socket.io will be listening for events happening in this room.
You will have a Cakephp method that handles the save. Then, when user submits the form you don't call directly the Cake action, you have socket.io to dispatch an event, then in your event you pass the data to the server (Node.js) and nodejs will call your cakephp function that saves the data. When Nodejs receives confirmation from CakePHP then you broadcast an event (using socket.io), this event will let know all users connected to that room that a comment has been made.
You have basically the choice between Websockets and long polling.
Websockets (with Ratchet and Autobahn.js)
Long Polling Using Comet
Decide which technology you want to use and start implementing your use case. Consider that Websockets are more or less new. Depending on your requirements you might not be able to use Websockets because you might have to support crappy browsers. See this page.

How to model Push Notifications on server

Brief Description:
Well, since many days I've been looking for an answer to this question but there seems to be answers for 'How to create a Push Notification Server' and like questions. I am using node.js and it's quite easy to 'create' a push notification server using sock.js (I've heard socket.io isn't good as compared to sock.js). No problem till here. But what I want is how to model such a server.
Details:
OK, so, let's say I've an application where there's a chat service (just an example this is, actual thing is big as you might have guessed). A person sends a message in a room and all the people in the room get notified. But what I want is a 'stateful' chat - that is, I want to store the messages in a data store. Here's where the trouble comes. Storing the message in the database and later telling everyone that "Hey, there's a message for you". This seems easy when we need the real-time activity for just one part of the app. What to do when the whole app is based on real-time communication? Besides this, I also want to have a RESTful api.
My solution (with which I am not really happy)
What I thought of doing was this: (on the server side of course)
Data Store
||
Data Layer (which talks to data store)
||
------------------
| |
Real-Time Server Restful server
And here, the Real-time server listens to interesting events that the data-layer publishes. Whenever something interesting happens, the server notifies the client. But which client? - This is the problem with my method
Hope you can be of help. :)
UPDATE:
I think I forgot to emphasize an important part of my question. How to implement a pub-sub system? (NOTE: I don't want the actual code, I'll manage that myself; just how to go about doing it is where I need some help). The problem is that I get quite boggled when writing the code - what to do how (my confusion is quite apparent from this question itself). Could please provide some references to read or some advice as to how to begin with this thing?
I am not sure if I understood you correctly; but I will summarize how I read it:
We have a real-time chat server that uses socket connections to publish new messages to all connected clients.
We have a database where we want to keep chat logs.
We have also a restful interface to access the realtime server to get current chats in a lazier manner.
And you want to architect your system this way:
In the above diagram, the components I circled with purple curve wants to be updated like all other clients. Am I right? I don't know what you meant with "Data Layer" but I thought it is a daemon that will be writing to database and also interfacing database for other components.
In this architecture, everything is okay in the direction you meant. I mean DataStore is connected by servers to access data, maybe to query client credentials for authentication, maybe to read user preferences etc.
For your other expectation from these components, I mean to allow these components to be updated like connected clients, why don't you allow them to be clients, too?
Your realtime server is a server for clients; but it is also a client for data layer, or database server, if we prefer a more common naming. So we already know that there is nothing that stops a server from being a client. Then, why can't our database system and restful system also be clients? Connect them to realtime server the same way you connect browsers and other clients. Let them enjoy being one of the people. :)
I hope I did not understand everything completely wrong and this makes sense for the question.

Node.js game logics

I'm in process of making realtime multiplayer racing game. Now I need help writing game logics in Node.js TCP (net) server. I don't know if it's possible, I don't know if i'm doing that right, but I'm trying my best. I know it's hard to understand my broken english, so i made this "painting" :)
Thank you for your time
To elaborate on driushkin's answer, you should use remote procedure calls (RPC) and an event queue. This works like in the image you've posted, where each packet represents a 'command' or RPC with some arguments (i.e. movement direction). You'll also need an event queue to make sure RPCs are executed in order and on time. This will require a timestamp or framecount for each command to be executed on (at some point in the future, in a simple scheme), and synchronized watches (World War II style).
You might notice one critical weakness in this scheme: RPC messages can be late (arrive after the time they should be applied) due to network latency, malicious users, etc. In a simple scheme, late RPCs are dropped. This is fine since all clients (even the originator!) wait for the server to send an RPC before acting (if the originating client didn't wait for the server message, his game state would be out of sync with the server, and your game would be broken).
Consider the impact of lag on such a scheme. Let's say the lag for Client A to the server was 100ms, and the return trip was also 100ms. This means that client input goes like:
Client A presses key, and sends RPC to server, but doesn't add it locally (0ms)
Server receives and rebroadcasts RPC (100ms)
Client A receives his own event, and now finally adds it to his event queue for processing (200ms)
As you can see, the client reacts to his own event 1/5 of a second after he presses the key. This is with fairly nice 100ms lag. Transoceanic lag can easily be over 200ms each way, and dialup connections (rare, but still existent today) can have lag spikes > 500ms. None of this matters if you're playing on a LAN or something similar, but on the internet this unresponsiveness could be unbearable.
This is where the notion of client side prediction (CSP) comes in. CSP is made out to be big and scary, but implemented correctly and thoughtfully it's actually very simple. The interesting feature of CSP is that clients can process their input immediately (the client predicts what will happen). Of course, the client can (and often will) be wrong. This means that the client will need a way of applying corrections from the Server. Which means you'll need a way for the server to validate, reject, or amend RPC requests from clients, as well as a way to serialize the gamestate (so it can be restored as a base point to resimulate from).
There are lots of good resources about doing this. I like http://www.gabrielgambetta.com/?p=22 in particular, but you should really look for a good multiplayer game programming book.
I also have to suggest socket.io, even after reading your comments regarding Flex and AS3. The ease of use (and simple integration with node) make it one of the best (the best?) option(s) for network gaming over HTTP that I've ever used. I'd make whatever adjustments necessary to be able to use it. I believe that AIR/AS3 has at least one WebSockets library, even if socket.io itself isn't available.
This sounds like something socket.io would be great for. It's a library that gives you real time possibilities on the browser and on your server.
You can model this in commands in events: client sends command move to the server, then server validates this command and if everything is ok, he publishes event is moving.
In your case, there is probably no need for different responses to P1 (ok, you can move) and the rest (P1 is moving), the latter suffices in both cases. The is moving event should contain all necessary info (like current position, velocity, etc).
In this simplest form, the one issuing command would experience some lag until the event from server arrives, and to avoid that you could start moving immediately, and then apply some compensating actions if necessary when event arrives. But this can get complicated.

Resources