Our Scripts Vault contains many game scripts that you can use to create your own game!
Example: you click "build tower" which has time of 3 hours. A db row is inserting with a timestamp of "now + 3hrs".
On every page request, a check is made: are any scheduled event *in the past*? If so, *retroactively* execute the action associated with each (example: update tower status to "construction complete")
Quote from: nano on November 10, 2009, 11:47:06 PMOn every page request, a check is made: are any scheduled event *in the past*? If so, *retroactively* execute the action associated with each (example: update tower status to "construction complete")You'll need to lock the table for reading (an SQL transaction) when you do this check, otherwise you might do things twice if two people load pages at the same time.
A note: from my experience, and to my surprise, load balancing of such "cronish" actions is irrelevant, it won't bog down your server, lags comes from active players.
You'll need to lock the table for reading (an SQL transaction) when you do this check, otherwise you might do things twice if two people load pages at the same time.
ChrisWhat do you mean by "virtual" cron?
Out of common ones ... InnoDB is not that slower than MyISAM from what I've been reading recently + Codestryke advocates row-locking engines which would be very beneficial for per-player updates
For per-player you don't need locking of any kind. Player can trigger only his own part of the table "WHERE id=$playerid" It is extremely unlikely for *one* player to click so fast (using different tabs) as to trigger the code twice.
The route I would take to develop something like this would be to actually create my own service daemon. The service would auto run upon the systems boot sequence (after mySQL of course). Being lazy and wanting to get it to just work right away I would simply create a PHP script that would poll the database, get the next timestamp and then issue a sleep command until that time. The PHP script itself would always run in the background.
I have to disagree a bit on the "per-player" locking. This might be the case with some games but other games allow one player to update a different player's record. Thus, you have a potential condition that would conflict.For example: Player A is attacked by Player B at Coord 0,0 and defeated. The system must track that Player A now has 0 units in Coord 0,0. Thus, Player B triggered an update to a row based on Player A. But, perhaps at the same moment, Player A issued a move command to move their units to Coord 1,0. The attack likely took a moment to resolve so Player B would be granted a victory, yet Player A would retain their units because they're no longer located in Coord 0,0.There's some obvious ways around this one, but it's only meant as a quick example.
I beg to differ on this point. We've had and still have players that run multiple tabs / windows on the games. One player can have multiple writes to his/her account almost simultaneously either by being to fast or trying to piggy back requests (an absurdly easy way to cheat on an unprotected system).I've stated before Chris' players must be the most honest player's on the web because he's never seems to have these types of problems, we on the other hand don't have this luxury Wink
Interesting approach. But what if there are new events added into the DB after the daemon goes to sleep? If those new events have timestamps that are before the wakeup time of the daemon, they will never be executed.