How to store a turn based game state in Node.js - node.js

I am developing a turn based mobile game which is a question - answer game. Basicly server will send a question to players (there will be two players in a match) then player 1 answers this question after that, player 2 will be answering too the same question in a limited time order. Players could use jokers such as extend the time or change the question. This is the basic logic of my game. So here is my question:
I will be using Node.js and Socket.io for the server side. You know whether a player losts the connection to the server or simply kills the app starts again during in a match, they should be rejoin the same match and they should see what happened in the game when they were not there. How should i store the game state in my server?
My approach:
There will be a Game class that stores every state of the game and manages the countdowns for turns with setInterval method etc. and when the match starts i will create them and store like this:
activeGames[lobbyId] = new Game(player1, player2, lobbyId)
So for example if a player uses a joker i will catch that request inside the socket.io then retrive my class like this:
var yourGame = activeGames[lobbyId]
yourGame.useBonus(player1, bonusType)
So all the status of the game will be stored inside the class. But with this approach if my server dies or restarts etc. all active matches will be dropped. So that is not a good thing. What do you suggest about this problem? How my server should store the active matches?
Ps: Matches will be lasted for 3 minutes. After that i don't need the match history or something like that. So i am not looking for a persistent database solution.

Generally, you would generate a token (preferrably a cryptographically-secure one) for each client. When a client joins for the first time, generate the game data, and associate that data with the token. Then, send that token to the client. When the client reconnects, it can send that token back to the server, which then re-associates the data with the client.
As for server issues, there are many ways to go about things. What I'd do is create a folder called temp or session or something, then store each game in its own temp file. When the server restarts, it checks the temp folder for game files, loads them, then clears their temp files. You can add handlers for unhandledException and unhandledRejection in NodeJS to save currently active games to their own temp files before the server crashes or shuts down.

Related

Multiplayer game with socket nodeJs, is DB needed?

I use socket on connection event. new players are created and seen, multiplayer array of objects in console, exists. However, not every event is seen properly (for example, 1. newest connections only see them self, while older see everyone on game. 2. I want also to show all players movements , real time. Dont know how node can handle that). For those issues in brackets, do I need to use Mongo DB or index DB to handle all data real time ?
You will need a database in order for your game to work in a distributed way i.e. so you can scale to more than more server / node process. If you are currently storing all connection/player data in memory, then this won't be accessible by other processes.
With regard to newest connections only see them self, while older see everyone on game I'd need to know more about how/where you store these connections.
For the second point, I want also to show all players movements , real time, I'll need more detail on how you are sending these movements from the client to server, & then broadcasting.

Best practice about multiplayer game with nodejs

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.

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

Storing short term user data on server

I'm implementing a web app in Node.js, a new framework to me. In the app, we pair users together and they share "game data" for the duration of the game. Both users need to be able to query for the current state, push updates to the game state, and recieve updates on the game state. I can do all the event stuff with sockets, but I'm a bit unsure about the proper way to store this data on the server.
I see Node.js has variables that can be accessed from all connections. Would maybe using a global object with unique session IDs as keys and game states and values be viable? Or is there a better way to do this?
You need to use a persistent data store, like a database. If you just use a variable, it could change if the server needs to restart. I recommend MongoDB to get started. It is fast and easy to use when getting started.
MongoDB NodeJS
There are other options like Redis, and many more.

Socket.io Different Client IDs

I'm trying to make a simple multiplayer game using websockets and socket.io.
We've got most features working, and our problem now is finding out who the winning player is.
So the solution we're trying to implement right now is by getting sockets on run time, and when a player dies, they send a message to the server. The server on receiving this message adds a property 'dead' to the socket. So socket.dead = true is set when the player dies.
We then check a list of connected sockets (obtained dynamically) to see if there is only one remaining player alive (by checking if socket.dead is defined). One thing we realised is that the socket.ids of connected sockets actually change - and this is prooving to be a problem for us...
The question is where and when does the socket ids change, and how can we detect these changes so that we update our game data?
Thanks
You shouldn't check for the socket id, instead you should authenticate the user each time he connects to Socket.IO (socket.user = username).
Then instead of checking for the id of the players that are "alive", you can check for their usernames.
More on handling sessions with Express & Socket.IO here: http://www.danielbaulig.de/socket-ioexpress/

Resources