Jump to content

  • Log In with Google      Sign In   
  • Create Account

[web] Updating Players - Tick / Time / Realtime

Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
14 replies to this topic

#1 ScottsCreations   Members   -  Reputation: 105


Posted 09 January 2011 - 12:11 PM

My question is to do with web games. I have never created one before and cannot find any information to how it is done on updating the players. I want to create a space game. Ive considered the tick based updates which would simply be a cron job updating all the players in x minutes, thats simple. But how does one go about doing time based updates. Example: I create a building it takes x time to build. How do i do that for say 1000 different players and different times. Do i really just have a cron job running every second checking a two columns the start and end dates of the building?

With my space game I would also want to, if i can, use js and somehow have the spaceships close to real time, where you can watch on a canvas the spaceship traveling and it gets updated every x seconds. I can get the information from the database and to the player but would it be reasonable to cron job ship updates for x many players every couple of seconds?

I have also considered web sockets, but i recently read its at the moment insecure and has been removed from some browsers....

I really want to hear from some experienced programmers on this, any links would help as well. Thanks


#2 cagecrawler   Members   -  Reputation: 226


Posted 13 January 2011 - 11:25 AM

You can simulate real time updates without the overhead by only actually updating the data when it's actually needed. Plenty of the information will be private to the particular player (army size, amount gold, spaceship positions etc.) and so you only need to update when the player is online. Take your building example. Assuming the building isn't visible by other players and doesn't affect them (ie. it's not defensive) then when the player logs on you can work out which buildings have completed and update accordingly. If they're online, then just have a JS countdown that triggers an update page when it ends.

#3 FounderSim   Members   -  Reputation: 108


Posted 13 January 2011 - 05:41 PM

then when the player logs on you can work out which buildings have completed and update accordingly.

To add to this, you will need to use timestamp's.

@ScottCreations: cron jobs every couple seconds is bad! Real bad. ;]

#4 touch_the_sky   Members   -  Reputation: 141


Posted 14 January 2011 - 08:21 AM

'...have a JS countdown that triggers an update page when it ends..'

Do NOT have anything like that unless you want your players to cheat as they please.

#5 Cygnus_X   Members   -  Reputation: 359


Posted 14 January 2011 - 08:27 AM

@Scottscreations - Can you tell us more about the game you have in mind? Will this be played over the course of an hour or over several months? This will make a difference in the type of technology you'll require.

#6 touch_the_sky   Members   -  Reputation: 141


Posted 14 January 2011 - 10:11 AM

'..I create a building it takes x time to build. How do i do that for say 1000 different players and different times. Do i really just have a cron job running every second checking a two columns the start and end dates of the building?..'

As cagecrawler and FounderSim mentioned - if it was supposed to be something ogame'ish for 1000 people - you could possibly do with usual requests.

Compare: server time when user clicked 'build', server time now, time required to pass for the building to be ready (built)

A basic example:
1) When some user 'buys' the building -> you store the server time of when it happened in the db
2) Everytime the 'show-this-users-buildings' action is called (for example: when I decide to have a look at my 'kingdom') -> if building status not set to 'built' -> having the above you check in your db how much time has to pass until the building is built:
- If not enough time passed the page displays a nice 'SomeBuilding: will be ready in getTimeLeft()' message
- If enough passed -> update the building status to 'built' -> display it on a page as 'building was built getWhenConstructionStarted() + TimeItTakesToComplete()'

You won't have to check 1000 users every second -> each detail will be updated when needed only. If I click 'buy a building which takes 30 minutes to build', but right after I log off and never come back to the game, my user won't cause you anymore traffic on your server. Then, if someone finds my 'kingdom' after 2 years and clicks on it, the building status will update at this very moment. But the user who called it will just see an old 'kingdom' with a building bought long time ago.

You can use js/ajax for better user experience (calling an action which would GET time left for example, than displaying a countdown timer on the frontend, etc). With a bit of determination and good app design you may achieve a nice real-time gameplay effect (while you won't have to spend tons on server / traffic).

#7 ScottsCreations   Members   -  Reputation: 105


Posted 19 January 2011 - 10:05 PM

Sweet, thanks for the replies. I understand the timestamp idea and the ajax / javascript loading bars and stuff.

What if say user x builds building y and its 3 hrs to build. User X logs off and goes off to work. Comes home after 5 hrs but would still want to reap the benefits of building y for the 2 hrs of it being built. Would you guys run a cron job hourly to check build times? or how would this be dealt with without being inefficient. Would this just be dealt with by using some timestamps, such that. User x logs back in, it reads the time built timestamp and knows how long its been built. It then does an update timestamp and gets say a difference of z. That difference is then added to the resources....or whatever it is....

My 1000 players was a general idea. It may be more or less hard to say. I do plan on having a continuous game.
My setup would be something like
a static server for images and static content.
nginx on the front end for load balancing, if it comes to it but ready for it.
and then i plan on using JQuery / ajax / html5 and perl catalyst on the backend

for the database i want to try postgresql. I hear good things....

Thanks for the replies sorry for the delay as i was waiting for gamedev.net to get back on its feet. So awesome now.

#8 Cygnus_X   Members   -  Reputation: 359


Posted 20 January 2011 - 08:26 AM

If you want the game to be 'real time'... ie, a player starts a building at 2:23, it takes 1 hour to complete, so you want it to finish at 3:23.... then you're going to have to go through a lot of trouble. You will need to update information for the player on each page refresh, and store the last timestamp when it was updated. Similarly, you will need to do the same if players can attack and steal resources from other players (ie, update enemy stats right before potential attack). This results in A LOT of updating, which would create a lot of bottlenecking on your server and most likely disturb gameplay. I highly recommend you avoid this approach.

The alternate, and more popular approach is to update in 15 minute to 1 hour intervals (1 hour is the most popular). This way, you can drastically reduce the number of updates your server needs to perform, and it greatly simplifies coding. For this, a Cron job is the best method.

#9 touch_the_sky   Members   -  Reputation: 141


Posted 20 January 2011 - 03:11 PM

You will need to update information for the player on each page refresh, and store the last timestamp when it was updated. Similarly, you will need to do the same if players can attack and steal resources from other players (ie, update enemy stats right before potential attack). This results in A LOT of updating

Hehe;) Absolutely not, what I said was about quite the opposite - updating ONLY when absolutely necessary, I'll try to reword it when I have a minute so it's less confusing. I can see cron jobbing being ok for some game scenarios / types as well

#10 Cygnus_X   Members   -  Reputation: 359


Posted 21 January 2011 - 07:17 AM

Virtually every page and refresh in this scenario would require a call to your update function. Consider:

Q) User begins building an item that takes 3 minutes to complete. He then either clicks refresh, or changes pages. What do you do?
A.1 Call update(); to check if the item in the queue is finished building. Failure to do this would cause # buildings to be displayed improperly.
A.2 Set a javascript timer that will call update() on completion. This can reduce the number of update() calls, but would be a serious pain to implement. I certainly wouldn't recommend this to a user asking how to use Cron jobs.

Q) A user attacks another user. What do you do?
A) First, call update() for the defenders account to make sure resources are available for the user to steal. Failure to do this would mean all players could defend perfectly by spending all their resources and then logging out. Second, call update() for the attacker to see if any buildings have been completed that would give a combat advantage.

Conclusion: The viability of 'real time' BBG progress is very low. This is why you don't see many implementations of this type of system, and why Cron is so popular.

#11 touch_the_sky   Members   -  Reputation: 141


Posted 21 January 2011 - 09:43 AM

I bet you're right with what's popular, the viability of 'real-time', etc., but:

Virtually every page and refresh in this scenario would require a call to your update function.

The above statement is false.

javascript timer that will call update() on completion

You have to be careful & clever there. Done wrong, this could be a potential bad practice / security threat - allowing me to easily skip the timer and call the update() when I please ('Why would I wait 20 mins to have it built / done if I can have it now')

Let's start over.
Some assumptions to make first: we have a browser based rts game - database driven, markup + js on the frontend of course. Let's assume 1000 players for the numbers sake. The game has the usual - displays money + some stats at the top, allows to purchase buildings, army, view & attack other players' kingdoms (takes time until your army reaches enemy). And we try to achieve the 'real-time' gameplay feel.

I'll try to reword the 'build a building' example:

Scenario 1 - The User buys a building:
DB pseudo-structure
1) You have a 'buildings' table in your db
2) Let's not get into the details of what params (table columns) can the buildings have (also skip the obvious columns like ids, etc.). For this 'real-time' example all the columns we should care about are like: building_name, price, status, time_it_takes_to_build, created_at, updated_at
The action
1) User clicks 'Buy Building Blah'
2) You create a new building for this user in the db; you take off the price from the amount of money the user has; you set the status to 'under_construction'; both created_at and updated_at you populate with current server time at this stage. Knowing current server time is a given, it's there for you all the time, no performance probs - it's also a big player in the further part of the story;)
And voila! - you're done, it's pretty much the same thing you would do always - regardless of whether you use Cron or not, so no performance talks here.

Scenario 2 - the infamous page refresh (The User decides to have a look at his buildings, etc.)
1) 'Click'
2) You GET user's building from db - there's a good chance that's gonna be the only db hit (and no updating)
3.1) The building has status of 'under_construction'. Well, right there you already have when the buildings was purchased (created_at), how much time needs to pass for the construction to complete (time_it_takes_to_build) and something you always have, no matter what - current server time. Now it's easy;)
  • 3.1.1) If enough time passed since the created_at till now, only then you update: status => 'complete'; updated_at => current server time. On a page the user sees 'This building was built format_time_nicely(updated_at)'.
  • 3.1.2) If not enough time passed, you echo 'building will be ready in time_remaining' - on the user's machine (after page is loaded) you can grab the number easily and have a nice js countdown (no talking to server there)
3.2) The building has status of 'complete' - no need to explain further, no extra db hits, checking - just display the data you already have

Well, there you go;) Hope you do not see 'updating everywhere' now, but updating ONLY when you actually should be updating. And most important - it's a 'real-time' game, players always see uptaded stuff - there is a feel of 'constant flow', etc.

With 'cron-way' (the way it was put) you would:
1) skip checking times - not really a performance boost there.
2) not have occasional update statement - hmmm.. mild performance boost, especially with all the js / ajax goodness which make 'waiting time' much less obvious and painful for the user

Plus, what seems to be the reason of why I am even talking against Cron here:
1) How do you achieve this 'real-time' effect with Cron, without stupidly low interval (seconds) - big performance issue
2) Imagine this: 1000 players online, 300 refreshes the 'view my buildings' page - the rest stares at the screen doing nothing:
  • Without Cron - could be lightweight / slightly heavier requests (depends if any updates necessary or not). But all the happy players would have the correct, up-to-date info constantly
  • With Cron - lightweight requests, info displayed to users most likely out of date until next Cron job. Then when it happens - you would have to run a giant loop through all the players, checking / updating every single detail - buildings, money, army, fights, etc. Even if most players had nothing to update, you'd still have to go through every single detail.

#12 Cygnus_X   Members   -  Reputation: 359


Posted 21 January 2011 - 10:37 AM


Good post, and well thought out. Ratings +1. I think my reply was built mostly around my own experiences, so I apologize. Two notes.

First, I agree with you that 'update checks' will be done and not a full 'update' on each refresh. As a default, I do all security checks inside my function (to ensure they never get called before security checks... which is easy to do with proper classes). So, I was confusing with my terminology when I said update(); would need to be called on each page refresh. In my example, update() would see that not enough time had passed, and quickly exit (but is still called. Minor overhead, but still there). Of course the real key to saving the bottleneck here is by reducing our insert and update statements.

Second, where I think this will get complicated is if buildings produce some sort of good (such as energy, gold, etc) every x units of time once its completed. If a building produces 1 gold every hour once it finishes building, then the older the game gets, and the more players the game has (and buildings in existance), then the higher the demand the update statements will become. I'd much rather do one giant "update Users set Gold = Gold + Goldmines" statement for all players once per hour than I would a single update against one playerID, but multiple times throughout the hour.

Third, if a player does not log in for a long period of time, and there are many buildings in the queue, then this again creates the need for an ugly update function that steps through each completion time, updating resources, etc as it progresses.

I'm not saying its not possible. Ogame does 'real time' updates, and is popular. But a hidden design element in Ogame is that buildings take progressively longer to build, up to several HOURS to perform after just a few days of play. I'm sure this is to get around the trouble noted in my 2nd point. Talk about having nothing to do :P My argument for Cron and updates no more frequently than once per 15 minutes is that it provides a much cleaner approach with some minor overhead savings. There are several other arguments here to support Cron, but its really for the OP to decide.

#13 jolid   Members   -  Reputation: 143


Posted 21 January 2011 - 04:21 PM

Damned new design, wrote a nicer post and hit the wrong button... So here's my main points:

touch_the_sky hit it pretty well, but don't update statuses like that. Player hits 'Create Building', create a DB entry with 'building_complete_time', and use that. You don't have to touch the entry again for maintenance purposes: queries like 'GET player_X_buildings WHERE completed_time > NOW' gets you incompletes, queries like 'GET player_Y_buildings WHERE completed_time < NOW' gets you all active/complete buildings. Calculate remaining time with completed_time - NOW. No issues here with long no login times, no extra DB queries/updates, almost no time/date functions (or, hell, math! just addition/subtraction) if you use *nix timestamps.

CygnusX has a point on realtime gold/energy/people/etc from buildings. Buildings producing goods is a simple compounding interest problem you can best solve by putting in a once-a-day/login/whatever time for those benefits to be gained (or cron, if you're so inclined, especially if you need to run other external maintenance/cleanup that way). If you HAVE to have those gains in realtime, your best bet is probably a separate process/DB to maintain everything separate from the game load, but that's still going to be slightly off and hard to maintain. You're basically running/writing banking software and/or stock markets at that point, and while it's not impossibly hard, it's probably more of a headache than you really want (unless you're that kind of math geek! :-P)

Just think in terms of data for now. Many large games (even running in realtime almost identically to what's described above) end up using regularly scheduled cronjobs and such but it's often a byproduct of load balancing or maintenance (meaning account security, checking for h4ckz, pruning old data, etc). Since those tasks end up getting optimized to hell and back and have to touch every account anyway, some things can be put in there to get a net gain (slower scheduled task, faster per user) in performance. None of that should matter at 1000 (or even 10000, sometimes even 100000 depending on DB size and host) users, though. Splitting any turn-based game (meaning you do X tasks over Y time) into chunks crunchable by an optimized cronjob is typically preferable, though, as it's a few minutes of server strain versus a constant moderate load (visible in page loading).

#14 ScottsCreations   Members   -  Reputation: 105


Posted 21 January 2011 - 05:34 PM

Thanks everyone. I learned a lot here. I did some research on the real time stuff and it seems if I wanted real time game play I would have to go with Flash or some other container that could be embedded into a website to have a socket server on the back end since javascript io:socket isn't quite there yet. The updating makes a lot of sense and I appreciate the lengthy posts with the examples. I think I will avoid the cron job as I want to be as close to real time as possible and if say the game does get popular and starts to crumble in speed, i'll look into a cron job as a solution or just cap the players and make a server2 instance :).

Hopefully this thread will help out others as well. Thanks! :)

#15 touch_the_sky   Members   -  Reputation: 141


Posted 24 January 2011 - 05:52 AM

Yep, there was a bit of a discussion going on here;) Cygnus_X, me and jolid made some valid points which should hopefully be useful to other people.

Flash is a bit of a game changer I suppose (not as risky as js in terms of moving some 'heavier lifting' to ther frontend?). Unity or similar may possibly be a good idea (since you've decided to require a plugin anyways), it's not something everyone will have installed cause it's needed for YT, but if the game justifies the requirement with it's looks, etc. (accelerated graphics) you should be fine - haven't used it, but it's said to be really easy to use.

Just an idea which came to my mind - back to js - it may be worth to have a look at some web based, ajax chat clients (gmail messenger, meebo and stuff), the way they operate - they do not require you to download anything, yet they provide a neat real-time chat facility.

Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.