Author Topic: Countdown + update  (Read 1363 times)

Offline Jesterhead

  • Level 8
  • *
  • Posts: 41
  • Reputation: +1/-0
  • In Flames we trust!
    • View Profile
Countdown + update
« on: May 25, 2011, 04:39:21 AM »
Hello again,

Now I've figured out how I will organise my troops, it was time to think about realtime movement or tick based.
The answer was simple, realtime.

Now I'm just a BIG NOOB when it comes to javascript, all I know is how to update a form. So I need a little bit of your help.



Database setup (troop_movement)
ID  From  To  Action  Arrival  Unit 1  Unit 2  Unit X 
112Attack  2011-05-26 11:07:03  10000



Now obviously, I want a countdown displaying somewhere.. and refresh the page once it hits 0.
Not a big deal.. but how do I make my database update once NOW() > Arrival ?

I can't let a cronjob run every 1 second (that's just stupid), but I have no clue how to update my database when there is nobody to initiate it. Let's say I send these 100 units, and then log off... the next day I log on and the troops have arrived (the attack script ran, and they are comming back) without me or any player causing action.

I know this is probably one of the most basic things to do with javascript and php, but I guess we all have to learn it once?

I hope you guys can help me out again,
Jesterhead

Offline Chris

  • Game Owner
  • Level 35
  • *
  • Posts: 2,217
  • Reputation: +28/-1
    • View Profile
Re: Countdown + update
« Reply #1 on: May 25, 2011, 06:01:00 AM »
If you want "real realtime" then you have to do cronjob each second :) No alternatives here (well if you switched to other languages there might be some options, but these will still be almost identical to cronjob so no real difference)...

That's why most people use tricks and only pretend it is real realtime.

Offline FutureLost

  • Level 4
  • *
  • Posts: 11
  • Reputation: +0/-0
    • View Profile
    • FutureLost Cyberpunk RPG
Re: Countdown + update
« Reply #2 on: May 25, 2011, 06:18:52 AM »
Hi Jester,

I agree with Chris. You probably know involved players for some territory (for example Player A is controller, Player B attacker), so maybe you can initiate code when first of the involved parties logs. Obviously, if time is not right nothing happens and if it is, you update database. You don't have to initiate code at the exactly right time, because results are needed only when somebody asks for them. If nobody asks, you don't have to initiate code at all.

Offline BlackScorp

  • Level 15
  • *
  • Posts: 123
  • Reputation: +6/-0
    • View Profile
    • Cruel Online
Re: Countdown + update
« Reply #3 on: May 25, 2011, 06:46:55 AM »
hm... i would not update my database. you just write in your database WHEN do the tropps arrive, not HOW LONG UNTIL.

so if user see the page, he can see the countdown via javascript, if the clock hit 0 the script refresh the page.

so everythink you need is to get the time from database, calculate the diffrence and display how long it will takes until the troops arrived with JS.

on the serverside you can say if now >= arrive time then attack

hope you understand what i want to say:D my english is really bad

Offline Freyr

  • Level 7
  • *
  • Posts: 30
  • Reputation: +1/-0
    • View Profile
Re: Countdown + update
« Reply #4 on: May 25, 2011, 07:28:24 AM »
There would potentially be a need for a cronjob, but I see no reason why it needs to happen every second.

Here's a couple of methods that you could use:
1. Ajax requests, query a receiver every few seconds, and when done, display the results.
This is very server intensive, so I would suggest against it. On the other hand, Facebook uses something similar for their "Live Comments".
The only difference there is that the server pushes the data, instead of the client pulling it.

2. Have PHP set a Javascript variable, for when it's done. Then have a simple JS function count it down, and when it's done, you then make an Ajax call, or reload the page entirely to display the result.
This would still mean you need a cronjob, but it should only come into effect when the player is NOT active. Though, this method does depend mostly on the player staying on the page until the timer is finished.

3. Creating a text file that's updated every minute or so by the server, containing a result of true or false.
True would mean that the task is completed, false obviously means it's not.

In all of these, the server would automatically update the database when it's complete, no matter if JS is involved or not.
But, in nr.1 & nr. 2, a script would be executed by the client, and not the server. This is the most popular technique to use, as it puts less strain on the server.
// this is a comment

Offline BlackScorp

  • Level 15
  • *
  • Posts: 123
  • Reputation: +6/-0
    • View Profile
    • Cruel Online
Re: Countdown + update
« Reply #5 on: May 25, 2011, 07:39:18 AM »
i think FutureLost is right, you dont need to Update a Database if no Infos needed. i would personally use Cronjobs to clear database, update user images for Forums but not to update some ingame actions.

Offline Jesterhead

  • Level 8
  • *
  • Posts: 41
  • Reputation: +1/-0
  • In Flames we trust!
    • View Profile
Re: Countdown + update
« Reply #6 on: May 25, 2011, 07:50:46 AM »
I don't like to compare my project with Travian (as it's not the same at all, but more on that later), but as everyone knows this game it might be easier.
But games like Travian, and basically all games where you have to build stuff have this feature what I'm looking for.(Tribal Wars, Illyriad, etc...)

Do you guys think they use cronjobs for this? (it has to run every second as some things have buildingtimes of 1h32m11s)

For example:

- You upgrade your cropfield (takes 2 hours)
- Logout
- Login after 5 hours
- The crop field has been upgraded for 3 hours now, so your production was higher for those 3 hours.. even if you didn't log in. (This is why the info should update when nobody initiates it!)

Even small community maffia games etc use it to get out of prison etc..

I've read about ajax stuff before I posted this, but I thought it was possible with PHP and Javascript.
But of course, I may be wrong...

PS: Of course I don't update database if there is no new data, I just need to find a way to let the server check every second if there is any new data to store.
« Last Edit: May 25, 2011, 07:54:07 AM by Jesterhead »

Offline BlackScorp

  • Level 15
  • *
  • Posts: 123
  • Reputation: +6/-0
    • View Profile
    • Cruel Online
Re: Countdown + update
« Reply #7 on: May 25, 2011, 07:54:38 AM »
everythink you need , is a function which update your last_login of your user in the database. so if you know how long wasnt the user online and what happened in this time, you can calculate everythink and update everythink if he comes back

Offline Jesterhead

  • Level 8
  • *
  • Posts: 41
  • Reputation: +1/-0
  • In Flames we trust!
    • View Profile
Re: Countdown + update
« Reply #8 on: May 25, 2011, 08:03:10 AM »
everythink you need , is a function which update your last_login of your user in the database. so if you know how long wasnt the user online and what happened in this time, you can calculate everythink and update everythink if he comes back

I also thought about that, but then this can happen.
Another player attacks you while you aren't there and destroys your cropfield 1 level.. what now?
Of a player robs your village while you aren't there, so he can only steal what was there once you last logged in?

Example (assume 1 hours = 1 extra food):
- I have 2 food when I log out...
- After 10 hours I should have 12 food..
- I get attacked after 10 hours, and the attacker can only steal 2 food (instead of 12), so he steals 2 food
- This means that when I log back in after 20 hours... my food stock is 20 instead of 10

Is this how it works in professional games? To be honnest, I'm not sure...

Offline BlackScorp

  • Level 15
  • *
  • Posts: 123
  • Reputation: +6/-0
    • View Profile
    • Cruel Online
Re: Countdown + update
« Reply #9 on: May 25, 2011, 08:09:31 AM »
its just harder to calculate, you need to add your events in a table

so if you upgraide your building you add this as event, if you getting attacked , add this as event , if you got items from other players add this to event list

if you come online, calculate first like in your example. after this calculate everythink from events then update your table and display the results.

but iam sure the Browsergame developers using Programms written in C/C++ or other stuffs instead of using Chronjobs. Chronjob is just an alternative way if you dont own a Root server

Offline Jesterhead

  • Level 8
  • *
  • Posts: 41
  • Reputation: +1/-0
  • In Flames we trust!
    • View Profile
Re: Countdown + update
« Reply #10 on: May 25, 2011, 08:47:30 AM »
I guess I'll just run a cronjob every minute with a code like this. As it's the only way around?
And then a simple JS countdown that refreshes the page on 0.

Code: [Select]
$query = mysql_query("SELECT * FROM unit_movement WHERE arrival =< 'NOW()'") or die (mysql_error());
while ($row = mysql_fetch_assoc($query))
{
$action = $row['action'];
switch ($action)
{
case attack:
//run attack script

case trade:
//run trade script
}
}

i hope there won't be a lagspike every min...
« Last Edit: May 25, 2011, 08:49:17 AM by Jesterhead »

Offline BlackScorp

  • Level 15
  • *
  • Posts: 123
  • Reputation: +6/-0
    • View Profile
    • Cruel Online
Re: Countdown + update
« Reply #11 on: May 25, 2011, 08:53:22 AM »
hm.. i wouldnt now use the Now() function of SQL... if you have 1 million + inserts in the tabel unit_movement your Database would crash, calculate the time in PHP and use it instead of Now function

Offline Jesterhead

  • Level 8
  • *
  • Posts: 41
  • Reputation: +1/-0
  • In Flames we trust!
    • View Profile
Re: Countdown + update
« Reply #12 on: May 25, 2011, 09:01:16 AM »
hm.. i wouldnt now use the Now() function of SQL... if you have 1 million + inserts in the tabel unit_movement your Database would crash, calculate the time in PHP and use it instead of Now function

Alright, it was just about the idea tough.. I wrote that in 2 sec.

Offline BlackScorp

  • Level 15
  • *
  • Posts: 123
  • Reputation: +6/-0
    • View Profile
    • Cruel Online
Re: Countdown + update
« Reply #13 on: May 25, 2011, 09:11:23 AM »
but werent it better to have somethink similar to this?

Code: [Select]
"SELECT * FROM events WHERE event_end BETWEEN $users_last_action AND $now AND user_id = $loggedinuser"

...

foreach($events as $event){
switch events

increase or decrese somethink
mark event ids which need to be deleted or delete events which you already calculated
}

so you just need to run this script if user is online

this seems to be interessting i will try to code it later and hope to get a result.. i think every browsergame developer is using cronjobs for updating.. i will try to solve this problem without cronjob
« Last Edit: May 25, 2011, 09:20:34 AM by BlackScorp »

Offline FutureLost

  • Level 4
  • *
  • Posts: 11
  • Reputation: +0/-0
    • View Profile
    • FutureLost Cyberpunk RPG
Re: Countdown + update
« Reply #14 on: May 25, 2011, 02:30:40 PM »
everythink you need , is a function which update your last_login of your user in the database. so if you know how long wasnt the user online and what happened in this time, you can calculate everythink and update everythink if he comes back

I also thought about that, but then this can happen.
Another player attacks you while you aren't there and destroys your cropfield 1 level.. what now?
Of a player robs your village while you aren't there, so he can only steal what was there once you last logged in?

Example (assume 1 hours = 1 extra food):
- I have 2 food when I log out...
- After 10 hours I should have 12 food..
- I get attacked after 10 hours, and the attacker can only steal 2 food (instead of 12), so he steals 2 food
- This means that when I log back in after 20 hours... my food stock is 20 instead of 10

Is this how it works in professional games? To be honnest, I'm not sure...

Well I think that you can treat every interaction of that type same as player logging in. All numbers and other data about player are in hibernation until something happens (player logs or some other player interacts with him). When that happens you initiate code for usual things that should happen between last interaction and this new interaction (food increase as you said for example) and then initiate code for special event (attack).

for example:

- you log out with 2 food
- after 6 hours someone attacks you, code checks how much food you should have at that moment and food is increased to 2 + 6 = 8 food
- attacker plunders for example 5 food, so you now have 3 and after updating database everything hibernates again
- you log in 13 hours after log out (7 hours from plunder) and the first thing code does is to again update your status (previous food was 3 and + 7 for 7 hours you have 10)
- player has 10 food and now he can take some action
 

Offline BlackScorp

  • Level 15
  • *
  • Posts: 123
  • Reputation: +6/-0
    • View Profile
    • Cruel Online
Re: Countdown + update
« Reply #15 on: May 26, 2011, 02:18:19 AM »
yeah its simple, i thought but it isnt that easy to code this.. i try with this scene

a building give me 1 Wood every hour.

User A is Online and Upgraid the Building to level 2 to gain 2 Wood each hour. Then he log Off and now shit going to happen:D

So he get 1 Wood each hour until the Building is done, during his offline time, he get attacked by User B and he stole 5 Wood from Him  , after the attack ,User A got some ressources from Marketplace

Now we need a Database for this events, as long as i can see there are 6 Event types

Attack (decrease Resources once)
Upgraid building (increase Resources whole time)
Downgaid Building(increase Less resources whole time)
Trade(increase and decrease once)
Send Resources(increase resources once)
Upgraid Research to gain Resource bonus(increase resouces once or whole time depends on research)

Did i forgot some?

so what Database structure you need for it?

Iam actually thinking about it but its harder to realize that i thought at the beginning..


Offline Jesterhead

  • Level 8
  • *
  • Posts: 41
  • Reputation: +1/-0
  • In Flames we trust!
    • View Profile
Re: Countdown + update
« Reply #16 on: May 26, 2011, 04:27:25 AM »
FutureLost is right. Only update when there is interaction with the player.
The code will be harder to figure out tough, but it's do able and way less server consuming.

Another way is to update the DB everytime someone connects to the DB (any player), but that's again fairly server consuming.

I just contacted the maker of "illyriad", asking how his mechanic works.
Once he answers I'll post it here.

EDIT: He doesn't respond, looks like they like to keep their secrets (which I totally understand)

EDIT: This is the final solution (just in case anybody else needs it): http://buildingbrowsergames.com/2008/07/18/using-the-on-view-method-instead-of-cron/
« Last Edit: May 27, 2011, 11:35:26 AM by Jesterhead »

Offline Chris

  • Game Owner
  • Level 35
  • *
  • Posts: 2,217
  • Reputation: +28/-1
    • View Profile
Re: Countdown + update
« Reply #17 on: May 29, 2011, 03:05:46 PM »
I have mixed feelings about update when it is needed vs update in bulk via cronjobs. From my experience bulk updates resource usage is heavily overestimated and player driven updates underestimated.

Anyway, you can read this: http://community.bbgamezone.net/coding-discussion/cron-jobs-or-not/msg11649/#msg11649

Offline Anonymous

  • Level 2
  • *
  • Posts: 3
  • Reputation: +0/-0
    • View Profile
Re: Countdown + update
« Reply #18 on: August 07, 2011, 06:54:47 PM »
If we can assume two players - A and B. then A when logged in I would:

Code: [Select]
us = new User('A');
us -> update_activity();
us -> regenerate_things();

for each and every page. The update_activity() is simply setting a timestamp and incrementing a counter; this is used to track user activity only. The regenerate_things() routine checks the a last regenerated value, and updates anything that is required if a certain time has expired (usually 1 minute or so).

If user B turns up, and for example attacks user A, where both user's details need to be up-to-date, then the code becomes:

Code: [Select]
us = new User('B');
us -> update_activity();
us -> regenerate_things();
them = new User('A');
them -> regenerate_things();
/* perform attack knowing everything is up-to-date */

This type of regeneration seems to work well, however it still doesn't address the problem of resource building acceleration / deceleration. In the case of building / field "levels", surely this can be done by keeping track of each building level and applying a scaling factor to the regeneration based on exactly what the user has at any time. - You know when the build is completed, destroyed... it just a case of designing a data structure to handle that.

[NB. I'm having a minor headache trying to actually envisage this one - but it can't be that difficult]

Offline Ben Adams

  • Level 4
  • *
  • Posts: 13
  • Reputation: +2/-0
    • View Profile
    • Illyriad - Dev Blog
Re: Countdown + update
« Reply #19 on: September 03, 2011, 06:54:03 PM »
FutureLost is right. Only update when there is interaction with the player.
The code will be harder to figure out tough, but it's do able and way less server consuming.

Another way is to update the DB everytime someone connects to the DB (any player), but that's again fairly server consuming.

I just contacted the maker of "illyriad", asking how his mechanic works.
Once he answers I'll post it here.

EDIT: He doesn't respond, looks like they like to keep their secrets (which I totally understand)
Hello

A bit late but, simplified, the items we use are:

1. Table with "current resources", "resources per time period", "resources last updated"
    - these are stored at high decimal precision, however "current resources" are floor() when displayed to player
2. Queue of events in db by completion date (e.g. building built, army arrived etc.)
    - again you'll need sub-second precision on this
3. A recalc resources db function
  • Set "current res" = "current res" + "resources per time period" * (Now() - "resources last updated")
  • Set "resources last updated" = Now()

On the server: we have an event loop which runs continuously - what this does is:

1. Pick up all events in the queue that have completed before now
2. Execute the events in ascending competition timestamp order
  • recalc resources of player effected by event to get the right current resources (using completion date rather than Now())
  • execute event - which may cause player to gain or loose "current resources" and update their "resources per time period"
  • recalc resources of player effected by event to get the right current resources (using Now())
3. Sleep for 1 second (otherwise you'll kill your server in a pointless spin loop)

This deals with all the background events that aren't driven by immediate player interaction

For player interaction:
Originally: We called recalc resources at the start of every page request and Illyriad operated like a regular website with a fresh page on every click and the new resources were displayed on each refresh

Now: After ajaxifying Illyriad we now load the "resources per time period" into the front end and count up/down with js; when an event either from the event queue or user initiated changes the resources on the server it sends a notification back to the browser to tell it to refresh the "current resources" and "resources per time period" from the server to keep them in sync and start counting again.

Hope this helps
« Last Edit: September 03, 2011, 07:00:48 PM by Ben Adams »
Currently working on Illyriad a real-time, HTML5 Massively-Multiplayer strategy game.

Illyriad - Dev Blog

 


SimplePortal 2.3.3 © 2008-2010, SimplePortal