Author Topic: World Time Question - run script every 60hours  (Read 461 times)

Legacy_Buddywarrior

  • Hero Member
  • *****
  • Posts: 512
  • Karma: +0/-0
World Time Question - run script every 60hours
« on: March 02, 2014, 10:43:00 pm »


               

I would like to trigger world events at a seemingly random time. I figure every game time 60 hours would quickly make things happen during the day or night and everywhere in-between. But how can I trigger something to happen every x hours? 


 


Thanks for the input!



               
               

               
            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
World Time Question - run script every 60hours
« Reply #1 on: March 03, 2014, 04:28:37 am »


               

check time in the module heart beat event



               
               

               
            

Legacy_Buddywarrior

  • Hero Member
  • *****
  • Posts: 512
  • Karma: +0/-0
World Time Question - run script every 60hours
« Reply #2 on: March 03, 2014, 02:30:31 pm »


               

For some reason my brain just wanted to do it by number of hours/days and forgot all about just counting heartbeats. I blame it on new board anxiety syndrome. 


Thanks Henesua!


 


-Buddywarrior



               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
World Time Question - run script every 60hours
« Reply #3 on: March 03, 2014, 02:38:04 pm »


               

do not count heartbeats, thats not realiable


 


instead retrieve local int "LAST_HOUR", check current hour, check if they match, if not set local int "LAST_HOUR" current hour and do some stuff


 


same with day/month/year



               
               

               
            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
World Time Question - run script every 60hours
« Reply #4 on: March 03, 2014, 09:16:08 pm »


               

What Shadow says is correct, but the best place in my opinion to track time is in the module heart beat.



               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
World Time Question - run script every 60hours
« Reply #5 on: March 04, 2014, 03:59:19 am »


               


do not count heartbeats, thats not realiable


 


instead retrieve local int "LAST_HOUR", check current hour, check if they match, if not set local int "LAST_HOUR" current hour and do some stuff


 


same with day/month/year




This isn't particularly reliable either, since updating time is low-priority in the engine. In fact, module heartbeats are MORE reliable, on any given server (ours has been roughly every 5.2 seconds for years now - linux boxes tend to have shorter intervals, for reasons we never discerned). We don't like to rely on either, though. Instead, we compare to UNIX_TIMESTAMP from MySQL. That's not perfect either, obviously, but it is a lot less variable. See here for part of our module heartbeat:


http://pastebin.com/SZKb5x7J


 


And yeah, I know you like to avoid SQL. '<img'>


 


Funky



               
               

               
            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
World Time Question - run script every 60hours
« Reply #6 on: March 04, 2014, 04:38:43 am »


               

crap i forgot about the issue with time when the server gets over taxed.


 


Funky, what it looks like what you are doing is tracking the passage of real time and converting it to game time when you need to. Is that correct?



               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
World Time Question - run script every 60hours
« Reply #7 on: March 04, 2014, 05:46:07 am »


               GetGameHoure is reliable, the game clock graphical display my not get updated but the internal clock is accurate.

If it was not delayed commands would not even work.

But i see no reason to update an integer every hour, just store a time stamp for your starting hour and check it against the current hour to see if 60 hours have passed.

ie.

Store a stamp for the current hour.
 

int GetHourStamp()
{
  return  GetTimeHour() + GetCalendarDay()*24 + GetCalendarYear()* 8064;
}
 
void main()
{
  //Set a hour stamp on the module
  SetLocalInt(GetModule(), "HourStart" , GetHourStamp());
 
}
Then you just need to check the current time against the stamp. 

int GetHourStamp()
{
  return  GetTimeHour() + GetCalendarDay()*24 + GetCalendarYear()* 8064;
}
 
void main()
{
  //Pull the hour start from the module.
  int nHourStart=GetLocalInt(GetModule(), "HourStart");
 
  if ( GetHourStamp()-nHourStart >60)
  {
    // code for event happening every 60 hours.
  }
}

               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
World Time Question - run script every 60hours
« Reply #8 on: March 04, 2014, 08:26:47 am »


               


crap i forgot about the issue with time when the server gets over taxed.


 


Funky, what it looks like what you are doing is tracking the passage of real time and converting it to game time when you need to. Is that correct?




We basically get 'real' computer system time, bypassing NWN's permutations of it. Remember that even computer system clocks are susceptible to inaccuracy, though - we're just removing some additional sources of it. Our system clock actually got almost a full half-hour off 'actual' atomic clock time at one point last year, though that was certainly unusual.


 


Anyway, we check unix time, and set a var on the mod, "uptime" from it, updating each heartbeat. We then use that variable in our timestamps. That limits granularity somewhat, but you can use effects if you need greater granularity, or even just delays. We like to avoid delays, though, and generally just check against the timestamp at appropriate times instead.


 


Funky


               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
World Time Question - run script every 60hours
« Reply #9 on: March 04, 2014, 08:37:49 am »


               


GetGameHoure is reliable, the game clock graphical display my not get updated but the internal clock is accurate.


If it was not delayed commands would not even work.


But i see no reason to update an integer every hour, just store a time stamp for your starting hour and check it against the current hour to see if 60 hours have passed.


ie.


Store a stamp for the current hour.

 



int GetHourStamp()
{
  return  GetTimeHour() + GetCalendarDay()*24 + GetCalendarYear()* 8064;
}
 
void main()
{
  //Set a hour stamp on the module
  SetLocalInt(GetModule(), "HourStart" , GetHourStamp());
 
}

Then you just need to check the current time against the stamp. 

int GetHourStamp()
{
  return  GetTimeHour() + GetCalendarDay()*24 + GetCalendarYear()* 8064;
}
 
void main()
{
  //Pull the hour start from the module.
  int nHourStart=GetLocalInt(GetModule(), "HourStart");
 
  if ( GetHourStamp()-nHourStart >60)
  {
    // code for event happening every 60 hours.
  }
}



It doesn't follow that DelayCommands wouldn't work - they would simply be less accurate. At least, that's my understanding. I don't pretend to know the engine as well as acaos, who finally settled on the method I pastebinned above. But then, I doubt anyone understood it as well as he did, save maybe vman and one or two other NWNX gurus who've been through it backwards and fowards in a disassembler.


 


In any event, I suggest you try testing under load. We managed to push our mod heartbeats from 5.2 to either 8 or 10 seconds apart (I forget which, it was a long time ago).


 


You're right about one thing, though, I shouldn't have mentioned the engine priority, since while it affects engine updating, it's not at the root of the inacuracy at issue.


 


Funky