2
\$\begingroup\$

I was once told that you should never re-draw a frame if the game logic has not changed since the last draw.

Assuming game logic is updated once every tick, and assuming a game runs at 40 FPS @ 20 ticks/second, does that mean that every two consecutive frames will be exactly the same? If so, is there any visual difference between a game running at 40 FPS @ 20 ticks/second versus a game running at 20 FPS @ 20 ticks/second?

Perhaps I don't understand game loops that well, but it seems to me that ticks/second is a limiting factor of FPS.

\$\endgroup\$
  • \$\begingroup\$ Yes, there will be two identical frames assuming there is ABSOLUTELY no change in state while drawing, or no random variations etc. \$\endgroup\$ – Ben Oct 27 '14 at 4:58
  • \$\begingroup\$ So it's pointless to have FPS above updates/second? \$\endgroup\$ – mario_sunny Oct 27 '14 at 5:40
  • 3
    \$\begingroup\$ Not necessarily. It's possible to interpolate the rendering between two states of the world to give apparent smoother motion, for example by using the velocity of objects. \$\endgroup\$ – usm Oct 27 '14 at 6:12
0
\$\begingroup\$

Your engine and your game must be super flexible to allow the possibility of drawing two times with no state change.
A usual game loop ties very closely all updates in a sequential fashion.
One thread, one loop, one point to flush events, one point to execute processing updates (entity/component processors, or simply manager's updates), and finally one render call which triggers the whole engine 1-frame render.

Whole engine 1 frame render can be made in two fashions, extrospective (intrusive), by accessing (with visitors) the state of the drwable objects of the game, and create the rendering states, passes and commands that go with it.

Or it could be fully retained, and the state of the engine was set BY the processors during the logic update, and it holds sufficient information per se to draw a frame in isolation.

This is a classical game loop. It uses a delta_time variable that is given to all managers during update.

If you have a physical manager, usually there is another loop within the Update itself, that will use a fixed dt and iterate as many time to fill the lagging-time to reach delta_time. And store the remainder for the next frame's refresh, to execute as part of the first loop next time.

Now, its possible to have a more advanced game loop by separating event treatments, by using a thread specific system event queue, preparing a pool of timestamped events, and when the main thread is in the event treatment update, it pulls this queue.

Its hardly possible to completely asychronize managers updates and frame rendering. Many engine state updates are not atomic. Even a fully retained engine will have limitations. DirectX11 introduces isolated command lists (deferred devices, in their parlance), which can help to design such an engine. But if you have such basic doubts about your own render loop, I suppose you don't use such things, yet.

Since you are in java, and you talk about ticks, I imagine you must have plugged your refresh function to a periodic timer. Of course this is sub-par as a game loop design, even from the most basic loop design described above. This is not how real time systems are designed, doing this, you rely on a framework, that depends on operating system native kernel tick rate, and java's virtual machine to relay you the wakening events (and scheduling) to fire up your frame routine. This will incur bad sampling rates (aliasing) and randomness from various sources. You will have to suffer from potentially long sleep times that are not controlled, in the thread ready queue, or kernel timer tick rounding issues. This will all misalign with your framerate presentation, and result in stutterings, and if the event queue is not fully depleted at each refresh, you will also have input lag, and potentially, building up with time. Worse, since you are event based, your events I fear, are consumed by event treatment, therefore your processing time will vary according to input, and delay your frame rendering. Potentially totally masking it out. This is like a security flaw, lots of input could overflow the game and make it unresponsive.

Event based systems are not made for real time applications, they are made for basically idling applications.

Now, back to your question, it should not be a problem to fraw at 40FPS when your game updates at 20. Also be careful, in a timer based system, 20 FPS = 50ms, it will likely round up to 60ms (4*15 ; 15=typical kernel), therefore you'll get 16FPS. Use some precise chronometers to display frame update time on screen, and another one to display display rate. (use a counter around the Present call. Or framebuffer Swap (OpenGL term), or simply install Fraps.)

This will give you some statistics.

The people advocating that high display rates are bad probably refer to useless loss of resource, resulting in machine heating up, or the useless frame taking time to finish, the GPU is not ready to render the next frame when its ready, that is to say, likely right in the middle of the useless redraw. Which is why, no redraw = better responsiveness, leaving the GPU available right away when the next frame is ready.

Also tearing, is an argument often heard. Tearing is caused by swappings (presentations) frequencies that are non multiples of the screen frequency. the VSynch is the feature that helps that, by using hardware support, the VGA/DVI/HDMI cable transports a tick signal that says "I flipped!", the graphic cards receives it, signal it to the CPU with an interrupt (most likely), and the driver gets it and communicate it to the currently waiting OpenGL/DirectX presenting threads. This unleash a fast back-to-front copy, which executes in much less that the 60Hz timeframe, and then when the screen next flips, a full image is presented, this avoids perfectly the tearing.

The best is to respect this presentation rate, it is a tempo given by hardware, and the whole game/engine thread is put to sleep by the graphics API itself inside of the Swap/Present call, which allows to rest the CPU, allowing it to cool down, and allows perfect frame/game synchronization if using a linear loop like mentioned above.

Provided your game can update faster than 60Hz. Otherwise, it will fallback immediately to 30Fps naturally, then 20, then 15, by plateaus. This is a natural response.

\$\endgroup\$
  • \$\begingroup\$ Can you sum up in a TL;DR; section please? That would improve the answer. \$\endgroup\$ – Kromster Oct 27 '14 at 7:02
  • \$\begingroup\$ @KromStern .. from your suggestion I tried actually, but found that people bumping into this question would get no value with direct answers that make little sense. Its better to have a long explanation which gives a big picture, and allows people to make their own conclusions. The whole "give a man a fish" vs "teach fishing" thing. \$\endgroup\$ – v.oddou Oct 27 '14 at 7:20
  • \$\begingroup\$ v.oddou's long explanation actually helped tremendously. That is why I chose his answer. \$\endgroup\$ – mario_sunny Oct 27 '14 at 21:33
1
\$\begingroup\$

It depends on your design.

If you have interpolation/extrapolation in your render layer, then any extra frames will add to the smoothness on animation. For example particle effects don't affect games logic and can use much higher framerates. Your GUI might work at higher framerates to respond to player interaction faster.

If there's indeed no change between frames (no interpolation/extrapolation/GUI), then skipping the extra frames is beneficial, since that extra frame might overlap with next ticks frame, delaying it.

\$\endgroup\$
0
\$\begingroup\$

Consider Minecraft as an example of when this is a good idea. Minecraft runs at a fixed 20 ticks per second, but can run at hundreds of frames per second if allowed. The frames between ticks are not identical - actually Minecraft interpolates movements and animations to smooth them out, so with a higher framerate you will see smoother movement. This is a good way to offset the high resource requirements of ticking with the low resource requirements of drawing. It also allows very smooth movement when looking around - the camera movement need not be constrained by the tick rate.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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