Jump to content

running multiple game instances on nodejs


gerardAlbin
 Share

Recommended Posts

Server does some collision detection,  game logic and handles input from clients.

Nothing too heavy but I can imagine it could start getting slow if there's a lot of game instances.

setInterval(() => {

    for (let game in games) {
      games[game].run();
    }

}, 1000/30);

Is there any way I can distribute the load to more cores, or because of it's single threaded nature, nodejs was a bad decision for this particular game architecture?

 

Edited by gerardAlbin
Link to comment
Share on other sites

With NodeJS there are several ways to benefit from multiple cores, or other process distribution.  My preference is usually "PM2".  Then within your application design you will need to engineer how each instance defines and manages its own responsibilities - e.g. which games it is managing, what happens if that instance fails, and so on.

https://pm2.keymetrics.io/

You may also wish to reconsider using setInterval as a reliable thresholded tick?  An alternative might be to loop faster than desired, measure the cumulative deltaTime within the loop, and if greater than the minimum tick then run the respective game updates (passing the deltaTime forwards), and resetting the cumulative deltaTime.  Additional checks for unacceptably slow deltaTimes can trigger other strategies - such as passing responsibilities to other instances, or spinning up more instances etc.

Many challenges lay ahead in this topic - enjoy the journey!

Link to comment
Share on other sites

28 minutes ago, gerardAlbin said:

Im not sure what you mean by using setInterval as a reliable thresholded tick. 

From the NodeJS documentation:

Quote

The only guarantee is that the timeout will not execute sooner than the declared timeout interval.

That is, setInterval can only "try" to call in the prescribed time.  If it's blocked, then the time elapsed will overrun.  Game updates can be heavy and so can easily create blocking scenarios, even at 30 FPS.

I don't want to provide code because I'm not yet sure I like the use of setInterval for this purpose?  I'd instead suggest reading this and properly exploring all the options:

https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/

Plus getting a good understanding of delta-time (in respect to game updates) will be a valuable foundation:

https://en.wikipedia.org/wiki/Delta_timing

 

Link to comment
Share on other sites

Thank you, I learned a lot about event loop timers.

I forgot to mention my game uses socket io so I couldn't get PM2 to work as it should.

I'm going implement the cluster module manually, but there's a couple of issues.

Im trying to make a proxy server on the top of the node workers so when a client connects to the server, the proxy server makes a decision on which worker the client should be routed.

I want to redirect the client to the node instance for which some conditions exist. Like for example if the client wants to join a room search all node instances and connect to the instance the first free room is found or if the client wants to make a room, redirect him to the instance which has the least rooms. I have no idea how to make a proxy server though, is this even a good idea?

 

 

Edited by gerardAlbin
Link to comment
Share on other sites

On 11/11/2019 at 6:54 PM, gerardAlbin said:

Im trying to make a proxy server on the top of the node workers so when a client connects to the server, the proxy server makes a decision on which worker the client should be routed.

Yes, told you it was going to be fun :)

This is getting a bit out of my comfort zone ... our approach was using Nginx as the load balancer (with sticky sessions).  PM2 approach works fine with this - with each NodeJS application instance running the service on a sequential port and sharing data between them with either a DB or Redis.  The Nginx maps inbound requests to each server via internal-IP, and each instance via the port.  So let's say 2 servers x 4 core = 8 instances with 8 ports.  New user comes to IP:80, Nginx routes them to one of those 8, and remembers which one (so that Websockets can persist).  Nginx configuration determines whether inbounds are round-robined or more elaborately determined - it's doing all the smart stuff automagically.

It's certainly been solved before, so it's a matter of implementation rather than invention.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...