Sign in to follow this  

Game Timing

This topic is 2004 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi,

I'm a student developer and I had a question for everyone regarding the best practices for timing things in-game.

Say, for example, that I had a heal button which heals the player-character. There are to be n milliseconds between when the heal button was last pressed, and when it's available to be pressed again.

In my last project, I simply created an int for each cooldown effect which gets set to n milliseconds and decremented every tick while it's greater than 0. If it's less than 0, that power is available again. This method, though, makes a lot of assumptions about the clock rate of the computer running the program. Can someone point me toward some reading or explain a better solution for timing things in-game?

Share this post


Link to post
Share on other sites
Why not get the system time, in milliseconds?
So, when you hit the heal button, you store the current milliseconds + the time before the next heal can be used as the cooldown timer. Then, you just check if the current time has past the stored cooldown time. If it hasn't, then you can't heal.

Be sure to use an unsigned int (or, uint32_t)

Share this post


Link to post
Share on other sites
Going off of what BeerNutts said, here's how you can get the current time from the start of the executable in millaseconds, taking into account clock speeds:
[code]unsigned int RunTime()
{
//CPU "ticks" since the program started.
clock_t programTickCount = clock();

//Conversion rate between ticks and millaseconds.
float msMultiplyer = 1000.0f / CLOCKS_PER_SEC;

//Convert from ticks to seconds.
int millaSeconds = (programTickCount * msMultiplyer);

return millaSeconds;
}[/code]

Sometimes, if you don't need accuracy, it's nicer to deal with the number as a float where 1.0f equals 1 second.
[code]//The time, in seconds, since the program started. (1.5f = one and a half seconds)
float RunTimeInSeconds()
{
//CPU "ticks" since the program started.
clock_t programTickCount = clock();

//Convert from ticks to seconds.
float seconds = float(programTickCount) / CLOCKS_PER_SEC;

return seconds;
}[/code]

This is standard C++, requiring no external APIs.[b] clock()[/b], [b]clock_t[/b], and the [b]CLOCKS_PER_SEC[/b] #define are all contained in the standard <ctime> header (From the old C standard library, I guess).

This gives millasecond ([size=2]1/1000 of a second[/size]) accuracy, which is plenty fine for my needs. Some people need microsecond ([size=2]1/1000,000[/size][size=2] of a second[/size]) accuracy depending on their projects, and then you have to go into non-standard APIs to get that. Edited by Servant of the Lord

Share this post


Link to post
Share on other sites
First of all: is your game trying to run at a fixed framerate or at a variable framerate?

If the former, whatever controls the framerate will just tell the game to execute multiple logic frames if it's going too slow (and to do nothing if it's going too fast). In this case you can easily just keep using your current method (albeit counting frames instead of milliseconds), since your game logic doesn't care.

If the latter, you'll need to keep track of when the cooldown started and then compare it against the current time. Use the difference to know if the cooldown expired or not (and if not, how much time is left before it expires).

Share this post


Link to post
Share on other sites
What I do is each of my game objects can register a delegate/functor with a global time manager, and each frame every object that registered for time events gets a callback with the time elapsed since the last update. I use a floating point number to express the time elapsed in seconds for clarity.

So for your case I would have something like this:

[CODE]
void HealButton::onClick()
{
heal();
startCooling(_timeToCool);
}

void HealButton::onTime( F32 timeDelta )
{
if (isCooling())
{
_coolTimeRemaining -= timeDelta;
if (_coolTimeRemaining < 0)
{
_coolTimeRemaining = 0;
stopCooling();
}
}
}

[/CODE]

Share this post


Link to post
Share on other sites
Thank you for the replies, everyone!

[quote name='BeerNutts' timestamp='1340053151' post='4950377']
[left][background=rgb(250, 251, 252)]So, when you hit the heal button, you store the current milliseconds + the time before the next heal can be used as the cooldown timer. Then, you just check if the current time has past the stored cooldown time. If it hasn't, then you can't heal.[/background][/left]

[/quote]

That's a good idea, and it's much simpler than the way I was doing it. I'll have to use this method from now on instead of my silly decrementation method.

[quote name='Sik_the_hedgehog' timestamp='1340070224' post='4950452']
First of all: is your game trying to run at a fixed framerate or at a variable framerate?
[/quote]

This was more of a general best-practices question than relating to a specific example, but thank you for the explanation regarding the differences [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img]

[quote name='krippy2k8' timestamp='1340080593' post='4950484']
What I do is each of my game objects can register a delegate/functor with a global time manager, and each frame every object that registered for time events gets a callback with the time elapsed since the last update. I use a floating point number to express the time elapsed in seconds for clarity.
[/quote]

This answer touches more on what I was thinking about when I asked the question. I've gotten into the practice of using managers (input manager for handling keyboard events, image manager for asset IO, etc). That got me wondering if people knew of any good patterns or code structures (i.e. timing manager) that would be good for handling cooldowns (or any timing-related problem, like length of time for a camera to pan during a cinematic, or something), and what functions or methods a utility timing class would have. Edited by AesteroidBlues

Share this post


Link to post
Share on other sites
The best way to make 0 assumptions is to remember what time it was the last time you updated your game state and what time it is when you start the new update.
Any time based logic then will ask for the difference between the two times, this will give out reliable results regardless of the processor speed and application performance.

It also makes any cinematic (in the meaning of physics, not cinematic videos) formula, like speed based movement or acceleration will have the Delta Time available to provide accurate results.

Share this post


Link to post
Share on other sites

This topic is 2004 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this