0

How should we make fixed timestep in Java? I think there are 2 ways:

  1. Synchronised game loop using while.
  2. Asynchronised game loop using Thread.

The most important thing is performance and accuracy. So what's the best way?

This is synchronised game loop:

    double timeStep = world.getSettings().getStepFrequency();
    long lastTime = System.nanoTime();

    while (true) {
        long currentTime = System.nanoTime();
        double elapsedTime = (currentTime - lastTime) / 1000000000.0;

        if (elapsedTime >= timeStep) {
            lastTime = currentTime;
            world.update(elapsedTime);
        }
    }

This is asynchronised game loop:

    double timeStep = world.getSettings().getStepFrequency();
    long lastTime = System.nanoTime();

    Thread loop = new Thread() {
        public void run() {
            while (true) {
                long currentTime = System.nanoTime();
                double elapsedTime = (currentTime - lastTime) / 1000000000.0;
                lastTime = currentTime;

                world.update(elapsedTime);

                try {
                    Thread.sleep((long) Math.floor(timeStep * 1000));
                } catch (InterruptedException e) {}
            }
        }
    };
    loop.start();

The synchronised game loop uses lots of CPU (I think 1 core? that's ~25% for me).

CPU usage of the asynchronised game loop is almost 0%.

Note: The game I want to do is WebSocket based game. The server is for physics, and HTML5's canvas is for rendering.

What way do you prefer? Why? Is there any better way?

Szymon Marczak
  • 1,055
  • 1
  • 16
  • 31
  • If you want precision, you need the former alternative between these two. Thread.sleep, if no exception, sets a *minimum* amount where the thread is not running. The scheduling may still delay it for an arbitrary amount of time. – Diego Martinoia Sep 28 '16 at 13:35
  • @DiegoMartinoia Yep, but canvas renders at 60FPS, I can set thread to do its job at 120Hz. – Szymon Marczak Sep 28 '16 at 13:38
  • 1
    A Timer seems best. It should be able to "drop frames" if an updateWorld takes too long. – Joop Eggen Sep 28 '16 at 13:47
  • @JoopEggen Please answer the question, if you could :) Why did you choose Timer, pluses, minuses, what's the difference between thread etc.. – Szymon Marczak Sep 28 '16 at 14:14
  • @SzymonMarczak the answer of DavidSN fortunately comes to the point: code plus explanation. A timer has a better scheduling, than reserving a thread and letting it sleep. Also it is more precise. – Joop Eggen Sep 28 '16 at 15:01
  • @JoopEggen Thanks for letting me knowing :) Is there any difference between SheduledExcutorService and Timer? – Szymon Marczak Sep 28 '16 at 15:09
  • 1
    There is a question about the differences between ExecutorService and Timer: http://stackoverflow.com/questions/409932/java-timer-vs-executorservice – David SN Sep 28 '16 at 15:11
  • @DavidSN Thanks :D – Szymon Marczak Sep 28 '16 at 15:12

1 Answers1

4

There are classes in the Java API to execute a task periodically. Its better to not try to reinvent the wheel and use the Java API. A ScheduledExecutorService seems to be what you need.

This example execute a Runnable periodically:

ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
executor.scheduleAtFixedRate(myRunnable, initialDelay, period, TimeUnit.MILLISECONDS);

In your first example, your thread is checking a huge amount of times if elapsedTime >= timeStep is true. It keeps doing the check until it is true, instead of doing this check time after time until it is finally true, the thread could be waiting and the processor could be used for something else.

The second option is better than the first one because the thread waits for the period to the next execution.

David SN
  • 3,389
  • 1
  • 17
  • 21