[web] How do Browser games implement 'tickers'?

Started by
39 comments, last by louissan 13 years ago
As opposed to a user not logging in for a week, and then having to calculate 10k updates? And that's not even taking into account any actions that impact other players..

Basically, calculating past steps on demand only becomes somewhat viable when players cant interact with each other at all. Once they can, you basically need to save the state of the game for all players at all steps in order to make sure interactions occur with the right data for each player.

Also, if you want to be able to notify users of things by email when they happen.. it's not terribly helpful to be emailed about your pet starving and dying only when you get around to logging in a couple days later.
Advertisement
Quote:Original post by DEbig3
And that's not even taking into account any actions that impact other players..


Quote:Original post by AverageMidget
If you allow interaction between users (as in a farm style game), and one of the users isn't logged in, I would just update their game if/when the other user interacts with it.


I agree with the e-mail feature, though.
Quote:Original post by sooner123
I've considered that option but I don't like it for a few reasons related to workload distribution.

What is the way this is usually done? Like say for large scale games like.. Farmville or Travian or any number of Browser based games with an updating world.


For a really large scale game i would write a dedicated server and treat it like any other multiplayer game. This pushes the complexity up to that level aswell though and pretty much requires that you use browser plugins(flash,java,silverlight or similar) for the client unless you're fine with only supporting modern browsers (Firefox4, Chrome4 or Safari5 basically)

a third option is to use a cron job or the windows task scheduler to run a script at a set interval, personally i'm not a big fan of this approach though since it greatly restricts your hosting options without really adding anything. (Hosts that allow you to mess with the scheduler tends to also allow you to run your own processes, which means you might aswell write a proper server)
[size="1"]I don't suffer from insanity, I'm enjoying every minute of it.
The voices in my head may not be real, but they have some good ideas!
Quote:Original post by AverageMidget
If I had to implement such a feature, I'd be in favor of what SimonForsman proposed. It seems unnecessary to have your server working away, when no one is playing. I assume, like the games you mentioned, you'll require some form of registration to play? I would imagine the standard practice would be to save the time the users game was last updated and, the next time they launched the game, calculate the number of updates that would've happened and perform them.

If you wanted to entertain an extreme example, say you have 1,000,000 users. If you updated every minute, you'd have to update all 1,000,000 users at once, even if there were only 2 users currently playing. If you had a lot of game state data, that could be hell on your server, and annoy for those 2 user. If you allow interaction between users (as in a farm style game), and one of the users isn't logged in, I would just update their game if/when the other user interacts with it.


Players interact with each other.

Fleets and armies are moving around in time. Training occurs in time.

It would be far too complex to only compute relevant changes when the user can see it as you'd have to build up some kind of map of all the interactions between the player, the player he's interacting with, all players that player has interacted with etc.

If it was a single player game I'd do it this way though.

As it is I'm leaning towards using curlpp.

I'm still wondering how this is normally done for large scale multi-user browser based games. I would assume it's not windows scheduler or cron since a lot of these games are based on remote hosts. I would imagine cgi would be the most common solution but I don't KNOW at all so I was hoping someone else would.

I think a c++ script with curlpp should work fine though if you guys don't see any other immediate better or more standard way.
Quote:Original post by sooner123
Quote:Original post by AverageMidget
If I had to implement such a feature, I'd be in favor of what SimonForsman proposed. It seems unnecessary to have your server working away, when no one is playing. I assume, like the games you mentioned, you'll require some form of registration to play? I would imagine the standard practice would be to save the time the users game was last updated and, the next time they launched the game, calculate the number of updates that would've happened and perform them.

If you wanted to entertain an extreme example, say you have 1,000,000 users. If you updated every minute, you'd have to update all 1,000,000 users at once, even if there were only 2 users currently playing. If you had a lot of game state data, that could be hell on your server, and annoy for those 2 user. If you allow interaction between users (as in a farm style game), and one of the users isn't logged in, I would just update their game if/when the other user interacts with it.


Players interact with each other.

Fleets and armies are moving around in time. Training occurs in time.

It would be far too complex to only compute relevant changes when the user can see it as you'd have to build up some kind of map of all the interactions between the player, the player he's interacting with, all players that player has interacted with etc.

If it was a single player game I'd do it this way though.

As it is I'm leaning towards using curlpp.

I'm still wondering how this is normally done for large scale multi-user browser based games. I would assume it's not windows scheduler or cron since a lot of these games are based on remote hosts. I would imagine cgi would be the most common solution but I don't KNOW at all so I was hoping someone else would.

I think a c++ script with curlpp should work fine though if you guys don't see any other immediate better or more standard way.


using curlpp to load the script from a c++ program is just insane, if you're able to run your own software on the server you can have it update the gamestate directly rather than go the long way through the webserver. (I'd also recommend having your own software handle the communication with the client in that situation since HTTP and HTML/XML overhead will kill your bandwidth for any large scale game)

What i suggested wasn't to only update for the player in question, but rather to update for everyone, So instead of running update.php once per minute using cron/windows scheduler or your own app using libcurl, you run the update script when a player tries to access the gamestate if it is time for an update. if the last update was at 22:00 and any user tries to access the game at 22:05:50 you run update.php 5 times before running the normal script (then it would set the last update time to 22:05 and the next update would run if a player is playing at or after 22:06), a simple table lock will avoid having multiple users cause extra updates to run and unless your game is completely empty for a very long period of time the backlog won't be a problem. (Unless your game is incredibly complex you should be able to run a few hundred updates per second on a modern server without any problems, at an update rate of once per minute a 24 hour backlog won't take more than a few seconds to work through and if you got that few users you'll have bigger problem than them having to wait a second or two extra to load the login screen)
[size="1"]I don't suffer from insanity, I'm enjoying every minute of it.
The voices in my head may not be real, but they have some good ideas!
You've got to be a LOT more specific to figure out how to make events 'tick' in a web environment. To take your main points:

Players interact with each other.

Spectacular! How? They fight and/or trade, I assume, from the army bit in the next sentence. Do you allow active/inactive fights? If so, all outcomes will be formulaic (pre-determined actions by inactive player). Your game logic will be something like ACTIVE_PLAYER attacks SUPERMAN, SUPERMAN not online (query updates for SUPERMAN, apply), SUPERMAN follows scripted battle.

Fleets and armies are moving around in time. Training occurs in time.

Probably nothing happens during transit/training, right? Or, if it does, those changes are effective after the movement/training? Then all changes can be applied when USER/PLANET/BASE/AREA is accessed after the end time.

It would be far too complex to only compute relevant changes when the user can see it as you'd have to build up some kind of map of all the interactions between the player, the player he's interacting with, all players that player has interacted with etc.

Why is it too complex? A user doesn't need to change AT ALL unless someone (the user himself or another player) accesses the user. When your battle/trade/display scripts access user data, they should confirm the data is timely (typically by including a LAST_ACCESSED field or separate, searchable update queue). You don't need to know (or care) what triggers your update method, you just need it to run prior to any interaction.

I would avoid lumping all your check update routines at login because you'll still want progress to roll forward while users are playing. Especially at the beginning of your dev cycle, no one will be signing in, meaning you'll never have updates while playing.

But really, what is happening EVERY minute? Interest on bank accounts? Auto-experience? Some sort of special power growing? Those are typical things (AFAIK) that can happen "constantly" in a game, but they are often not. Even some of the most complex growth patterns you can find (I did some crazy interest gains in Calc) can be figured in one step to adjust for time. Say you want them to gain 0.5% of their experience every minute and they don't login for exactly one week (10080 minutes). You just use a basic compound interest formula (assume 100 XP at logout 1 week ago - in the Wikipedia link, here n is 1): 100(1+.005)^10080 = 682185533694734340099690.06898055 XP when they login again. Also, that is a prime example of why you should avoid any kind of uncapped interest on games...

The point is that your updates are probably just numbers changing by a formula and you can adjust that formula for ANY amount of time, making "on-demand" updates a simple, practical solution.

Another thing to remember is you AREN'T Farmville or EVE. You aren't trying to balance simultaneous updates of 600,000 users in realtime because you have 500,000 online. Trying to design for those problems when you'll be successful with 10,000 regular players (not simultaneous) is absurd. Do you think about transferring exabytes of data every time you make a website?

Anyway, feel like I'm straying from the initial point: Breakdown EXACTLY what is happening in your game and then figure out how to best keep it up-to-date. That means being much more specific than armies grow, people age; you have to figure out precisely how you will track that information (database design/formula work). I'm not out to dis cron jobs, even this usage, just that you need to consider if that's the best method. The only way you can do that is by knowing precisely what and why your 'update.php' does every minute.
Quote:Original post by SimonForsman
using curlpp to load the script from a c++ program is just insane, if you're able to run your own software on the server you can have it update the gamestate directly rather than go the long way through the webserver. (I'd also recommend having your own software handle the communication with the client in that situation since HTTP and HTML/XML overhead will kill your bandwidth for any large scale game)


I don't understand what you're saying about using curlpp being insane.

How would I update the gamestate "directly." Without having a c++ program that sleeps or loops on a timer and uses curlpp to call update.php every 60 seconds?

Quote:Original post by SimonForsman
What i suggested wasn't to only update for the player in question, but rather to update for everyone


I see what you mean here but I still don't like this solution. I'd like the game world to be alive when no one is in it. But I'm still not sure I see the advantage.

Whether it calls update.php 5 times after 5 minutes of zero activity or once a minute during those 5 minutes, it's the same amount of work done by the server, but less chance of a user having to wait a little longer than they would normally have to.

As you said, it's a solution that works, but I don't see what advantage it has over a c++ program looping/sleeping.

Is the advantage just that the continuous cpu-usage of the c++ program looping/sleeping is not necessary if I do it this way?
Write a CLI PHP or Ruby script that handles simple HTTPSocket handshakes and run it on as your game server. It's a persistent process that your &#106avascript/other server can connect to using HTML5 sockets/CURL (or you can drop the whole HTTPSocket all together if you're using flash [or some other applet with socket support] and just implement your own basic protocol on-top of tcp.)
Quote:Original post by sooner123
Quote:Original post by SimonForsman
using curlpp to load the script from a c++ program is just insane, if you're able to run your own software on the server you can have it update the gamestate directly rather than go the long way through the webserver. (I'd also recommend having your own software handle the communication with the client in that situation since HTTP and HTML/XML overhead will kill your bandwidth for any large scale game)


I don't understand what you're saying about using curlpp being insane.

How would I update the gamestate "directly." Without having a c++ program that sleeps or loops on a timer and uses curlpp to call update.php every 60 seconds?


He's saying that if you're going to use a C++ application, you might as well connect to the database and manipulate the game data directly, rather than connecting to a PHP script, which then connects to the database to manipulate the data.

Also, if it were me, I would never use C++ for something like this. I would tend to lean toward a small Python app or something similar, which would be much easier and faster to develop, and no less powerful.
Ahh I see.

I don't see a big advantage of having the C++ application make all the updates itself over it calling an update.php. Unless C++ would simply do it far faster than PHP can. But I'd imagine in both cases the bottleneck would be the database.

Well I'll definitely weigh all the suggestions here and figure something out based on the final nature after more design fleshing. I now see that choosing between an "update when user loads a page or does something update-relevant"-solution, a "curlPP-driven C++ app that executes an update.php"-solution, and a "C++ app that updates the gamestate itself"-solution is fairly dependent on the specific nature/popularity of the game.

Ultimately I'll choose something that works without introducing any serious bottlenecks and takes the least work to implement.

This topic is closed to new replies.

Advertisement