Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm working on a realtime multiplayer game using Django and gevent-socketio, I'm facing some issues:

I need to send an update of the game state to connected players every X seconds (~4 seconds), so basically I need to execute a function every x seconds which does some calculations and sends the connected players the new game state. What is the easiest way to achieve this? is using cron a good choice here or should I look for other tools like celery or ...?

Also, the function needs to operate on some data. querying the database every time the function is executed does not seems to be a good idea, where can I store the game data (which is updated frequently during the game)?

share|improve this question
    
Unless x is a multiple of 60, standard cron doesn't cut it. There are workarounds 1 2. Additionally, please ask different questions in different posts. Asking two questions in the same post can lead to one answer answering the first question, another answering the second question - both right, but neither answering it all. –  MichaelT Apr 10 '13 at 4:33
    
there was an answer here on a infinite loop. not sure why that was deleted. if you want game state to be updated very often (you said ~4 seconds in your post) then a loop with sleep might be a good idea. need to make sure the loop does not end no matter what exception occurs (in java have done that with a try-catch-throwable) in python will have to see how to do it –  tgkprog Apr 10 '13 at 6:12
    
instead of 4 seconds you will have to take in to account how long it takes peak number of users to get game state updates or how their local version will react if state is stale for a few (in case few have slow internet). and then arrive at a value for game refresh. But arnt there open src multiplayer games whose code you can go thru? –  tgkprog Apr 10 '13 at 6:14
    
@tgkprog: The documentation for time.sleep explicitly warns that it can sleep for arbitrarily longer or shorter than the user requested. In most programming languages, using sleep as a means of handling event timing is a bad idea. That is not the problem sleep is designed to solve. –  Brian Apr 10 '13 at 6:18
    
yes but that will only happen if there are other processes running that are hogging all CPU. if you are making a game server then you need to ensure there is enough CPU for the game. maybe this is not the best solution and need to see code of a few open source games? en.wikipedia.org/wiki/List_of_open-source_video_games –  tgkprog Apr 10 '13 at 6:26
add comment

4 Answers

Regarding your first question:
If the type of game allows it, I would advice a round-robin strategy. You send the game state in equal intervals you obtain by dividing the maximum time between updates by the number of players that are connected, and send the state as a series of updates to the single connected players.
Like that you avoid performance issues due to CPU spikes, as mentioned in some of the comments to @Kolyunya's answer.

As an aside this strategy allows the following optimisation:
Adapting the maximum time between updates to the number of players that are connected at a given time:
If the number of players is low you can set the maximum update time low as well, so the few players can have faster updates.

For the implementation I second @Brian's tip to see if this strategy suits your needs.

Regarding your second question:
You should keep your game state in memory, redis would be a obvious choice.

share|improve this answer
    
this post is rather hard to read (wall of text). Would you mind editing it into a better shape? –  gnat Aug 24 '13 at 13:52
1  
thanks @gnat, it should be more readable now. –  kr1 Aug 24 '13 at 21:38
add comment

The general language independent idea is to have some kind of a 'Timer' and 'GameStateSender' objects which are connected using an observer pattern. Timer sends events every x seconds and sender listens for these events and sends data upon recieving them.

*Implementation should be discussed on SO

share|improve this answer
    
Polling in this fashion will spike CPU, degrading overall system performance. This performance problem cannot be resolved via sleep, as sleep is too unpredictable to be trusted in this fashion. –  Brian Apr 10 '13 at 6:05
    
@brian I've created a socket server for a realtime game this way and it works just perfectly. Why don't you post your solution? –  Kolyunya Apr 10 '13 at 6:17
    
Perhaps your server is under very low load? You can often get away with coding like this, though it may introduce some form of gameplay jitter if your server experiences heavy load. The simplest approach would probably be to just use a timer or scheduler object (e.g., stackoverflow.com/a/2399145/18192 ) –  Brian Apr 10 '13 at 6:28
1  
@Brian: where did you read "polling" in this answer? "Listening" does not imply "polling". –  Doc Brown Apr 10 '13 at 11:25
    
@doc I first suggested a concrete implementation but after that generalised the answer to match site context. –  Kolyunya Apr 10 '13 at 11:42
add comment

What i would recommend you to use PUSH Technology .. for example 'long polling' connections. What happens in these connections that the client give a request with always keep alive and server receives it.

Now client keeps waiting for the response and on server side , server waits for any actions , as soon as server receives actions , it responds to the client request and as soon as client receives response from server , it again request the server as this goes in a loop .

So in this technique you dont have to send request on some particular time and there will be no lagging also.

Use frameworks like : Twisted

share|improve this answer
add comment

Regarding #2: querying and updating a database for every change of game state is an extremely good idea, as long as you're using a right database.

Obviously things like MySQL can be subpotimal in such cases (or maybe not; it depends on the size of the game state and the complexity of your model). If you use a low-overhead NoSQL database that only stores things to disk when it has time, you'll have plenty of performance. Durability will suffer, though; a crash might lose the state.

Of course, it's silly to recompute the entire game state for each client request, if the state did not change. You can cache the hard-to-compute common part and only recompute client-dependent parts, like 'fog of war'.

This leads us to the idea of a tiered database. Your most important things, like users' inventory or monetary balance, should be stored in a durable database, like Postrges or MongoDB. (BTW it's amazing what modern Postgres is capable of, and how fast writes to Mongo can be.) The often-changing things, like fog of war, positions of missiles in flight, etc, should live in a caching layer, something like Redis or Memcached, and only be stored to the durable store when an irreversible action happens (missile hits). The most important facts about the current game tick should be computed once and stored in the caching layer, in a form that allows easy queries and immediate sending to clients.

The state of the caching layer can be lost to a crash without catastrophic consequences, and can be recomputed from the durable data.

This is, of course, somehow complex. Don't go for it until you have a working crude prototype. Use only the durable store (e.g. Postgres) until you start hitting performance problems and have identified these problems to be database-related. Then you will see what to cache.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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