Multiplayer game programming, latency and starting players in sync with others - javascript

I've been pecking away creating a multiplayer game where I used python for the server (with Twisted Framework) and javascript for the frontend (web game).
I'm a bit stumped at how I can start players in tine with others. For example, the server sends the players a new map, which starts a countdown from 3, then they can race to the finish.
The issue is if someone has poor latency and another doesn't, the better connection would give them a head start, which is unfair.
I'm stumped as to how to at the very least limit this. What measures can I take or look into? I don't believe I can rely on ping time as that will fluctuate quite often.

Usually, when developing multiplayer features, the engine that run the game run both on clients and server.
When the server receive client data (along with their game clock) the state of the clients game prediction is reconciled with the server's one (the only source of truth).
You can find a very interesting introduction article about the topic here.
Notice also that some protocols, like UDP, are by far more suitable than other for multiplayer realtime data exchange.

Related

How to make a multiplayer javascript game cheat proof whilst considering server load

to learn some more and new techniques I've started building a little game. The idea is to keep expanding it and adding new things. It is a nice way for me to experiment and try out new techniques whilst also having something to play with.
Right now I have a base standing that works quite well. It is fully build in Vue.js. However right now everything is being handled client side. In the future I would like to use websockets to turn this into a multiplayer game. I get that it would be less than ideal to have the clients handle everything because cheating would be very easy to do. I was wondering what the best way to counter this would be. My game is somewhat like space invaders. A lot of enemies spawn and you have to shoot them.
Initially I thought of having all the game logic on a server and just have the client render things as the server dictates it to do. But how would this turn out with a high load? If 10000 players are playing at the same time this would mean an enormous amount of requests per second to the server. This would heavily impact the performance of the game I think.
What are the best practices when it comes to this? I would like to keep things as cheat proof as possible whilst also keeping a high load and well functioning game in mind. I have read that some games just use some form of obfuscation as to how a score is calculated but since mine is quite simple it seems that obfuscating it would not really work. I have included a screenshot of the current game to give you an idea of what I'm talking about.
You are the ship, the enemies are the yellow dots and spawn at the top. When they hit the bottom row you lose a life. When you lose 3 it is game over. My problem is that with many of these games running at the same time keeping track of all these enemies would become extremely difficult as there will be lots.
With kind regards.
First, TCP is not the way to go if you plan to have thousands of user to keep in sync, you have to go with UDP that is a far better protocol than TCP when dealing with multiplayer.
Second, you are right, the game engine must run also on the server and the server engine clock has to be ahead of players engine clock (maybe 200/500ms) in order to validate and forecast user input.
Then when you receive an input you can validate both the input at the time it was fired (your engine has already passed that gametime) and check the condition on the next 200/500ms making possible to reconcile the client state as needed.
Multiplayer data prevision and sync is hard take a look at the already available implementations like this or articles about this particular topic as this
Note: you'll find more help posting in https://gamedev.stackexchange.com/

Inner workings of browser based real-time MMO games

So, suppose there was a game which consisted of a website, and a client that you can launch from said website. I've looked a bit and a relatable example would be Habbo Hotel.
What I'm asking is, what are all the different parts that would make such a game work: for the website part, I'd imagine a server, a database, and some HTML, CSS and PhP coding would be required, but how would the client side operate?
More specifically, how would the client-to-server (and vice versa) real-time communications happen?
Suppose the client be coded in C, how would the integration of C into a (I suppose PhP-framed) browser window be executed?
Note that the client is never downloaded on the user's PC, so where would it reside?
I'm sorry if these are a lot of questions, if the answers were to be too tedious to compose, feel free to just leave some documentation or tutorials (which I've looked for but haven't really been able to find), I'll happily read them on my own. Thanks in advance.
On one side your question is too broad but on the other side I can give you some pointers of how to do this in a modern way:
don't have a client, just a page in a browser
use HTML5 canvas, you may also want to look into SPA (single page application)
connect via websocket, there are HTML5 javascript implementations and PHP or node.js for the server-side
best is, use node.js on the server, PHP would be way too cumbersome
via websocket, send and receive JSON objects
host node.js on its native platform (Linux)
you may want to look into phaser as an HTML5 client-side canvas rendering framework, but it lacks many functionality and is mainly oriented towards twitch-based action games, which don't work well with this architecture because of lag
this will lead you to one conclusion: javascript is at the center of this system. you'll encounter several roadblocks, such as:
security on websockets with SSL for login
avoid SSL for real-time data (above 1 Hz)
UI on the client inside the canvas is not easy to implement, you'll have to re-invent the wheel or find a UI library for that
expect lag, the network code will take some 20%-30% overhead in respect to native C/C# code using TCP/IP or UDP (Lidgren?) and protobuf (Lidgren+protobuf) is what high-frequency AAA titles use (MMORPG or FPS alike)
From the questions you asked I sense a great lack of understanding and knowledge about the field. I guess you'll have to study some 6-12+ months beforehand. This is what I recommend, because if you start right away you'll make a lot of errors and waste your time. If above are any names you don't know about, search them and study them well. And don't start to code, there is a very steep learning curve ahead of you!
EDIT: more about server-side
If you want to implement an action-based interactive game (like an FPS or 2D shooter) I have to tell you this.
You may want to look into Unity 3D, using directly TCP/IP connections and binary messages (no HTTP, no websocket, instead protobuf).
C# (client-side) and node.js (server-side) are a good combination. For horizontal scaling you may want to look into cloud computing, docker, provisioning and a lot of server security.
But this is hostile terrain, it leads you into DevOps territory, which is way off game development. More like an architect's job. Imagine that 3-tier system (client + server + database) has a bottleneck on the server.
You want to spawn more nodes to handle more clients. This is what EVERY lobby-based game does (LoL, Overwatch, WoT, WoW instances, and so on) and what you do for partitioned maps (e.G. the "maps" in LOTRO, RIFT, many more MMORPGS). Also, to mirror (which means multiple instances of the same map to accomodate an overpopulated crowd).
To have this kind of horizontal scaling your servers must go online/offline on their own without you clicking around on command and control (e.G. puppet and similar software).
While this is the ultimate approach, it also has the most steep learning curve, especially because of security (advert DDOS, flooding, slow-loris, fake clients, and the list goes on). A new node must be "provisioned" on the fly (e.G. cloud-config) before it attaches to the cluster and goes online, so there's a whole new world of pain and learning.
The center-piece of such an elastic cloud-based server system is SSO (single sign-on).

What is the best way I can scale my nodejs app?

The basics
Right now a few of my friends and I are trying to develope a browser game made in nodejs. It's a multiplayer top-down shooter, and most of both the client-side and server-side code is in javascript. We have a good general direction that we'd like to go in, and we're having a lot of fun developing the game. One of our goals when making this game was to make it as hard as possible to cheat. Do do that, we have all of the game logic handled server-side. The client only sends their input the the server via web socket, and the server updates the client (also web socket) with what is happening in the game. Here's the start of our problem.
All of the server side math is getting pretty hefty, and we're finding that we need to scale in some way to handle anything more than 10 players (we want to be able to host many more). At first we had figured that we could just scale vertically as we needed to, but since nodejs is single threaded, is can only take advantage of one core. This means that getting a beefier server won't help that problem. Our only solution is to scale horizontally.
Why we're asking here
We haven't been able to find any good examples of how to scale out a nodejs game. Our use case is pretty particular, and while we've done our best to do this by ourselves, we could really benefit from outside opinions and advice
Details
We've already put a LOT of thought into how to solve this problem. We've been working on it for over a week. Here's what we have put together so far:
Four types of servers
We're splitting tasks into 4 different 'types' of servers. Each one will have a specific task it completes.
The proxy server
The proxy server would sit at the front of the entire stack, and be the only server directly accessible from the internet (there could potentially be more of these). It would have haproxy on it, and it would route all connections to the web servers. We chose haproxy because of its rich feature set, reliability, and nearly unbeatable speed.
The web server
The web server would receive the web-requests, and serve all web-pages. They would also handle lobby creation/management and game creation/management. To do this, they would tell the game servers what lobbies it has, what users are in that lobby, and info about the game they're going to play. The web servers would then update the game servers about user input, and the game server would update the web servers (who would then update the clients) of what's happening in the game. The web servers would use TCP sockets to communicate with the game servers about any type of management, and they would use UDP sockets when communicating about game updates. This would all be done with nodejs.
The game server
The game server would handle all the game math and variable updates about the game. The game servers also communicate with the db servers to record cool stats about players in game. This would be done with nodejs.
The db server
The db server would host the database. This part actually turned out to be the easiest since we found rethinkdb, the coolest db ever. This scales easily, and oddly enough, turned out to be the easiest part of scaling our application.
Some other details
If you're having trouble getting your head around our whole getup, look at this, it's a semi-accurate chart of how we think we'll scale.
If you're just curious, or think it might be helpful to look at our game, it's currently hosted in it's un-scaled state here.
Some things we don't want
We don't want to use the cluster module of nodejs. It isn't stable (said here), and it doesn't scale to other servers, only other processors. We'd like to just take the leap to horizontal scaling.
Our question, summed up
We hope we're going in the right direction, and we've done our homework, but we're not certain. We could certainly take a few tips on how to do this the right way.
Thanks
I realize that this is a pretty long question, and making a well thought out answer will not be easy, but I would really appreciate it.
Thanks!!
Following my spontaneous thoughts on your case:
Multicore usage
node.js can scale with multiple cores as well. How, you can read for example here (or just think about it: You have one thread/process running on one core, what do you need to use multiple cores? Multiple threads or multiple processes. Push work from main thread to other threads or processes and you are done).
I personally would say it is childish to develop an application, which does not make use of multiple cores. If you make use of some background processes, ok, but if you until now only do work in the node.js main event loop, you should definitely invest some time to make the app scalable over cores.
Implementing something like IPC is not that easy by the way. You can do, but if your case is complicated maybe you are good to go with the cluster module. This is obviously not your favorite, but just because something is called "experimental" it does not mean it's trashy. Just give it a try, maybe you can even fix some bugs of the module on the way. It's most likely better to use some broadly used software for complex problems, than invent a new wheel.
You should also (if you do not already) think about (wise) usage of nextTick functionality. This allows the main event loop to pause some cpu intensive task and perform other work in the meanwhile. You can read about it for example here.
General thoughts on computations
You should definitely take a very close look at your algorithms of the game engine. You already noticed that this is your bottleneck right now and actually computations are the most critical part of mostly every game. Scaling does solve this problem in one way, but scaling introduces other problems. Also you cannot throw "scaling" as problem solver on everything and expect every problem to disappear.
Your best bet is to make your game code elegant and fast. Think about how to solve problems efficiently. If you cannot solve something in Javascript efficiently, but the problem can easily be extracted, why not write a little C component instead? This counts as a separate process as well, which reduces load on your main node.js event loop.
Proxy?
Personally I do not see the advantage of the proxy level right now. You do not seem to expect large amount of users, you therefore won't need to solve problems like CDN solves or whatever... it's okay to think about it, but I would not invest much time there right now.
Technically there is a high chance your webserver software provides proxy functionality anyway. So it is ok to have it on the paper, but I would not plan with dedicated hardware right now.
Epilogue
The rest seems more or less fine to me.
Little late to the game, but take a look here: http://goldfirestudios.com/blog/136/Horizontally-Scaling-Node.js-and-WebSockets-with-Redis
You did not mention anything to do with memory management. As you know, nodejs doesn't share its memory with other processes, so an in-memory database is a must if you want to scale. (Redis, Memcache, etc). You need to setup a publisher & subscriber event on each node to accept incoming requests from redis. This way, you can scale up x nilo amount of servers (infront of your HAProxy) and utilize the data piped from redis.
There is also this node addon: http://blog.varunajayasiri.com/shared-memory-with-nodejs That lets you share memory between processes, but only works under Linux. This will help if you don't want to send data across local processes all the time or have to deal with nodes ipc api.
You can also fork child processes within node for a new v8 isolate to help with expensive cpu bound tasks. For example, players can kill monsters and obtain quite a bit of loot within my action rpg game. I have a child process called LootGenerater, and basically whenever a player kills a monster it sends the game id, mob_id, and user_id to the process via the default IPC api .send. Once the child process receives it, it iterates over the large loot table and manages the items (stores to redis, or whatever) and pipes it back.
This helps free up the event loop greatly, and just one idea I can think of to help you scale. But most importantly you will want to use an in-memory database system and make sure your game code architecture is designed around whatever database system you use. Don't make the mistake I did by now having to re-write everything :)
Hope this helps!
Note: If you do decide to go with Memcache, you will need to utilize another pub/sub system.

Websockets faster than WebRTC?

I'm new in the WebRTC and Websockets world. I'm interested in making an 1 vs 1 web game.
The problematic is just : How to send simple variables (mainly numbers) from a client to the other client ?
I have a Node.js server with websockets (via socket.io).
So, for the clients, I have two solutions :
Using Websockets : The client 1 push the var to the server and the
server push the var to client 2. This solution allow me to easily adapt my application for many users in one game.
Using WebRTC : The offer and the answer are sended via the server with websockets. Then, the client 1 push the var to the client 2 via DataChannel (I don't need getUserData)
I prefer using WebRTC because it eases the work of the server, that allow him to manage more clients.
So I set up the two solutions to compare and, big surprise ! Websockets are highly faster than WebRTC !
My test is simple : just a cube rotating using Three.js, the first client make a little rotation at each frame (60 per second) and push the rotation result to the client 2. At the reception, the client 2 update the rotation and render.
With Websockets, the result is perfect but with WebRTC, the client 2 runs really slow, like 5 FPS.
Is that the problem is the way I'm doing it ? Is it normal ?
I'm working on localhost, on Firefox.
The problem is with WebRTC. The WebRTC DataChannel implementation on Chrome (probably the same goes for firefox) is limited to around 30 kbps. I don't know the reason why? Something about not flooding the internet. There is a hack to circumvent this limitation - manually changing the "B=" filed in the SDP before setting it.
However... WebRTC is p2p UNRELIABLE communication. This means that you have to take extra care to ensuring that no messages are lost and the two players observe the same events and environment. I would go with websockets just because they are so much easier, understood and supported. If the game goes viral I would consider WebRTC as a possible optimization.
However if you are doing this game just for fun then you will learn a lot of useful stuff if you choose WebRTC.
If you want to see an example how webrtc is used in real projects take a look at:
http://viblast.com/demo
NB! After the introduction of SCTP-based data channels at around the Chrome 31-32 time there is no bandwidth throttling any longer and there is a new mode of operation which allows for reliable data channels.

Strategy Game Server Concept

I´m planning to create a WebGL-based, realtime strategy game, where players are able to play together. I´ll use Node.js to create the game server, and websockets for realtime connections.
I´ve broken my mind about what would be the best concept to synchronize the clients.
One possibility would be to send only the orders of the users (moving units, building buildings etc.) to the server, which sends them to all other clients. But here, I have the problem of the delay. I think that the games would get async this way.
Another possibility would be to calulate the game on the server. The clients still send the instructions to the server, but the server sends now all changed states of all units&buildings to the clients in a high interval. The problem is here the high amount of data and how fast this can be...
Do you have some other ideas or improvement proposals?
Thanks!
Basically you have to decide between speed vs security.
Letting the client do the job and the calculations is faster but the data is at risk because the client can manipulate the data.
On the other side, having the server do all the job is slower but the data is more secure.
You could opt for a dual approach, decide to let the client calculate only some data, synchronize and then check for its validity, and let the rest being executed on the server.
It also depends on how fast the game runs, the amount of data to calculate, the speed of the server and band/connections, etc...
You should prototype both methods and try some tests to emulate the client and servers load.
If the game is small I would opt for a more server-side work. On the other hand, for a much complex game probably sharing more work to the client is best. Anyway I think a tradeoff is always needed.
Here are a few links you may find useful
Multiplayer Game Programming Introduction
Real time strategy networking
Multiplayer Programming thread (old but still with many useful links)
Lag Compensation
Prevent Multiplayer Cheating
The first link has helped me a lot back in the days and imho is still one of the best resources avaiable on the subject.
Books
Multiplayer Game Programming
I would suggest to watch these resources regarding browser based game development concepts:
Multiplayer Gaming with HTML5: Are We Ready?
Realtime HTML5 Multiplayer Games with Node.js
HTML5 Games 0.3: Seeing the Future
Unfortunately I have no experiences in WebGL based online games, but usually it is a good approach to let the game logic be executed on the client side, and synchronize the results.
In this approach it is important to keep track of what game object is "owned" by what client. Clients only send updates (creation, update, deleteion) from their own objects and receive the updates of the other game objects from the other clients.
Additionally you can set up a messaging framework to deliver additional messages like "Player has entered/left" or something like that.
This concept has proven useful for a game I created, and I hope it is as useful to you.
You should have the game state and logic on the server, otherwise your game is wide open to cheating. The server is the ultimate authority the game state.
Not sure about WebGL, but to my understanding following approach will be good.
Initialize all objects (which are common across players) on server and run them
On client start, it will request all renderer (related to specific client) for the objects running on server.
client will render the objects on UI for all recieved renderer.
When client make any update on UI, changes will be notified to server, and server will update the object accordingly
When objects common between players are modified by one player, each player (client) will be notified to make UI changes.
This approach will be specific to common objects not UI / client specific objects.
For security reasons, all the logic should be on servers side, and all the data update is on server.
But the client is able to predict some logic and play animation first, which is called client prediction.
The server side is in charge of verify the client logic, if there is no cheating, all done.
If there is someone cheating, the server can tell the client to go back to right state.
If you are using node.js for server, there is an open source framework , pomelo .
And there is also a full source code demo and online demo for it: lordofpomelo

Categories