|
|
This thread is locked; no one can reply to it.
|
1
2
|
| Timer Method |
|
Onewing
Member #6,152
August 2005
|
When I started using Allegro, I was in a rush to finish a college project with it, hence my study time was low. Originally, I just used the clock() method of somewhat governing my game. For ChristmasHack, I decided to use/learn the allegro methods. After a little messing around and reading other discussions about timers (there's quite a bit if you do a forum search), I've got a basic understanding. I thought I'd present my methodology and see what the general consensus is, pros and cons. Without further ado, My timer function is very simple: volatile int system_timer; void GAME_TIMER() { system_timer++; } END_OF_FUNCTION(GAME_TIMER);
In the init routine at the beginning of the game, I do the following: Here's where system_timer begins to control things, at least, if I've imagined this correctly. I kind of use a time stamping method. Typically what I do is create timestamp-like integers that remember when a certain time occurs and when there is a certain amount of difference between the timestamp-like integer and the system_timer, then whatever to follow is allowed. e.g. if(abs(system_timer - some_timestamp_integer_x) > some_determined_amount_of_time) { //do whatever it is that you want to do some_timestamp_integer_x = system_timer; } To further explain, each one of my AI bots has it's own private int called "move_timer" (defined in the class) and public (this could be private as well) int "move_speed". Changing the "move_speed", I can have my AI bots walking at different speeds: if(abs(system_timer - bot.move_timer) > bot.move_speed) { // take a step in whatever direction bot is facing bot.move_timer = system_timer; } The whole idea is to have just one timer variable and the others just pretending like they're timers. What do you think? Is that a bad idea? If so, why? ------------ |
|
Murat AYIK
Member #6,514
October 2005
|
I basically use a 200 ticks per second timer to do the job and a 1 tick per second one just for fun! The kernel has global-enough(!) variables like: Calculating new_ticks is obvious. If a bot has a move speed of 0.2(per_tick) then I let it walk (bot.walk_speed * new_ticks) Works flawlessly. There is only one timer variable and it can't be touched by anyone but the kernel. EDIT: Instead of keeping timer-clones you can better save info about what the bot wants to do and in how much time(rather then "when") Also I'm not sure a milisecond level timer would be accurate in Allegro. I remember complaints about it here. And if you insist on keeping that resolution I suggest you use a variable(like my current_tick) to be used by the logic, instead of testing the volatile one(since it is quite volatile!!) _____________________________________________________ |
|
razor
Member #2,256
April 2002
|
If I rememeber right the allegro timer is only accurate to ~10ms, but that should be good enough for any game. Whoooo Oregon State University |
|
HoHo
Member #4,534
April 2004
|
Quote: If I rememeber right the allegro timer is only accurate to ~10ms That depends on the OS. On older windowses it was around 50ms, newer (2k, xp) ~10ms. Newer Linux kernels have 4ms default, configurable up to 1ms (if I understood kernel config correctly). __________ |
|
Onewing
Member #6,152
August 2005
|
Quote: Also I'm not sure a milisecond level timer would be accurate in Allegro. I wouldn't think so either, but I had no idea how accurate allegro could get it, so instead I opted for 1 millisecond and then shoot for an approximation. So if a certain timestamp was waiting for there to be a difference of 50ms, it might not be till 51ms, 52ms, etc. until it actually validates the difference and updates the clone. At least, that was the idea. Since I'd probably never say "when 53ms have passed", I'll probably change it to 10ms or something a little more agreeable. ------------ |
|
Murat AYIK
Member #6,514
October 2005
|
Quote: On older windowses it was arounbd 50ms, newer (2k, xp) ~10ms. Do you think I should change my 200/sec timer to 100/sec? I chose 200 because it was the value of "i_love_bill" thing! And works well even in long term. EDIT: Interesting! I edited my post, and it dropped to the bottom of the thread! MATTHEW!! _____________________________________________________ |
|
HoHo
Member #4,534
April 2004
|
Quote: Do you think I should change my 200/sec timer to 100/sec? I don't know. If 200ms works for you I don't see a reason. Remember, don't fix it if it isn't broken __________ |
|
Murat AYIK
Member #6,514
October 2005
|
Quote: If 200ms works for you I don't see a reason. Remember, don't fix it if it isn't broken Works perfectly, even in "do stg after this much time" things. And for about two months people are trying my stuff, nothing came about this. Also that 200 value is kept in a constant, I can change it later without any problems if anyone complaints about it. EDIT: Did any of you see my last post fall down, too?! _____________________________________________________ |
|
Thomas Harte
Member #33
April 2000
|
Quote: That depends on the OS. On older windowses it was around 50ms, newer (2k, xp) ~10ms. If you're happy to throw a Win32 specific call in to your code, you can use timeBeginPeriod to get a much better resolution on all Windows since 95. Quote: The whole idea is to have just one timer variable and the others just pretending like they're timers. What do you think? Is that a bad idea? If so, why? It is a good idea. If you aren't using an update method that syncs to the retrace you might also want to consider a frame cap implemented via rest() so that all the laptops and modern desktops can power save and/or switch off some fans. [My site] [Tetrominoes] |
|
Felipe Maia
Member #6,190
September 2005
|
I think my method is old and stupid, instead of using the global timers, I just use logic cycles as my method to decide if it's time already or not, but that way the game wouldn't run the same on different computers, oh well, need to learn new methods. EDIT: Actually, it is not that bad since the only harmed targets are old computers, that wouldn't be able to do the logic cycle on time, which would mean very low fps, which would mean game unplayable. No need for new methods |
|
Tobias Dammers
Member #2,604
August 2002
|
Allegro timers have 2 major problems. First, their granularity, which differs per platform (and possibly per system). While 10ms is short enough an interval, the frequency generated from the interference of the game timer (the rate at which your position variables are updated) and the screen refresh rate (the rate at which they are displayed) can lead to very noticeable "jumps" in what is intended to be smooth movement, since there will not be a constant number of timer ticks between two (screen) frames. For example, if refresh rate is 72 Hz, and the timer runs at 10ms, then there will be 100/72 ticks per frame - some frames will contain a single logic tick, while others contain two. So in some frames, the character will move twice as far as in others. --- |
|
HoHo
Member #4,534
April 2004
|
I think it 4.3 series and up there should be a better timing framework. Possibly some counter that gets updated frequently* that could be used to compute the time that has passed. *) probably red from either RDTSC, gettimeofday or whatever the current platform has __________ |
|
Murat AYIK
Member #6,514
October 2005
|
I was recently misdirected to a page about a timer lib named "ltimer". I didn't check it but it was presented as better than any other. I guess it was win32 only. Maybe Allegro can use the algorithms of that or another nice working one(for matching ports at least) For now, I will stick with Allegro's timers since I don't like using too many external libs together. _____________________________________________________ |
|
Onewing
Member #6,152
August 2005
|
Quote: In short: Allegro timing methods look nice, elegant, and useful, but aren't. I only use them as fallback when other methods aren't available. So, should I just keep to the clock() (time.h) functions instead? ------------ |
|
HoHo
Member #4,534
April 2004
|
I think clock() is even worse than allegro timers. If all you need is a variable that gets updated frequently use platform specific stuff. QueryPerformanceCounter on windows and gettimeofday on *nix work perfectly. __________ |
|
Onewing
Member #6,152
August 2005
|
Quote: If all you need is a variable that gets updated frequently use platform specific stuff. QueryPerformanceCounter on windows and gettimeofday on *nix work perfectly. I did a google on QueryPerformanceCounter (being that I've never heard of that before) and noticed that, from microsoft, they say: Quote: However, you can get different results on different processors due to bugs in the basic input/output system (BIOS) or the hardware abstraction layer (HAL). So it's still not going to be perfectly accurate. How comparable to clock() and allegro timer functions is that statement? ------------ |
|
Felipe Maia
Member #6,190
September 2005
|
Steven it's a game, it's not a nuclear station control software. Allegro is more than enough for a game. |
|
Onewing
Member #6,152
August 2005
|
Quote: Steven it's a game
But my game is a nuclear station control software simulation! j/k Nah, I just find all of this interesting and want to know as much as possible to make the most efficient game that I can. ------------ |
|
HoHo
Member #4,534
April 2004
|
Quote: So it's still not going to be perfectly accurate. I think that doesn't stop almost every professional game developer from using it As fro clock, this s what manual says about it: Note that the time can wrap around. On a 32bit system where CLOCKS_PER_SEC equals 1000000 this function will return the same value approximately every 72 minutes. On several other implementations, the value returned by clock() also includes the times of any children whose status has been collected via wait() (or another wait-type call). Linux does not include the times of waited-for children in the value returned by clock(). The times() function, which explicitly returns (separate) information about the caller and its children, may be preferable. I don't remember the granuality of it but I think it was quite bad. The CLOCKS_PER_SEC usually don't mean anything because: __________ |
|
Onewing
Member #6,152
August 2005
|
Quote:
On a 32bit system where CLOCKS_PER_SEC equals 1000000 this function In my timer method above, I used the abs() of the difference for this very reason. Nonetheless, I'm going to see if I can't get the QueryPerformanceCounter to work in place of the timer. Thanks for the info, Hoho! ------------ |
|
Tobias Dammers
Member #2,604
August 2002
|
Up until now, I have found only three methods that produce smooth animation. --- |
|
Onewing
Member #6,152
August 2005
|
Number 3 appears to be the most efficient, not to mention clear. EDIT: I'd give you and HoHo cookies, but I don't know if I can since I didn't make the right kind of thread (unless I can change that). ------------ |
|
gnolam
Member #2,030
March 2002
|
Quote: EDIT: I'd give you and HoHo cookies, but I don't know if I can since I didn't make the right kind of thread (unless I can change that). Try these: http://www.twinkies.com/images/box_hohos.jpg HoHos -- |
|
Tobias Dammers
Member #2,604
August 2002
|
Yum. On a side note, these have been known to me as "Cadbury's Mini Rolls" since that one holiday I spent cycling the south coast or Ireland. Although I did at least 60 km's a day with heavy luggage, I gained something like 3 to 5 kg's. Damn you, Mini rolls! --- |
|
HoHo
Member #4,534
April 2004
|
heh, they look tasty __________ |
|
|
1
2
|