Ticks/Timed Events/Crons etc

April 3, 2007 at 12:09 pm (browser based, game development, internet, PBBG, scripting, web game)

This post is going to be sweet and simple. When you design a game, say you want to give a player 5 more energy every 15 minutes or that you want to give them a ‘tick’, turn, round whatever every 3 minutes.

Well for this you would use a cron job. A cron job is pretty simple. You simply need to write a script that is constantly checking the time and running it against a equation or database or something. After you have the script written, this is the trickiest part: Ensuring that your server supports crons. It will state somewhere in the describe whether they are supported. Most web hosts don’t support them and that is why you need a server.

Anyways, what the cron on the server does is allow you to set how you want your script ran. So I can set it to run every minute, every 5 minutes or every 10 minutes.

And here’s a tip*

* When getting a server and you need say 5 crons and the server you’re looking at say it only supports one, don’t worry! What you do is turn you crons into functions and put them all in one script that runs, say every minute. This way you still have all your crons running without managing 3 or 4 or even 5 separately.

Now, I have a question for all the scripters out there: What other ways do you have for doing ticks/events, whatever? I would be interested in seeing what other ways a cron can be simulated/done.

Advertisements

55 Comments

  1. Cameron said,

    One could use a simple JavaScript timer or AJAX call to fire the server side CRON or serious of functions.

    I think this may depend on what your purpose for having the cron job is to begin with. For instance, to refresh player stats a simple AJAX call could do the trick, if you want to move mobiles around then you probably do want something that is handled on the server.

    In .NET one could initialize a timer in the application start event and have that handle mobiles movement, etc. The only problem there is that if the application stops, which it can in IIS 6, then your timer stops. Of course if players are actively using your site your application won’t shutdown but it is still something to be aware of.

  2. bardicknowledge said,

    Thanks for the input Cameron. I figured the glorious AJAX would make an apperance here. I’m actually just going to start teaching myself JavaScript. Hopefully in about a month or two I will be able to start using AJAX in my scripts.

    I don’t know a whole lot about .NET so I have a question or two for ya. You have a timer start when you start the program (the game). So say every 5 minutes I give players new energy. Using this timer would one have to have a call on every page calling the function(timer) on the server?
    And if that is the case, and your server supported crons, what would be the advantage?

    How would this timer run? I don’t have a lot of experience with servers either. From my understanding, my files sit on the server waiting to be called. When they are called they are ran and the info is set to the client. How would this timer run all the time? For a large game where you get several hits every minute I can understand, but for smaller games that only get hits every 4 or 5 minutes, wouldn’t this pose a problem?

    I’m not trying to target/bash your idea, just trying to make it clear for myself and anyone else that reads… if anyone else does πŸ˜›

    Again thanks for the input. I really do enjoy reading your comments since I know you have a wealth of knowledge I can only dream of attaining.

  3. Cameron said,

    CRON is not available on Windows, unless someone wrote some type of CRON service, it is a UNIX/LINUX thing. You can run the Windows scheduler but hosted environments won’t allow that.

    I wouldn’t use a timer to update individual player stats, I would have the page make an async AJAX call to do that. I would use a Timer to update NPC movements, weather, etc. All the timer would do would be update the database so when I new request was made the information would be up to date. Having a global function update all players stats would be a bit of overkill and put unneeded load on the server.

    Even with a CRON job you still have to make a call in to the server, the server can not push information out to the clients without a request. That is where an AJAX call would be more effective.

    In .NET a web application is started the first time a user requests a page, in which time a Timer would start that executes on a background thread. The application runs as long as players continue to connect to the server, on older IIS installs it continues to run regardless. The application stores values in server memory and continues to receive tick events from the Timer.

    As for AJAX, any type of quick call to the server would work. I know some guys wrote a push/pull type of application using JavaScript that was kind of like an AJAX call but I can’t remember what they called it. πŸ™‚

    In my opinion it is better for the client to make calls that pertain to the individual player rather than putting that responsibility on the server. The server will still process that request but at least it can do them one at a time instead of trying to manage everyone’s information at once. However, if there are world related activities that need to take place, having a CRON or Timer would be a huge benefit.

  4. bardicknowledge said,

    Crons are avialable now on a windows server through your CMS. Not all CMS’s support them, but the newer ones are starting to from my understanding.

    When I say update players stats , I mean every player in the database. And while it calls the server everytime you have the cron set to run, wouldn’t you’d have to call the timer to do database updates everytime a player clicked to check if that time has passed?

    If not how is the timer function called?

    I don’t know enough AJAX.. I don’t have a clue what it can/can’t do yet.

    Whats the difference between AJAX making a call and using ASP or PHP to make the call?

  5. blueleaf said,

    So is it pretty standard to use Crons for PBBG games? Thinking about a game but I’m really stuck on how to implement turns in it.

  6. bardicknowledge said,

    If you’re using PHP its the only way I know how to do it πŸ˜› As Cameron explained with ASP you have a timer event.

    Hey Cameron, if ya read this, how would you like to write a quick tut on timers in ASP so I can post it on here? I plan to write a tutorial on crons in php eventually when work calms down.

  7. Cameron said,

    I can write something up. Timers run on background threads so they won’t need to be called but one time when the application starts. From there the timer will raise an event at set intervals and your application can subscribe to that event and then perform whatever process you have in mind.

    You could do a postback with PHP but an AJAX call would allow you to perform a postback without a refresh of the entire page. The same thing could be managed using iFrames but the AJAX is a little cleaner and easier to maintain.

    AJAX basically allows you to use javascript to make an asynchronous call to your web server and receive xml, html or JSON data from the server. You can have a div basically update itself rather than have the full page postback and reload in the browser.

    I’ll have to look into the CRON thing for Windows.

  8. mike from bbg talk said,

    You could do the following:

    Write your code into a PHP file, and if on a linux server with SSH access, use a shell file to run that php file, and sleep for x seconds.

    Or you could use fake crons like vbulletin forums do, where every time a visitor comes to the forums it checks the times and fires the cronjob script if it needs to be ran. No need to use AJAX at all.

    Mike

  9. Pensador said,

    I was talking to a colleague of mine about a way of calculating “action points” in a game without using a script that runs at periods of time, which seems to be inefficient.

    I thought I could have a timestamp telling when the user account was created. From it, the number of available action points is calculated. A counter would keep track of how many were spent. This function would be called only when the user logs in; this way we avoid having to calculate the action points of the entire population at same time.

    Maybe this design can be also applied to turns.

    Any comments?

  10. bardicknowledge said,

    Hey Pensador,
    I have played with a similar idea myself.I would have two functions myself. One would be to update your player when you logged in and a second to update any player you come in contact with.

    But say that I gain 5 health or points or turns or whatever everyone five minutes and I’m logged in for 15. I don’t get my updated points since it was meant to only update on log in. This now means I need to call that function every time I refresh the page.

    Now, would that call to the db be more work (for the server) than one big call? I really don’t know. I don’t claim to be a db expert but I think it would be if you had a large population.

    I suppose if you knew javascript a lot better than I do, you could have a timer that is passed between pages, but then you have the issue of people hacking your timer since javascript is pretty easy to get around.

    But back to using a timestamp idea. Say to have a cap on how many points you ‘pool’. Then that equation wouldn’t take that into account. So if I am to gain 1 point every 5 minutes and I can have a max of 20 points after almost 2 hours my ‘pool’ would be full…
    Of course if you don’t have a pool and don’t expect players to remain logged into for an extend period of time waiting for turns or points, it would work.

    This is a very interesting topic I think and has a multitude of different possibilities. I will find out about the little or big database call though. My boss is a db freak so I imagine he will be able to tell me if I ever have a chance to get him away from his PC.

  11. Tominator said,

    Hi,

    What are the people with ajax talking about anyway? I believe the question in the article was: how does the server database update itself periodically? Not: how does the screen of the user show the values? Because to get the values, who cares if it’s ajax or meta refresh, the values have to get in the DB first.
    I’m wondering myself too if cron is the answer, or to just update right before the user refreshes the page with the stats.
    On the one hand, you could update right before, but what if you’re in a game where attacks can be sent and they arrive (for example) an hour after sending. After the hour, the attacker hopes to receive 50% of the resources of the victim. Then the game had better give 50% of the current resources and not 50% of the amount the user had the last time they refreshed the page.
    On the other hand, this isn’t easily cronnable either, because the job would have to run every second to check all attacks i guess.

    Linux users will recognise the “at” and the “cron” command in the options above. Neither seems really feasible with a game running lots of attacks, or are they?

  12. bardicknowledge said,

    Hey Tominator,

    Why would the cron have to run every second? Once an hour is enough. And here is my reasoning:

    We have a strat game where I gain 100 credits an hour or whatever. Everyone has their ‘tick’ (cron runs) every hour on the hour. So that way even if you are not around you can still be gaining credits from the cron and anyone that attacks you will be able to take your current amount and not the last time you logged on.

    After the attack your’s and the attackers stats in the DB are updated through a function within the attack function. This way your stats are always up to date even if you haven’t logged on in several hours.

    Another way would be in the attack function have another function that checks your last log in and compares it to the current time and updates your (the defenders) stats. This way would eliminate the cron.

    You could also have it when anyone looks at your account (in a list or through your profile) that your account is updated. This could potentially led to more db traffic though then having the cron.

  13. Tominator said,

    Hi bardicknowledge,

    In the game i proposed, you don’t really need the hourly cron to update the resources/credits/turns, if you update them right before any action happens (user views, attacks happen). I think in your game you get 100 credits every hour, in my game you get them continuously at a slow rate.

    What you do need is a way to act out the attack after the hour (or random time really) is over. I don’t know if you can do this with the ‘update before view’ method, or if you need the ‘at’ program in unix.

  14. Ranger Sheck said,

    I use a couple cron jobs – one is for healing characters who are “inactive” (in my game, you have a party and if you want to rest characters, they have to be swapped out of the party) – so every 5 minutes, a script throws this at mysql:

    UPDATE characters SET health = (health + 1)
    WHERE (player_party_id IS NULL AND health

  15. sunchaser said,

    I use a very economic hosting that does not give me crontabs. I solved the problem using webcron (up to three tasks it’s free).

    However I would prefer to have direct control on my crontabs. I have seen an implementation with php, in a table called Timers every player had an entry, and there was a php crontab task that was checking the end timestamp of every player entry. This need of course, that the player to refresh the page.

    Pity I do not know Ajax, I will start to look at it.

    — Sunchaser

  16. Hatch said,

    I’ve been looking for a way to do timed events in a Browser game myself. Cron jobs won’t really work, since as far as I can tell they can only be set to run once a minute on the minute.

    What I’d like to do would be similar to how things are done in Travian, where everything occurs at specific times. So an attack may happen in 1 hour, 3 minutes, 22 seconds, or an upgrade may occur in 23 minutes, 44 seconds. I know they use an event queue, but I’m not sure how they implement it.

    I would assume that you would have to have some type of backend server software written that would continuously check to see if an “event” needed to be handled. So it might be possible to store future events in the database and have them processed at a specific time. I’m unsure how to implement it right now and there doesn’t seem to be much out on the web concerning this, since most browser games are not designed to function this way.

    Anyone have any thoughts on how to implement a backend event handler like this?

  17. Fernando said,

    If you are using Microsoft SQLServer, you can schedule jobs in the SQL Enterprise Manager. This way you don’t need cron, but you need MS SQLServer πŸ™‚

    In MySQL 5.1, there is an “Event scheduler” that allows you to create events to run at specified intervals like:
    CREATE EVENT update_health
    ON SCHEDULE
    EVERY 1 HOUR
    DO
    UPDATE characters SET health = (health + 1) WHERE health < max_health

  18. bardicknowledge said,

    Thanks for that tip mate! That very well be useful in the future ^^

  19. Hatch said,

    Fernando! Thanks so much for your reply. I knew there had to be some simple way to do it, but couldn’t figure out the right search term to Google it with. I owe you a beer.

  20. Cameron said,

    Some hosts won’t allow MS SQL jobs to run, they either don’t enable SQL Agent or your account will not have permission. This is a problem I have, I am not able to schedule MS SQL jobs so I am forced to reply on other means to execute jobs.

  21. bardicknowledge said,

    I’m thinking of ditching crons all together. The more I look at my game and how crons work the less and less I want to use them.

    I plan on soon writing a post on what I plan on doing from now on instead of crons. As in next week, since I will be gone all weekend.

  22. jmucchiello said,

    No, no, no. Don’t do anything until someone observes it.

    For stuff like ticks/moves/healing you don’t use a cron job. You just store a field on the user account saying when their ticks were last set. The next time they hit the website, you subtract that value from the current time and multiply/divide by your interval. So if datetime in the database says 1:05 am and it is now 1:55am and your tick rate is 5 per hour (or 1 per 720 seconds), you subtract now from last and get 50 minutes (3000 seconds). Divide and you get 4 ticks with a remainer of 120 seconds. Now you update their account record with 4 more ticks and set the last update time to now – 120 seconds.

    Same thing with health. The player is at 3 health and doesn’t login for 3 days but 12 hours after he logged out another player attacked him. Update his health while processing the other player’s turn then handle the combat. If the first player survives, 2.5 days later he’ll read about in his logs and at that same time, you’ll have updated his health again only once.

    Basically, nothing needs to happen in your game until someone observes it. If I don’t login for 10 days, you shouldn’t waste your processor time giving me game moves every 5 minutes.

  23. Hatch said,

    jmucchiello,

    This only true of some game designs. Other designs need things to happen when they are scheduled to happen.

    For example, if your unit is moving from one square to another, and you want to see if it encounters an enemy when it enters a new square or when it enters a destination square, that needs to happen right then. This is different from how most browser games operate, but could make for some interesting changes.

  24. jmucchiello said,

    If you can see it, then you are hitting a URL. When you do, the game updates to current time. If you don’t refresh (or an AJAX agent doesn’t refresh), then there is no witness and thus there is no one to see if something is or is not encountered.

    Now, there could be problems deciding whose unit need updating. This is why in a game like Travian, you can’t see units moving. It’s because they aren’t moving. Their destination and a time of arrival are fixed when you click ok to send them. If neither you nor you target log in for 2 days, the result of their attack is unresolved until one of you does (or until a third party interacts with you or the opponent’s cities).

    Tell me why things need to happen “on time” if there are no witnesses. If no game agent interacts with a specific game object, it’s status is irrelevant. It sits in your database until someone does need to know what it’s doing.

    Back to your example, in order to encounter an enemy, your units must occupy the same square. So the movement table in such a game would store all the squares the unit expects to traverse and the time when it will get there and leave there. So when the unit is deploy, you plot its path and expected arrival times and populate the movement table.

    When the user logs in again later, you can generate a report that says Unit X spots calvery of nation Y at 34,-23 at 4:33 am.

    This may require a sweep function that cleans the table. (Cleaning the table is ugly, you check each entry and ask, are any units who also passed this square at the same time still unreported? If not, delete the row.) But that can run any time. It doesn’t require strict periodic timing.

  25. Xalthorn said,

    One project I did a while ago was a game helper for a popular online game. Although it wasn’t the same as a game in itself (processing the game mechanics) it was doing a similar enough task to warrant mentioning.

    The project provided a front end to the game, mainly for world mapping and tactical battle planning, although it also showed the user (if they wanted) the status of their territories and what resources and troops were where.

    I knew that I would need to grab a huge amount of data by grabbing url’s of the game and processing the page to read out the bits I needed. Initially, this was done in one huge daily process, but I wanted something more responsive to deal with territory conquests and changes in troop levels throughout the day.

    I didn’t have access to cron to do the updates of the map or the territories, so I took another approach which I nicknamed trickle updates.

    Every time someone viewed *any* page in the interface, it would perform two trickle updates. One would be their personal data (if they wanted), the second would be the global map data.

    A trickle update would simply keep a pointer to the next item to check, and when run, check that item, store the data, and move the pointer on.

    In the case of the world map (which was dynamically changing with islands disappearing and new islands appearing under certain conditions), it was a simple grid system. The world was split into a grid of maps, each map was then split into sectors, and each sector had cells that would either be empty or contain an island territory.

    All the trickle system did in this case was to grab a whole sector display, process the islands that were there, update the database, and then set the pointer to the next sector, rolling over to the next map (or back to the first) accordingly.

    The personal data system would grab a list of the territories owned, and the pointer would be set to the last territory checked. The pointer would move to the next territory owned and the data for that territory would be processed for resources and troops, and the data stored in the database.

    All of this was subtle enough to not cause too much delay in the page loading. For someone with 30 territories, after logging in and viewing 30 pages (account, map, tactical tools, island data, whatever) their entire account would be updated.

    The map would take longer, but with lots of people using the system, it didn’t take too long. I also had an option to grab more than one sector if I wanted to speed that up a bit.

    The tool was mainly used by tactical players who wanted to look at a proper graphical world map with public island details available when they hovered over them. They could also colour code the islands according to their own conditions (player name, alliance name, island score, etc).

    However, it doesn’t scale *down* well, as with fewer players, the whole global data takes longer. However, with a decent player population, it gives a nice subtle global update system and the principle can be applied to updating events in an event queue if needed.

    It was certainly the system I was going to play with for my ‘tick’ based wargame that is currently on the back burner.

  26. jmucchiello said,

    Your trickle system could work alongside my system. It would make sure the system didn’t fall so far behind that people experienced timeouts during their page loads.

    And the trickle system could self throttling. As the number of outstanding needed requests rises, you do more requests per page load. As the number falls, you reduce down to 1 trickle request per page load.

  27. Hatch said,

    Let me try again to explain an idea of a movement system I’m toying with:

    The unit is moving from one square on the map to another square that is 5 squares away. It is Travian style movement in that it takes real time to get there. Let’s say that it’s moving at 1 square/hour, so we’ve got 5 hours. If it wasn’t possible to interact in the intervening squares then I agree your method would be just fine.

    However, what I left out before is that I want it to be possible for things to happen to the unit as it moves through the intervening squares. Other units can have Enemy Lists and Support Lists. If our unit moves into the next square and another unit is sitting there that has the player on their enemy list, then a combat would be initiated. If a third unit had our player on his Support list, then it would also join in the combat on our unit’s side. If our unit survived the combat, it would then proceed on it’s original course, minus some time for the combat to have occurred. It could even be moving slower after the combat if the units were starships and their engines were damaged.

    I think it would be very complicated to use your method in this example. This is a great conversation however, and I look forward to your comments.

  28. Hatch said,

    Also, your Travian example has one flaw. An attack report is generated immediately that is available for everyone in your alliance and the other player’s alliance to view. I’m pretty sure they don’t “delay” the results in Travian until someone views them.

  29. jmucchiello said,

    An alliance member is just another observer.

    If my attack on your village arrives at 1:40 and a 3rd party sends two scout groups into the village arriving at 1:39 and 1:49. If he refreshes his browser at 1:44, his scouts are advanced to 1:44, the system doing this sees the scouts have a 1:39 event and it executes the event. Your village is brought up to 1:39 setting your mine totals to what they should be at 1:39, the report is generated at placed in his mailbox “at” 1:39. If he checks again at 1:50, the village is advanced to 1:40, the attack I sent gets generated, the village is again advanced to 1:49 and the scouting report is generated “at” 1:49.

    That said, contrary to what I may have implied, Travian most likely does use cron jobs. That’s why you get those ?:??:?? things during high load. But I think the purpose of the cron job is to avoid letting the “observer” queue getting too long. After all, attacks are happening every second. There’s no way to schedule an every second cron job.

    Going back to the original topic though. Resources, health, etc. These kinds of “running counts” work perfectly using calc-on-observation rules. After 100 users, your system would crawl to a stop if it had to update player 1’s corn at 5/minute, player 2’s rice at 66/minute, player 3’s …. using cron jobs.

  30. Hatch said,

    Cron jobs can’t be scheduled down to the second, so it wouldn’t be possible to even do running counts like Travian does using Cron jobs. I think the minimum interval on a Cron job is 1 minute on the minute.

    I think the idea of calculating resources only when they are “observed” is a great idea to reduce server load, though. The only issue I might see with it is that it would allow resources to be produced even when the server was down, which may or may not cause problems. I guess it could even be a “feature.”

    “Look! Even though the server was down for 6 hours, you still had your resources produced.”

  31. jmucchiello said,

    You’re “catch up” code has to make allowances for server downtime. This is just one of many complexities involved in calc-on-observation.

    Using the calc-on-observation method is extremely complex. But that complexity is in the fiddley details. It is not computationally complex nor is it extra time consuming. But it does require thinking about your database design differently because updating just 1 village might entail updating 20 villages and 45 combat units.

    One way to handle “time travel” is to not store absolute dates in the database. Use seconds since game start instead. One of you master variables becomes the offset needed to convert that number to a real time (generally unix_time() – server_start = your_epoch). To make 6 hours disappear, just move “server_start” forward 6 hours before bringing the server back up.

  32. Kahey Seiben said,

    Hi everyone!

    I’ve seen a lot of BBG’s and come up with some ideas of my own for which I’ve completed the initial ‘planning’ stages (ie: theme development, presentation design, stc) and currently in the ‘code development’ stage.

    Wow! What a learning curve for a boilermaker!

    I’ve been reading about BBG construction in numerous forums and come up against ever more numerous conflicting opinions regarding what scripting language/database type, timed event controls, server types, graphical plug-ins, etc provide the best methods.

    Now I know I’ve started this post out a little off topic however I’ll get back to the point now…lol.

    Many different methods of setting up timed events have been discussed here (and a lot of other places) already and it’s a bit overwhelming for for the uninitiated (myself for instance) to read thru such a long thread and come to a profitable conclusion.
    To this end would it be possible for you guys to contribute to a common article (with a clearly defined structure) which explains and demonstrates each of the above methods of timed event control?
    The benefits of such an article would be that the reader would then be able to compare methods side-by-side to decide which is most appropriate to their application.
    Additionally the wealth of experience already demonstrated and shared by the authors here would passively tutor others like myself…lol!

    Thankyou in advance for your time and efforts,

    (presumptuously) Kahey πŸ˜‰

  33. afifio said,

    Just found the gold in BBG dev πŸ™‚

    Nice job everyone, here are my comments…it all depends on the game play. I haven’t code yet, still developing ‘game plan’, have one in mind that resemble Travian but seems quite complex in terms of timing and map making/unit movement.

    On to timer thing…in comparison to Travian.
    AJAX based updating – Totally NO NO NO on everything except updating data display, cosmetic, non game mechanic like user sessions.

    Viewed/access php type cron – Thought about it but..if no one login for 1 hour, the game play screwed/miscalc. Might work for simple game update.

    Cron – Great! but still can’t do like travian :(, can’t do seconds, server down = user penalty, cpu intensive for realtime game.

    MySQL Event (thanks Fernando) – Good for background update like tick, resource, points but terrible at user generated action (attack, moving to another space), however still can be used to do those things.

    Ticks calculations – Same like MySQL event but can do user generated action. Bad side is cron like – cpu/database intensive.

    The best answer is combination of above (minus AJAX).
    Why compare to Travian – Because it felt like realtime. So users “stuck” – update, play, check, repeat. Honestly, a well designed BBG but can be much more improve.

  34. bardicknowledge said,

    Hey all,

    @Kahey, That is a great idea and I will start my own part of that post tonight or tomorrow after the one I am working on now.

    @afifio If you could please explain what you mean by AJAX timer that would be great. Because from what I seen while I played Travian is that the timer on your page isn’t the timer actually updating the database. It’s just a Javascript timer that takes the complete time from a row in the DB and subtracts the current time from it for your count down. If you had it update the database everytime it ticked, travian simply wouldn’t run.

    Crons: If you have 5k players and you want to update their info every 10 minutes, your server is going to die. It’s just an inefficient way of doing it.

    The way that is the best that I can think off, is the update and view. I will be writing an article about this tonight or tomorrow. With a database that meets 2nd normal form this would work well.

    The biggest part of this doesn’t rely on your code, but your database structure. A well organized database would be able to handle ‘view updates’ fairly easily compared to crons.

    But as I said, I will go into more detail with one of my upcoming posts.

  35. The ‘tick’ « OpenBracket said,

    […] topic of debate among developers. I, for one was confused about how to appoarch this when I first posted about it. But after reading comments made by people smarter than me, and learning more about […]

  36. Hatch said,

    I did some more research on the Event Scheduler in MySQL and I don’t think it’s going to be as useful for what I want to do with it as I thought.

    If an event is scheduled for say 12:00 AM and the server goes down at 11:59 PM and comes back up 5 minutes later, the event scheduled at 12:00 AM never gets fired. It’s lost.

    For now I’m going to redesign my potential game to operate only on the Observed Updates model.

  37. jmucchiello said,

    Glad you found out sooner rather than later. The scheduler was going to cause you a lot of troubles in the long run.

  38. Bob Tabor said,

    Awesome discussion … I’ve been wracking my brain how to solve this elegantly. The Observed Updates model outlined by “jmucchiello” is beautiful and what I was leaning towards before I found this post, but there’s one problem that I can’t get past. Hopefully I can articulate this:

    1) You are producing MyResource at a rate of 60 per hour.

    2) You level up your MyResource production facility, which will give you 80 units per hour. BUT it will take 20 minutes to complete the upgrade.

    3) You come back one hour later … you would expect that the first 20 minutes produced at a rate of 60 per hour, while the last 40 minutes produced at a rate of 80 per hour.

    Cool — do-able — but from a database design perspective, where do you keep all that info?

    You need two records (or bits of data or whatever) — the old production rate, and the new production rate, as well as what time they each where in effect.

    Once a “user” attmempts to observe the new inventory amount, you would then need to 1) use the algorithm to determine how much MyResource was generated in the time that elapsed, 2) update the current inventory with the additional MyResources, and 3) delete the old production rate record. THEN you can return the new number back to the “user” who’s observing.

    Just seems a bit … kludgey … am I headed down the right path with this line of thinking? Is there a better “pattern” for this?

  39. jmucchiello said,

    Each resource object has 2 pieces of data (in addition to stuff like owner, location, etc):
    The update rate.
    The last time a full unit was produced.

    Likewise there is a global event queue for stuff like “John’s Iron Mine in VillageZ finishes level 3 at epoch + xyz seconds”

    So, when John logs in we go through his list of resources. It is now epoch + 500 seconds. John’s iron mine has an update rate of 16/minute, last updated at epoch + 400. We then look for any events in the queue that affect John.

    We find the iron mine levels up at epoch + 450 and Steve attacks John at epoch + 520. Steve’s attack will not affect any thing this second so we handle everything up to epoch + 450.

    16/60 * 50 = 13.3333333. Increment iron resources by 13 and move the last update to 400 + 13 * 60 / 16 = 448.

    Now we change his iron mine to level 3 and set the iron resource to 18/minute.

    18/60 * 52 (500-448) = 15.6 Increment iron by 15 resource and move last update to 448 + 15 * 60 / 18 = 498.

    A dumb algorithm would also calculate wood and stone production twice: once up to epoch + 450 and once up to epoch + 500. A smart algorithm realizes that they aren’t affected by the listed event.

    Of course when John click again at epoch + 530, you need to do all the calculations for the whole village up to the attack time of epoch+520. Then resolve the attack to see if Steve makes off with some loot. Then you need to advance the village to epoch+530 in the wake of the attack.

    Yeah, that’s a lot of calculations for such a simple thing. That’s one reason most PBBGs have lots of small screens with few data elements that you have to click and click and click to navigate.

  40. Ven said,

    Hey guys, this is just the type of discussion I was looking for. Before I saw this, I was planning on going with cron jobs, because I thought that would work okay. I am doubting it now.

    I will probably work toward the user event driven model, where it doesn’t refresh until a user needs that data. It is more complex, but it seems like the the gain will be worth it. I think I am beginning to understand what this might involve as far as coding and setting up the database goes, but I have a few concerns.

    First, it isn’t a problem to update a user’s resources/whatever when they grow at a certain fixed amount, but I am wondering about events that will be put in a queue. I’m not sure how this would be implemented. I really don’t have much experience with databases, and I’m wondering if it would be better to have a table for each separate user that would be their own little event queue, where every time you are about to update their resources/units you first check the queue to see if anything happened to them (like attacks). However, a global event queue was mentioned above. Is the performance of querying something like that acceptable? If you have lots of users, that queue could be very big. I don’t have enough experience to say whether querying a large table for one user’s id is better or worse than creating a lot of separate tables for everyone.

    Also, do you guys have any thoughts on chat servers in these types of games? I was thinking of doing an AJAX chat server, but that really involves a lot of extra queries from the client to the server, and I’d like to avoid that. It seems like you can use a technology called Comet to push data out to the user when an update is received, which might be feasible. It would also be possible to host a chat server on a separate server than the game server. It just seems like having a chat server with lots of users is going to create a lot of extra queries or transfers either way.

    Also, what about a low priority process that sits in the background, continually looping over all the players and updating their information. This way nothing gets too out of date. I’m not sure if this really serves a point other than maybe making it easier to generate a ranking of all the players.

    I’m also concerned about security in these games. I don’t want it to be easily hackable or anything. I don’t know much about SQL injection or cross-site scripting or anything like that, so I guess I’ll have to learn, but any general tips? I guess this is sort of off the topic of this discussion.

    Guess that’s all for now, thanks for the discussion!

  41. jmucchiello said,

    Asking for tips on SQL injection and cross site scripting is like asking for tips on heart surgery. There are lots of little things you can be told in a “tip” but without a foundation (7 years of medical school for the surgery analogy) the tip isn’t as useful. General tips are the only thing available. Like, don’t trust any data that comes from outside the source code.

    Working backwards…. Most database have shorter limits on the number of tables than the size of tables. If you have 10,000+ users, that’s a lot of tables. Each table creates overhead in the SQL engine. I suspect you would bring your server instance to its knees with that many (or more!!) tables. Like the cron idea, I don’t think it scales well. Database developers expect and are always improving performance of big tables.

  42. Xalthorn said,

    The main thing to be aware of for security is that you can’t trust any information passed by the browser. Some bright spark will always try and break your site by throwing data you weren’t expecting in there.

    SQL injection is one of the most shouted about security issues and a quick Google search should yield a whole bunch of pages talking about it.

    I would recommend making some small tables that follow the structure of what you’re aiming for and popping some test data in them. Write some routines that do the tasks you want and then try to be your worst possible user and see what happens if you throw sql commands in the data entry fields.

    One thing I do is include a security script at the top of all my scripts which sanitises any data passed in forms, stripping out HTML or SQL commands, converting them to escaped characters. That way, even if the data is passed to a query, it’s relatively safe.

    Another thing to be aware of is the danger of using parameters in the URL (http://mysite.com/myscript.php?param1=ooh&param2=itbroke for example).

    If you use this method of linking, you really need to expect people to change the values and see what they get. This is a more common and more visible way for people to ‘hack’ your site.

    Be especially careful if you control access by placing some sort of login or session ID in the url. People will start putting in random values hoping to catch someone else’s account.

    InselKampf was open to this and it took a lot of shouting at the game owner to get him to fix it.

    Also, don’t trust .htaccess to make specific pages in your site only accessible (linked from) other pages in your site. The referrer can be faked really easily.

    Also also, don’t assume that a form you create won’t be faked, modified and sent to your site by some idiot, don’t take forms on their face value, only read the data you are expecting to see (don’t just loop through the form array picking up values).

    Also also also, please please please, initialise all your variables at the start of the script. It’s both good coding practice and stops people overriding them with faked global variables.

    We’re probably all going to be a bit vague about this subject because, as jmucchiello says, it’s a huge subject that has different implications depending on how your site works.

    Hmm, I still have a tendency to waffle…

  43. jmucchiello said,

    And all those things are just the n00b mistakes. There are many more subtle mistakes to be made. Notice though that the main point here is trust no data you didn’t type into the source file yourself.

    That said, there is no real danger in URL parameters since they are no less secure than form variables. They just take less sophistication to fake. But since you don’t trust any data you didn’t type into your source file, you’ll verify that the currently logged in user can access the objects the parameters refer to, right?

    I disagree with quoting data at the start of the script. You should only quote data in one place, just before it goes to the database. Sanitizing data at the start is fine, but making the data database ready should be the responsibility of your database layer. (You are coding in layers/modules, right?) Basically, when you are manipulating the data, you should be manipulating the data as it is meaningful. If it is quoted, you have be careful not to break the quotes while you are manipulating it. And those bugs can be hard to track down.

  44. Xalthorn said,

    When I talk about initialising variables at the start of the script, I mean setting their initial values so that you’re not leaving yourself open to someone passing them in a form or url and thereby having them override what you’re expecting because of the register_globals setting.

    I know it’s bad practice to have this turned on and by default it is now turned off. However, if you have no control over the installation of PHP, it may be turned on and you wouldn’t know.

    This opens your code up to a nasty security issue and can also cause you a troubleshooting headache as you try to work out how a variable is being set when you weren’t expecting it, especially if you are using isset().

    I mention it as another door to close with regards to security issues. If you are initialising your local variables at the start of each script/function, then you *know* that they are behaving as your code expects.

    For example, let’s look at the following code:

    if (authenticated_user() ) {
    $authorised=true;
    }

    if ($authorised) {
    // do some secret stuff
    }

    The problem with this is that if you have register_globals on and some bright spark sets the $authorised variable in a url or form, whether your authenticated_user() function decides that they are authorised or not is irrelevant.

    If we changed the code to:

    $authorised=false;

    if (authenticated_user() ) {
    $authorised=true;
    }

    if ($authorised) {
    // do some secret stuff
    }

    I know I could have done that with an ‘else’ instead, but there may be times when you want to clear down or initialise more than one variable.

  45. jmucchiello said,

    Of course, there’s nothing wrong with your advice. But, in addition, find a new host provider if you can’t turn off register_globals. There are some settings that are deal breakers when you are setting up a public server.

  46. Xalthorn said,

    Hehe, yeah there is always that solution.

    Either way, I think we’re agreed that it is something to be aware of, no matter how you resolve the problem.

  47. bardicknowledge said,

    That is some sound advice. I’m far from a PHP pro, so this may sound a little stupid, but how would they spoof your authentication? I also have no experience in hacking forms whatsoever.

    So I just the register_variable doc… So if it’s on I can try to use a get method to set vars? If thats the case, wtf!

  48. jmucchiello said,

    Register_globals is PHP setting. When it is set true (the default value in all versions of PHP before version 5), every $_GET, $_POST and $_COOKIE variable is made into a regular variable. So a url like: http://www.example.com/index.php?userid=1 causes $superuser to equal 1 when the script starts. If for some reason you say:

    if ($userid==1) { special_access_stuf(); }

    without setting the variable yourself, anyone can spoof being userid 1 just by setting values on the url.

    It was a “time saving” idea very poorly thought out.

  49. bardicknowledge said,

    That is just a horrible idea.
    I agree with your easiler advice.. Get a new host.

  50. Xalthorn said,

    Not that I don’t trust hosts, but….

    I think I’d opt for both solutions. Find a host that has register globals turned off, but also make sure my code is safe just in case the host turns it on to appease another hosted site.

    Paranoid? Moi? You betcha!

  51. jmucchiello said,

    It’s not paranoia when there are people out to get you. Coding anything for the Internet means any flaws in your code, any flaws in your supporting software (databases, web server, etc), any flaws in your OS will be exploited.

    Compounding the issue by not coding defensively will get you 0wn3d.

  52. jmucchiello said,

    I was playing the-crusades.org (a travian/tribal wars/ogame style game) and noticed they definitely use the “until player notices it” event method. In fact, they go so far as to only update each CASTLE when someone notices it. At the moment I have 6 castles. If I set them all to build something and come back to the game after they all finish. My score goes up 6 times, once for each castle I examine in turn.

    I bet that saves the server a lot of cycles per page hit.

  53. Raghavan said,

    I need ot simulate a timer in php for my site.Can anyone give me a code how to develop a cron job please??
    I am waiting for any reply.Or any other ideas? Any articles about this in web? i could not find any useful things for this one? help please!

  54. Building Browsergames » Blog Archive » Using the “on-view” method instead of cron said,

  55. pbbg said,

    pbbgs are the future of work procrastination πŸ˜€

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s

%d bloggers like this: