3

I am working on a multiplayer collectible card game. Server side is node.js + websocket.io. I am now considering which database to implement.

I got really intrigued by MongoDB, mostly due to the fact that I can exchange JSON between DB and my application and also because I can describe entire game state in one mongodb document. It is also supposed to read and write faster.

However, I have come across the views that MongoDB is not that great in terms of performance when it comes to updating existing records.

In my game this is a key feature, as game state would change all the time (with every player's turn).

One of the solutions I have been thinking is actually pulling current game state document, conducting all calculations necessary and then simply creating a new document in MongoDB for the same game. Effectively, I do not update an existing record, but create a new state instance which I will pull later. And this repeats onwards.

I wonder how justified such approach is and what is best practical way to implement this? I will somehow need to find the most recent document in collection filtering by gameID and then somehow utilising a document timestamp. Is there any built in functionality in MongoDB which could help me, any hints on what to explore are much appreciated!

4

The document storage model does match your requirement as you wont need to look at more than one record at a time.

However! I would question whether you need storage at all. If you can send the entire game state from the client with each 'move' you could do away with the data layer entirely and your backend would be very scaleable.

  • +Ewan I guess I need some storage to handle disconnects/reconnects and get latest known state for a player from a trusted source rather than the client. – Vadimster Oct 9 '17 at 19:29
  • You could have the client resend and maybe have the other client compare and validate the game state it receives. The cost savings could be substantial – Ewan Oct 9 '17 at 19:32
3

Your plan seems to be to abuse Mongo DB. Mongo DB is a database. Its purpose is to persist data, not to act as central memory (which is your current plan).

For what you are describing, you should be using Redis. It is a great tool for inter-process memory and communication, which is what you are doing.

The store the state of the current game in Redis, then once the game has concluded, remove it from Redis and store it in Mongo DB.

  • you will run out of memory before you run out of disk space – Ewan Oct 9 '17 at 19:04
  • @Ewan what's your point? You can't use disk as main memory. Well, you can, kind of, but don't expect much throughput. If it's a problem, when a game has not been accessed in a bit, it can be swapped to mongo, then swapped back to redis when modification is needed again. – TheCatWhisperer Oct 9 '17 at 19:30
  • exactly, you need the database backing, and all the in play games will be accessed with the same frequency. theres no benefit in caching them – Ewan Oct 9 '17 at 19:35
  • Why do you say need? At a certain point, you need a certain amount of memory; that is inescapable. Database backing is one possible way of reducing memory requirements, but does not seem necessary. Why would thousands of game instances not fit in a 1gb redis instance? Also, with the DB backing strategy, you don't need to back every modification to the DB, one per request would be sufficient after modifications are done in Redis. – TheCatWhisperer Oct 9 '17 at 19:46
  • with a db you need 1 games worth of memory to run as many games as you like. with redis you have a hard limit on the number of active games. an expensive, low limit. It doesnt help at all in this situation – Ewan Oct 9 '17 at 19:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.