Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (517)
Games in Android Showcase (123)
games submitted by our members
Games in WIP (577)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Gamer Timers and Animation Loops  (Read 1887 times)
0 Members and 1 Guest are viewing this topic.
Offline rackham

Junior Duke





« Posted 2009-05-12 12:31:21 »

Hello everyone, I have a question which i have seen asked a few times on this and other forums but I cant seem to find a good answer for it!

I want to use a higher resultion timer or clock reading method with a better granularity than that of System.currentTimeMillis(), I have seen the use
of System.nanoTime() recommended a few places, but have also read that it has problems when using multi core (usually athlon) systems, which can lead to useless results. Does anyone know the scale of this error, a few nanoseconds here and there wouldnt bother me at all, but if it is really inaccurate then i wouldnt be able to use it.

Is their a better alternitive?

I just really want it for measuring my FPS and UPS in my game accuralty to achive a consistant UPS, any help or info would be much appreciated!

Thanks  Huh

Offline sgaffga

Junior Newbie





« Reply #1 - Posted 2009-05-12 12:53:46 »

Hi!

I'm calculating the FPS from the nanoTime()-Value, but only after a number of frames have been drawn and a minimum amount of time elapsed.

The FPS value changes quite frequently - it is difficult to adjust the game speed to it without having occasionally things "bumping" and "hopping" around... So I calculate a smoothed FPS value as well: smoothFPS.


numFrames++;

final long now = System.nanoTime();

// 1 nanosecond  = 1e-9 seconds
// 1 microsecond = 1e-6 seconds = 1e3 * nanoseconds
// 1 millisecond = 1e-3 seconds = 1e6 * nanoseconds

// Only update the FPS value if enough happend in the meantime
if ( now-lastTime > 1e7  && numFrames>10 ) {
    // Enough time or frames since last update - now calculate the new FPS value
    fps = numFrames * 1000.0f / ((now-lastTime)/1000000.0f);
    numFrames=0;
    lastTime = now;
   
    // Smooth the FPS over the last 200 frames...
    smoothFPS = 199.0f/200.0f * smoothFPS + 1.0f/200.0f * fps;
}


Greetings
Stefan

Offline rackham

Junior Duke





« Reply #2 - Posted 2009-05-12 13:00:35 »

Hello, thanks for you reply, you dont comment on the nanoTime() reliability, that was specifically what my post was regarding, of what should be used instead of it because of the multiple processor issue! Smiley

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline sgaffga

Junior Newbie





« Reply #3 - Posted 2009-05-12 13:11:14 »

Oh yes, sorry...

I did not ran into any problems with nanoTime yet. My approach was tested on single, dual- and quad-core Intel machines without any problems.  (but no testing on Athlons was performed yet)

Having around 1000 FPS on the quad-core machine, the timing is still very accurate in the way that the gameplay feeling gives no indications that a timer resolution problem exists.

Greetings
Stefan

Offline rackham

Junior Duke





« Reply #4 - Posted 2009-05-12 13:16:54 »

excellent, thanks for the insight! 1000fps is pretty hefty, i imagine it's a typo Tongue

Ill have another look into it, thanks!

Offline Darrin

Junior Duke


Projects: 1



« Reply #5 - Posted 2009-05-12 14:56:52 »

Hi,

I wrote up my tests on java timers.  You can find the whole article here.

http://darrinadams.blogspot.com/2009/04/timers.html

The bottom line is that to be semi accurate, given the bugs and OS conflicts, you have to be off multiples of 10 like 11, 21, 32, etc.   It can't be 10, 20, 30.   Milliseconds is just as good as if not better than nano or even third party as long as you set it up correctly.

I hope it helps.

Darrin

Offline oNyx

JGO Coder


Medals: 2


pixels! :x


« Reply #6 - Posted 2009-05-12 19:07:09 »

LWJGL's timer is the most robust one. It's TGT (time get time) with a resolution of 1msec. On Linux and Mac currentTimeMillis is used under the hood, which also results in a resolution of 1msec.

nanoTime uses QPC (query performance counter), which has some issues on some machines.

On my old 500mhz machine I got so called QPC-leaping, which basically means that the timer will randomly jump a few seconds into the future whenever there is some bus load. With the Nvidia graphics card everything was fine, but the ATI one triggered the issue for reasons unknown to me. I guess it either caused more bus load or the usage pattern was different. (Using nanoTime in command line programs worked fine for example.)

Well, that's just one of the QPC issues. IIRC there are like 5 different ones. TGT on the other hand only got one problem (IIRC), which only occurs on some 20-25 year old mainboards. So yea, it's a rather robust timer.

弾幕 ☆ @mahonnaiseblog
Offline DzzD
« Reply #7 - Posted 2009-05-12 21:20:02 »

in some case it may be practical to achieve smart UPS using a low granularity timer as System.currentTimeMillis()  and an uncontrolled FPS loop.

logic is only updated when a new frame is being rendered

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
   
   
private long gameLogicLastTime=-1;
   
//Logic update rate = 10 ms
private long gameLogicRate=10;


//Your main rendering Thread
public void run()
{
   //Uncontrolled FPS loop
   while(this.mustRun)
   {
      this.doLogic();  
      this.diplay();
      Thread.yield();
   }
}

//Perform game logic for elapsed time
public void doLogic()
{
   long time=System.currentTimeMillis()
   
   //First call ?
   if(this.gameLogicLastTime==-1)
   {
      this.gameLogicLastTime=time;
      return;
   }
   
   //Compute elapsed time since last game logic
   long elapsedTime=time-this.gameLogicLastTime;
   
   
   //If elapsed time lower than logic rate return
   if(elapsedTime<this.gameLogicRate)
      return;
     
   
   //Compute number of game logics to perform  
   int nbGameLogic=(int)(elapsedTime/this.gameLogicRate);


   for(int gameLogicCount=0;gameLogicCount<nbGameLogic;gameLogicCount++)      
      this.doLogicOnce();  
   
   this.gameLogicLastTime+=nbGameLogic*this.gameLogicRate;      
}

//Perform game logic for 10 ms (gameLogicRate)
public void doLogicOnce()
{

}  

//Render game graphics
public void display()
{

}
   

Offline rackham

Junior Duke





« Reply #8 - Posted 2009-05-13 07:35:00 »

LWJGL's timer is the most robust one. It's TGT (time get time) with a resolution of 1msec. On Linux and Mac currentTimeMillis is used under the hood, which also results in a resolution of 1msec.


Aha, good to know there is something out there which can work, i was gettting worried. I was trying to find it for an applet, but i am not famililiar with the LWJGL, it seems it might not be the easiest thing to use with applets (but i could be wrong, ill have to have a read)

Anyone know off hand if pulpcore implements any good useable timers

Offline bobjob

JGO Knight


Medals: 10
Projects: 4


David Aaron Muhar


« Reply #9 - Posted 2009-05-13 07:50:03 »

in java 1.4+
there is the un documented timer

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
import sun.misc.Perf;

 public static long getTime() {
  return  p.highResCounter();
 }
 
 private static Perf p = Perf.getPerf();
 public static long sync(int fps, long timeThen) {
  long gapTo =  p.highResFrequency() / fps + timeThen;
  long timeNow = p.highResCounter();
     
  while (gapTo > timeNow) {
   try {
    Thread.sleep(1);
   } catch (InterruptedException e) {}
   timeNow = p.highResCounter();
  }
  return timeNow;
 }


1  
long timeThen =  p.highResCounter(); //init call


1  
timeThen = sync(fps, timeThen); //sync call (I personally set fps = 60)


and the best one you can get with the default api 1.5+ is nanoTime()

This code doesnt really measure FPS like you want. It will just cap the game speed to a disired frame rate.

If you would like source code of how to make an LWJGL sync timer without having to make a call to Display creat just ask, but LWJGL needs to be signed for applets so its not that user friendly.

My Projects
Games, Webcam chat, Video screencast, PDF tools.

Javagaming.org with chat room
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline rackham

Junior Duke





« Reply #10 - Posted 2009-05-13 08:23:55 »

No, user friendly is always key!

Anyone know off their head how the pulpcores platform specific calls to CoreSystem.getTimeMillis() and getTimeMicros are implmented?

Isnt it a risk using sun.misc.Perf as it could be removed in a newer java version?

Offline bobjob

JGO Knight


Medals: 10
Projects: 4


David Aaron Muhar


« Reply #11 - Posted 2009-05-13 11:15:11 »

its possible to implement multiple methods, and check the java version at runtime.

My Projects
Games, Webcam chat, Video screencast, PDF tools.

Javagaming.org with chat room
Offline tom
« Reply #12 - Posted 2009-05-13 15:21:57 »

sun.misc.Perf uses the same timer as nanoTime(), so it will have the same problems. I had a problem with TGT in LWJLG where the resolution degraded to around 15ms in some situations. This was on a 6-7 year old computer.

I don't think there is a timer that works on all computer. The best solution would be to do an analysis when the app start and select the best time. Should find some c code that does this if you google.

Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

TehJavaDev (38 views)
2014-10-27 03:28:38

TehJavaDev (29 views)
2014-10-27 03:27:51

DarkCart (43 views)
2014-10-26 19:37:11

Luminem (24 views)
2014-10-26 10:17:50

Luminem (29 views)
2014-10-26 10:14:04

theagentd (35 views)
2014-10-25 15:46:29

Longarmx (63 views)
2014-10-17 03:59:02

Norakomi (61 views)
2014-10-16 15:22:06

Norakomi (50 views)
2014-10-16 15:20:20

lcass (46 views)
2014-10-15 16:18:58
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!