4
\$\begingroup\$

I'm trying to create a browser-based game (made in PHP, MySQL, Js, HTML, and CSS) that is heavily dependent on user's actions being carried out after a certain amount of time passed whether online or offline. Will running cron jobs every second/minute a good practice or a solution to my problem?

Please check out this question first before answering, I ask this new question to focus more on the pros and cons of using cron jobs. To be more specific, here's a list of the things that I want to know:

  1. Scalability? Up to what extent?

  2. Performance? How fast? How slow?

  3. Server Overhead? Will a normal server be able to accommodate the load?

Assuming the game will be an MMO.

I appreciate all the help people! Thanks in advance!

\$\endgroup\$
3
\$\begingroup\$

If you're smart with it, it won't be too resource intensive - but I definitely wouldn't try to run it every second (plus the shortest time interval for a cron is 1 minute). Because you mention actions occurring for a user when offline, a cron is probably your only option for that.

For online actions, I recommend not having that in a cron, that way you can do actions on a per user basis, immediately, rather than batched in a cron.

If you're not already set on PHP as the backend, you should take a look into node.js combined with Websockets or socket.io - it will allow you to keep a persistent connection, so if you want something to happen after a minute you can just use setTimeout. Based on what the other question states, that sounds like it'd be the best option for what you're trying to do.

Alternatively (again based on your other question, you could use setTimeout on the client side, and pass the info to the server to call the action. Of course, you should verify on the server that the correct amount of time has passed. This won't work if the user goes offline before the timeout callback is called (if you really wanted to, the cron could be a fallback for this scenario).

\$\endgroup\$
6
\$\begingroup\$

I know your question is specifically asking about cron jobs, but I think a lot of web-based mmos are written using "completeTime" logic as opposed to lots of crons.

When you start a long-running action, like building a granary that takes 5 hours to complete. The server will just mark the granary's completion time as start time + 5 hours and store that in the database, that's it. The client will see constant progress if they stay online, but that's only simulated on the client side. If the client logs out and back in before the 5 hours is up, when they connect, the server will tell the client when the granary is expected to be complete, and the client continues the simulation with no further server interaction. If the client logs back in and the granary should have been completed days ago, on connect, the server looks at the date and figures this out and not only completes the granary on the spot, but provides the user with the ability of the granary (let's say +2 food/hour) for all the time the user has been away for with the simple calculation:

foodToAdd = (currentTime - granaryCompletionTime) * 2 food / hour

For other actions that may affect other users (eg: building an army), updates can be executed when the affected parties do something that may require the army to be there. Everything should be able to break down in to rates, and rates can be multiplied by the amount of time that has passed.

I can't think of a case where cron jobs are necessary, other than automated backups. This also effectively removes inactive players from being processed unless they are interacted with.

Battle example:
Start a 3-day training session and you log out
An enemy attacks you, but the army takes 2 hours to arrive (use the same completeTime logic), then the enemy logs out

--- Time passes with no login, Nothing happens on the server

You log in a few days later and a re-calc occurs for your empire (as it does every log in)
The server figures out that you were attacked and brings both your army and the enemy army from their last update time to the battle time, making any necessary adjustments (like for training or whatever)
Resolve conflict
Continue with normal operations and pass on simulation data to client

Notice how the server doesn't do anything about the battle until someone (you) logs in. I'm pretty sure Travian uses a system similar to this, although there's no way to be sure.

\$\endgroup\$
  • 1
    \$\begingroup\$ I've actually already thought of that, and yes, in some parts of my game, I'll use that "complete time" logic you're talking about. But there is this certain part of my game where user 1 can make changes to a specific area. User 2 may enter that area and see the changes made after the completion of the user 1's action. In this case, there is no action that directly involves user 1 & 2. This action is more of a user 1 to area 1 interaction. Using the "complete time" logic, the user 2 will not be able to see the effect made by user 1 until the he logs back in. \$\endgroup\$ – user31246 Jun 24 '13 at 16:53
  • \$\begingroup\$ A logic that checks the area of any actions currently in queue made by "who knows who" every time a user enters that area don't seem like a good solution for me. That's why I'm considering cron jobs. \$\endgroup\$ – user31246 Jun 24 '13 at 16:58
  • \$\begingroup\$ User 1's changes to the area would need to be attached to the area, and when anyone comes to look at it, the area would need to be updated. \$\endgroup\$ – John McDonald Jun 24 '13 at 17:17
  • \$\begingroup\$ I had a related conversation with someone last night. Here is the conversation. I'm frequently in chat if you want to discuss. \$\endgroup\$ – John McDonald Jun 24 '13 at 17:45
1
\$\begingroup\$

There are pros and cons of a long-running daemon vs cron.

"Cron" will run your job every 1 minute (maximum). This carries some overhead of starting a new process, loading data files etc.

However, starting a new process will avoid memory leaks (because when the old process exits, it releases any leaked resources).

So there is a performance / robustness trade-off.

PHP is a poor language for writing a long-running daemon in due to its lack of "proper" garbage collection - certain objects, when created, cannot ever be freed (NB: It is possible that this has been partially solved since I last checked this).

In any case, if you use "cron", you should be careful that multiple instances of your processor can't run at once (hint: create an exclusive lock on a file you have open for writing; if it fails, there is another instance running). Some versions of "cron" do check if the previous instance is running but this is not completely reliable because instances may be run outside of cron.

\$\endgroup\$
0
\$\begingroup\$

Very interesting thinking :)

I did try to make a game using cron jobs because I didn't have the money to own my own server. And I was new to programming. But soon enough, I had a working game logic which was doing its thing every so often; the server data was processed and using php I was saving things to database and I had a table of jobs which the Server had to check for every minute. I also had htop open to check for resources being used, I was surprised that the cron jobs were using almost nothing to run, a mere 2-3% of cpu ...

So I decided to automate a browser script and run few hundred instances of the game, each instance doing something simple like move player to map x and kill x monsters, update the database with the new xp and new gold collected if any. (Funny I had to automate my own game , basically hacking it.)

I was surprised. The server didn't really go much higher than 10% with so many jobs to do it was still doing them all no problem at its set interval. Soon though I realized there was no point in completing the jobs per cron run, rather every time user makes a job do it as soon as the user made the job for the server. I was able to make the game look more live like feel like this was proper MMO with other players existing on the map with tiny delays. But Soon I realized I should go back to cron jobs. I mean the performance Went really high because players made requests more often to the server than cron jobs per day ... Literally everything a player did was immediately recorded to the database. So imagine how many requests were done .... It was like DDoS attacking from the inside. CPU was up the roof top and the free hosting company actually banned me from using my hosting account for a while because of too many requests.

So I went back to cron jobs and it felt less Online like but it worked like a charm. Of course If you have money and enough to get a vps or anything with socket support, highly recommending it because you only make initial handshake request and the rest of the game runs smoothly, and I mean it, seeing other players live moving next to you makes the game more interesting and players more happy.

However if you think you've an idea for a game that just needs to be updated every minute then go for cron jobs. They are not that resource hungry and they worked for me no problem! (Make a jobs list table and let it complete jobs in the joblist table.)

Good luck!

\$\endgroup\$
  • \$\begingroup\$ Hey, that Enter key on your keyboard won't bite :P Please use paragraphs as they make make the text much easier to read, and will contribute a great deal of you getting upvotes :) \$\endgroup\$ – Vaillancourt May 4 '17 at 0:52

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.