1

I'm currently working on a browser game with a PHP backend that needs to perform certain checks at specific, changing points in the future. Cron jobs don't really cut it for me as I need precision at the level of seconds. Here's some background information:

  • The game is multiplayer and turn-based
  • On creation of a game room the game creator can specify the maximum amount of time taken per action (30 seconds - 24 hours)

Once a player performs an action, they should only have the specified amount of time to perform the next, or the turn goes to the player next in line.

For obvious reasons I can't just keep track of time through Javascript, as this would be far too easy to manipulate. I also can't schedule a cron job every minute as it may be up to 30 seconds late.

What would be the most efficient way to tackle this problem? I can't imagine querying a database every second would be very server-friendly, but it is the direction I am currently leaning towards[1].

Any help or feedback would be much appreciated!

[1]:

  • A user makes a move
  • A PHP function is called that sets 'switchTurnTime' in the MySQL table's game row to 'TIMESTAMP'
  • A PHP script that is always running in the background queries the table for any games where the 'switchTurnTime' has passed, switches the turn and resets the time.
putvande
  • 15,068
  • 3
  • 34
  • 50
Senshi
  • 27
  • 6
  • so many people using php, the wrong language, to make games, anyway a php daemon comes to mind –  Aug 15 '13 at 22:42
  • What about Cron jobs. – putvande Aug 15 '13 at 22:54
  • @Dragon Heh, I chose PHP since it'll be readily available no matter where I'll end up hosting it. =) A daemon sounds good; are you thinking of using it along the lines of what I posted at my [1], or something else entirely? The whole web thing is still pretty new territory for me. – Senshi Aug 15 '13 at 22:58
  • 1
    @putvande Seriously? Did you even read my question? – Senshi Aug 15 '13 at 22:58
  • And you have a dedicated machine because shared hosts normally wont support mysql events its a some kind of deamon in the database it self and you can only update mysql tables with it.. – Raymond Nijland Aug 15 '13 at 23:20
  • @RaymondN I'm not sure I follow; are you saying shared hosts don't fully support MySQL? – Senshi Aug 15 '13 at 23:31
  • shared webhosts normally don't support MySQL "events" it some kind of cronjob in the MySQL database. Thats way i asked you if have a dedicated server or not. – Raymond Nijland Aug 16 '13 at 12:49

2 Answers2

0

You can always use a queue or daemon. This only works if you have shell access to the server.

https://stackoverflow.com/a/858924/890975

Every time you need an action to occur at a specific time, add it to a queue with a delay. I've used beanstalkd with varying levels of success.

You have lots of options this way. Here's two examples with 6 second intervals:

  • Use a cron job every minute to add 10 jobs, each with a delay of 6 seconds
  • Write a simple PHP script that runs in the background (daemon) to adds an a new job to the queue every 6 seconds
Community
  • 1
  • 1
jtv4k
  • 224
  • 2
  • 7
  • Once I have a daemon though, wouldn't a job scheduler become unnescesary as I could just call the PHP function directly? Or am I missing something? – Senshi Aug 15 '13 at 23:18
  • Sure. Job queues make things easy to manage, but it's definitely an additional level (and sometimes unnecessary) of complexity. Here's a quick Google search on creating daemons: http://kvz.io/blog/2009/01/09/create-daemons-in-php/ – jtv4k Aug 15 '13 at 23:20
  • Alright, gotcha. I'll wait a while to see if any other answers pop up, but if not this is probably the route I'll take and I'll accept your answer. Thanks. =) – Senshi Aug 15 '13 at 23:32
0

I'm going with the following approach for now, since it seems to be the easiest to implement and test, as well as deploy on different kinds of servers/ hosting, while still acting reliably.

  • Set up a cron job to run a PHP script every minute.
  • Within that script, first do a query to find candidates that will have their endtime within this minute.
  • Start a while-loop, that runs until 59 seconds have passed.
  • Inside this loop, check the remianing time for each candidate.
  • If teh time limit has passed, do another query on that specific candidate to ensure the endtime hasn't changed.
  • If it has, re-add it to the candidates queue as nescessary. If not, act accordingly (in my case: switch the turn to the next player).

Hope this will help somebody in the future, cheers!

Senshi
  • 27
  • 6