Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I was working on my game loop and I came across an odd problem. The loop was working fine, my states could render, received updates, etc. I then proceeded to create my Input system, which, also works. However, after implementing that I continually & randomly receive a Exception in my thread stating: Exception in thread "Thread-3" java.lang.IllegalArgumentException: timeout value is negative

I first tried to debug this. The problem is there is 0 consistency with the exception occurring. KeyEvents seem to have no affect, due to the fact I can use the poll system & not generate an exception. That & sometimes upon running it automatically throws an exception. I've re-looked through the code and I'm not quite sure what is causing this.

For convenience I'll just leave the relevant code.

public class Game implements Runnable {

public int FPS = 0;

private Double delta;
private long lastFps = 0;

private final int TARGET = 60;
private final long OPTIMAL_TIME = 1000000000 / TARGET;   
private boolean gameRunning = false;

@Override
public void run() {

    long lastLoop = System.nanoTime();

    while (gameRunning){

        //Figure out how long its been since last update - used for entity calculation
        long current = System.nanoTime();
        long updateTime = current - lastLoop;
        lastLoop = current;

        delta = updateTime / ((double)OPTIMAL_TIME);

        lastFps += updateTime;
        FPS++;

        if(lastFps >= 1000000000){
            System.out.println("(FPS: "+ FPS +")");
            lastFps = 0;
            FPS = 0;
        }

        //Updates state + calls render
        updateState();

        /*
         * We need each frame to take 10mill-sec
         * Take recorded time + 10 milli
         * then factor current time
         * this ^ is final value to wait
         */
        try{
            Thread.sleep( (lastLoop - System.nanoTime() + OPTIMAL_TIME) /1000000 );
        }
        catch(InterruptedException exception){
            exception.printStackTrace();
        }



    }

}

Unless the KeyEvent's could possibly have relation to the problem or my input polling (Which doesn't manage time or anything affecting the thread) I'm not sure if it's needed to post any relevant code from that class. (If you think I need to you're welcome to ask but it's just boolean arrays + a string cache).

The question: Why is the thread encountering a negative timeout value?

share|improve this question
    
Why are you using nano-scale time? Isn't micro-scale time good enough? –  Raceimaztion Aug 23 '12 at 6:51
    
From my own practice/reading I was more used to using Nano scale. Does it make a big difference/should I change it? –  thedeadlybutter Aug 23 '12 at 7:05
    
The documentation for Java 6 says that it provides nano-scale precision, but does not guarantee nano-scale accuracy. The documentation for currentTimeMillis() also mentions that some OSes only measure time in 10 millionths of a second. –  Raceimaztion Aug 23 '12 at 18:12
add comment

2 Answers

up vote 1 down vote accepted

Your problem is in the line that performs the sleep operation:

Thread.sleep( (lastLoop - System.nanoTime() + OPTIMAL_TIME) /1000000 );

Remember that System.nanoTime() will almost always be after the last-recorded time stored in lastLoop, so you need to reverse those two expressions.

share|improve this answer
    
Ah forgot about that. However I was a little curious & looked in to the problem more, turns out it was a "rounding" problem, or appeared to be. Which made it have negative numbers. Using Micro-Time has solved the problem, so I do not think I do this. –  thedeadlybutter Aug 24 '12 at 1:00
add comment

Okay fixed the problem. As suggested by a friend + comment I should be using MicroTime which has appeared to solve the problem. For anyone looking for how I solved it, I just changed these 2 lines to this:

long current = System.currentTimeMillis();

Thread.sleep( (lastLoop - System.currentTimeMillis() + OPTIMAL_TIME) /1000000 );
share|improve this answer
1  
If you have solved this problem you should accept the answer. –  ChargingPun Aug 23 '12 at 18:10
    
It won't let me accept my own answer so I was waiting for this time limit to expire. Doesn't matter I guess, the other answer also works so I just marked that one. –  thedeadlybutter Aug 24 '12 at 13:52
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.