Jump to content

  • Log In with Google      Sign In   
  • Create Account


Why do games keep track of ticks?


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
17 replies to this topic

#1 warnexus   Prime Members   -  Reputation: 1231

Like
0Likes
Like

Posted 16 April 2013 - 09:18 PM

I am not entirely sure but I did some research beforehand: reading some code comments from a different programming language I never used and method description of the method

 

From what I can legitimately gather this is what I can sum up based on my research:

1) Games run in real time. Different from procedural programming. 

2) Games run in a time based tick. 

3) Games run in frames per second.

 

It is a totally a different realm of programming from what I did in my introduction to java course in college.

So I have a question: 

 

The game codebase is in Java and it contains no comments. 

 

It declare a variable that keeps track of the current time in the game constructor(where all game objects are created beforehand)

 

lastTick = System.currentTimeMillis();
 
in the game loop it contains this part:
 
long milliseconds = System.currentTimeMillis() - lastTick;
lastTick = System.currentTimeMillis();
 

So the question comes up: why exactly does this time based tick work? The method description from what I gather although it explains it in technical detail makes a statement about an operating system having an internal clock. 

 

Why does an operating system have an internal clock and why do game use the OS internal clock to keep track of time? Why keep track of current time in the game constructor and update that time during the game loop? The idea is still foreign and fuzzy to me.

 

 

 
 

Edited by warnexus, 16 April 2013 - 09:20 PM.


Sponsor:

#2 kburkhart84   Members   -  Reputation: 1461

Like
0Likes
Like

Posted 16 April 2013 - 09:49 PM

Well, there are three problems off the top of my head that using a "clock time" based system could have.  First, the lowest unit the regular clock has is seconds, and games run typically at 60 frames per second, so you can't get the accuracy that you need.  And second, if you are playing a game just before midnight, the clock goes from 23:59:59 to 00:00:00, and if your game didn't allow for this without bugging out, you'd be in trouble.  So it is best to go with something that works better.  And lastly(that I know of) if the game depends on the clock, and the player decides to fiddle with the clock during game play, it could allow cheats of some sort(using software to slow down the clock or some other control) or it could simply cause some bugs or freezing depending on the game.

 

Note that by using ticks since system start, or since game start, you avoid these 3 problems.  It takes one heck of a hacker to tinker with processor tick counting, though I'm sure its possible in some form like about anything.





#3 Nypyren   Crossbones+   -  Reputation: 3418

Like
4Likes
Like

Posted 16 April 2013 - 10:17 PM

Because computers have processors with different processing speeds.

Really old games often didn't do any timing - they assumed the CPU was 33 MHz or whatever, and would run correctly at that speed. But if you installed one of those games on a much newer processor, say a 133 MHz, the game would run so fast that the player couldn't react quickly enough anymore, because the processor could do 4 times the work in the same amount of real-world time.

So, modern games use the system clock to try to keep the game the same no matter what processor the player owns. There are generally two approaches:

1. Each frame of the game is assumed to take X real-world milliseconds. Each subsystem of the game performs a slice of work corresponding to X milliseconds. The game loop then attempts to align the work performed to real-world time so that the game doesn't stutter. (Fixed timestep game)

2. Each frame of the game is processed as fast as possible, no waiting. The game measures the time the last frame took to process, and passes that 'time delta' value to the various subsystems for the current frame. The frame is then rendered immediately and the next frame begins without waiting. (Variable timestep game)

Edited by Nypyren, 16 April 2013 - 10:21 PM.


#4 AllEightUp   Moderators   -  Reputation: 3892

Like
0Likes
Like

Posted 16 April 2013 - 11:17 PM

Well, beyond what the others said, I have three reasons to run using multiple concepts of time:

 

1.  "Delta time" between frames is the primary measurement I care about in most game related objects.  How far I moved, turned etc.

2.  "Time since game start".  Anytime you need a 'I will last for x seconds' you need to have some concept of 'now', time since started is that reference.  (NOTE: you may think to just use supplied OS concepts of 'now', that would be bad, what about 'pause'?  You don't reset the OS clock, it might get pissed at ya. smile.png)

3.  "Ticks", or I usually just use frame count.  Many algorithm's have to explore data structures and update things without a concept of time.  They only care about 'dirty' or not but a simple flag may not be enough sometimes.  Using a tick count, explorative algorithms are able to figure out if they are visiting something they have already processed, something which is really out of date and should be prioritized or something which was computed last frame and can be ignored for a bit.  This is just one of many examples I could come up with, time is not important, but knowledge of relative age is.

 

Other concepts of time exist, but I'm pretty sure they can all be calculated from one of the above.


Edited by AllEightUp, 17 April 2013 - 12:02 AM.


#5 warnexus   Prime Members   -  Reputation: 1231

Like
0Likes
Like

Posted 17 April 2013 - 09:37 AM

Well, beyond what the others said, I have three reasons to run using multiple concepts of time:

 

1.  "Delta time" between frames is the primary measurement I care about in most game related objects.  How far I moved, turned etc.

Change in time between frames. Thanks for the explanation.



#6 KnolanCross   Members   -  Reputation: 1064

Like
0Likes
Like

Posted 17 April 2013 - 10:17 AM

Two advantages I can tell you by my experience:

Most "game engines" are actually graphics engines and when you are dealing with really heavy performance cost operations, having the tick counts is usefull as their payload is lower than the clock related functions.

Also, you can use then to find the amount of times some function was called, which is useful when you are trying some algorithms to reduce the search space.


My blog on programming and games.
http://16bitsflag.blogspot.com.br/

#7 MichaelNIII   Members   -  Reputation: 195

Like
0Likes
Like

Posted 17 April 2013 - 04:36 PM

You can also use your avarage tick count to help with prerending depending on what kind of game your making. Also hacking this is simple - just a queryperformancecounter detour. But don't worry about any of that - it doesn't matters if they cheat besides in mmo's and this one is pretty easy to detect server side if you ever have that issue.

#8 L. Spiro   Crossbones+   -  Reputation: 9763

Like
0Likes
Like

Posted 17 April 2013 - 04:40 PM

A few things need to be mentioned.

 

having the tick counts is usefull as their payload is lower than the clock related functions.

You can also use your avarage tick count to help with prerending depending on what kind of game your making. Also hacking this is simple - just a queryperformancecounter detour. But don't worry about any of that - it doesn't matters if they cheat besides in mmo's and this one is pretty easy to detect server side if you ever have that issue.

The original poster was not clear on this at all but he was actually talking about the ticking of the game logic. A function called Tick() that calculates how much time since the last Tick() and runs accordingly. Because he did not make this clear, many replies were thrown off target.


To warnexus, while you got the answer you sought (delta time between Tick()’s), be aware that milliseconds are unacceptable for this purpose. You should always use microseconds.


L. Spiro
It is amazing how often people try to be unique, and yet they are always trying to make others be like them. - L. Spiro 2011
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
I went to my local Subway once to find some guy yelling at the staff. When someone finally came to take my order and asked, “May I help you?”, I replied, “Yeah, I’ll have one asshole to go.”
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums

#9 BGB   Crossbones+   -  Reputation: 1460

Like
0Likes
Like

Posted 17 April 2013 - 08:40 PM

for things like game logic, I usually accumulate deltas, and run game-ticks so long as the (accumulated-current) time is >= the tick-length.

 

a downside I have found of this is that these sorts of timers do tend to drift by a slight amount, which in some cases may need to be accounted for (such as for sound-mixing or video-recording, where after a little while the drift between the accumulated times and real-time can become potentially significant, requiring a sort of "detect and re-align" handler, say, whenever the drift (accumulated-real) exceeds 100ms or so).

 

granted, typically I have also been using milliseconds here (for things like delta-times and similar), but typically a float is used for the current (actual) time.

microseconds and doubles could probably be more accurate (and reduce the need for realigns), but oh well...


Edited by cr88192, 17 April 2013 - 08:41 PM.


#10 warnexus   Prime Members   -  Reputation: 1231

Like
0Likes
Like

Posted 17 April 2013 - 09:34 PM

A few things need to be mentioned.

 

having the tick counts is usefull as their payload is lower than the clock related functions.

>>>

You can also use your avarage tick count to help with prerending depending on what kind of game your making. Also hacking this is simple - just a queryperformancecounter detour. But don't worry about any of that - it doesn't matters if they cheat besides in mmo's and this one is pretty easy to detect server side if you ever have that issue.

The original poster was not clear on this at all but he was actually talking about the ticking of the game logic. A function called Tick() that calculates how much time since the last Tick() and runs accordingly. Because he did not make this clear, many replies were thrown off target.


To warnexus, while you got the answer you sought (delta time between Tick()’s), be aware that milliseconds are unacceptable for this purpose. You should always use microseconds.


L. Spiro

 

Which purpose for games? Why microseconds? Since milli is 10^-3 and micro is 10^-6. That would mean I need to code like this: (System.currentTimeMillis * Math.pow(10,-3). Can I do it this way?


Edited by warnexus, 17 April 2013 - 09:35 PM.


#11 L. Spiro   Crossbones+   -  Reputation: 9763

Like
0Likes
Like

Posted 17 April 2013 - 09:57 PM

a downside I have found of this is that these sorts of timers do tend to drift by a slight amount, which in some cases may need to be accounted for

This should never happen if you are careful about how you store these accumulators.

#1: Do not accumulate in any form of floating-point value. Always use a 64-bit unsigned integer.
#2: Accumulate in the system’s native tick resolution. Always re-derive the current microseconds based off that. Keep those for the current frame and last frame and use that to determine how many microseconds since the last frame, but always determine the actual current microseconds based on the actual unmodified system tick time that has passed since your timers began.

If you take the system tick time, subtract the last time time and convert that to microseconds since the last frame, and accumulate that, you will definitely get drift.
So #2 is very important.

On Windows it requires a custom 128-bit integer class with division and multiply operators since the tick resolution on Windows is so high.
When converting, always perform the multiply (by 1000000ULL in this case) first (which will easily overflow 64-bit integers on Windows, hence the need for a custom 128-bit integer) and then divide by the resolution.

Again, always accumulate the raw ticks, not ticks converted to microseconds.


L. Spiro
It is amazing how often people try to be unique, and yet they are always trying to make others be like them. - L. Spiro 2011
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
I went to my local Subway once to find some guy yelling at the staff. When someone finally came to take my order and asked, “May I help you?”, I replied, “Yeah, I’ll have one asshole to go.”
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums

#12 L. Spiro   Crossbones+   -  Reputation: 9763

Like
0Likes
Like

Posted 17 April 2013 - 10:03 PM

warnexus, on 18 Apr 2013 - 12:25, said:
Which purpose for games? Why microseconds? Since milli is 10^-3 and micro is 10^-6. That would mean I need to code like this: (System.currentTimeMillis * Math.pow(10,-3). Can I do it this way?

No, that doesn’t increase the resolution of your timer, just addeds 3 0’s to it.

The reason you need to measure time in microseconds is because the framerate easily gets above 1,000 FPS these days. On my engine with my old graphics card I could easily get 13,000 FPS in some cases. That would be 0 milliseconds. Even if you multiplied that by 1,000, it would be 0 × 1,000, which equals 0.

You have to get the raw time in microseconds from the start.

But if you are just working in Java it is unlikely you need to worry too much about this. This will be more relevant when you get into real graphics processing down the road.


L. Spiro
It is amazing how often people try to be unique, and yet they are always trying to make others be like them. - L. Spiro 2011
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
I went to my local Subway once to find some guy yelling at the staff. When someone finally came to take my order and asked, “May I help you?”, I replied, “Yeah, I’ll have one asshole to go.”
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums

#13 warnexus   Prime Members   -  Reputation: 1231

Like
0Likes
Like

Posted 17 April 2013 - 10:49 PM

warnexus, on 18 Apr 2013 - 12:25, said:
Which purpose for games? Why microseconds? Since milli is 10^-3 and micro is 10^-6. That would mean I need to code like this: (System.currentTimeMillis * Math.pow(10,-3). Can I do it this way?

No, that doesn’t increase the resolution of your timer, just addeds 3 0’s to it.

The reason you need to measure time in microseconds is because the framerate easily gets above 1,000 FPS these days. On my engine with my old graphics card I could easily get 13,000 FPS in some cases. That would be 0 milliseconds. Even if you multiplied that by 1,000, it would be 0 × 1,000, which equals 0.

You have to get the raw time in microseconds from the start.

But if you are just working in Java it is unlikely you need to worry too much about this. This will be more relevant when you get into real graphics processing down the road.


L. Spiro

Okay. I will bear in mind about this. Yup the codebase is in Java.



#14 BGB   Crossbones+   -  Reputation: 1460

Like
0Likes
Like

Posted 21 April 2013 - 01:10 PM

a downside I have found of this is that these sorts of timers do tend to drift by a slight amount, which in some cases may need to be accounted for

This should never happen if you are careful about how you store these accumulators.

#1: Do not accumulate in any form of floating-point value. Always use a 64-bit unsigned integer.
#2: Accumulate in the system’s native tick resolution. Always re-derive the current microseconds based off that. Keep those for the current frame and last frame and use that to determine how many microseconds since the last frame, but always determine the actual current microseconds based on the actual unmodified system tick time that has passed since your timers began.

If you take the system tick time, subtract the last time time and convert that to microseconds since the last frame, and accumulate that, you will definitely get drift.
So #2 is very important.

On Windows it requires a custom 128-bit integer class with division and multiply operators since the tick resolution on Windows is so high.
When converting, always perform the multiply (by 1000000ULL in this case) first (which will easily overflow 64-bit integers on Windows, hence the need for a custom 128-bit integer) and then divide by the resolution.

Again, always accumulate the raw ticks, not ticks converted to microseconds.


L. Spiro

 

part of the problem I think is because:

the actual ticks are read as milliseconds. and accumulated via deltas;

most of the actual "work" is done using 32-bit floats (calibrated in seconds).

 

changing things over to using integers would be a big pain (would effect many parts of the engine), although switching over to doubles could be done a little more easily, and I could probably go write something to fetch the current time in microseconds as well (this would be mostly invisible if using double). (I have already since moved over to doubles for things like object positions, ... mostly as world sizes were getting big enough that jitter was becomming an issue, ...).

 

 

luckily, apart from things like audio-mixing, the drift isn't really all that noticable (mostly as audio is a bit more sensitive to time-drift than is general rendering or game-tick stuff).



#15 mhagain   Crossbones+   -  Reputation: 6367

Like
1Likes
Like

Posted 21 April 2013 - 01:46 PM

Even aside from the > 1000 fps consideration (which is valid), measuring in milliseconds is still broken with more typically-seen framerates.  The most common monitor refresh rate nowadays is 60 Hz, which is impossible to accurately represent in milliseconds alone - 16 ms is 62.5 fps, 17 ms is 58.82... ms.  So if you're running with vsync enabled you'll get an inaccurate time measurement (most of the time), if you're running with it disabled you're not going to accurately hit your target framerate (unless you pick a target that divides into 1000 evenly).


It appears that the gentleman thought C++ was extremely difficult and he was overjoyed that the machine was absorbing it; he understood that good C++ is difficult but the best C++ is well-nigh unintelligible.


#16 TheChubu   Crossbones+   -  Reputation: 3081

Like
1Likes
Like

Posted 21 April 2013 - 02:09 PM

Games are very overzealous of their ticks, that's why they keep track of them at all times.


"I AM ZE EMPRAH OPENGL 3.3 THE CORE, I DEMAND FROM THEE ZE SHADERZ AND MATRIXEZ"

 

My journal: Making a Terrain Generator


#17 L. Spiro   Crossbones+   -  Reputation: 9763

Like
0Likes
Like

Posted 21 April 2013 - 04:26 PM

part of the problem I think is because:
the actual ticks are read as milliseconds. and accumulated via deltas;
most of the actual "work" is done using 32-bit floats (calibrated in seconds).

The main problem is how you are reading time. Systems don’t usually return time in milliseconds (and using milliseconds instead of microseconds is another problem), so you are doing some kind of conversion between getting the clock time and returning a millisecond value from a function.

Don’t do the conversion there. The basic problem is just the location of the conversion between system time and milliseconds )or preferably microseconds).
You can still accumulate by deltas even if they are only microsecond or millisecond resolutions. The problem is the conversion point, which currently does not gain back any microseconds or milliseconds it loses to rounding errors. That is why you must accumulate native system ticks and re-derive the current microseconds each frame, as that is the only way to put rounded-off microseconds from the previous frame onto the current frame.

Time should be managed by a class that does nothing but manage time and its conversions (from ticks to microseconds, deltas to floating-point seconds, etc.) If it is difficult to switch over, there may be other problems with your structure.
It may take work, but it is just the right thing to do and it will be worth it in the long run.


L. Spiro

Edited by L. Spiro, 21 April 2013 - 04:29 PM.

It is amazing how often people try to be unique, and yet they are always trying to make others be like them. - L. Spiro 2011
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
I went to my local Subway once to find some guy yelling at the staff. When someone finally came to take my order and asked, “May I help you?”, I replied, “Yeah, I’ll have one asshole to go.”
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums

#18 RobMaddison   Members   -  Reputation: 608

Like
0Likes
Like

Posted 30 April 2013 - 01:17 AM

13,000 FPS...?




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.



PARTNERS