5
\$\begingroup\$

I'm converting a game that was using a very basic game loop that executed update/render methods 20 times per second to lwjgl. I'm using the fps loop examples in their wiki, but have found that while this is great for rendering, it's not where I should be running game element movement logic.

What I'd like to do is use this logic for rendering only (variable fps), but also have a loop that calls game update logic 20 times per second.

I'm still somewhat new to java, but it seems to me like the best way to do this is to have two loops. One runs the rendering code ~60 fps, and one runs the game logic at 20 tps.

A few sites recommend multiplying all game element movement values by the fps delta, but I'd rather not have to remember to always multiply movement values by this, and I'd like to have an update() and render() method to keep logic separate.

Is this an acceptable way of handling this?

\$\endgroup\$

2 Answers 2

7
\$\begingroup\$

Yes it is. Many games have a slow logic loop (~10/s) and a fast render loop (~60/s). Turns out most games don't need to update that often. Also by decoupling logic and rendering, you won't see a frame rate drop when the game hits a particularly difficult logic tick. I could go over it, but just read this article:

http://entropyinteractive.com/2011/02/game-engine-design-the-game-loop/

Its definitely the go-to article about game loops.

\$\endgroup\$
3
  • 4
    \$\begingroup\$ Your linked article is great, but its examples describe game loops where the render loop is no faster than the logic loop. Could you please elaborate on exactly how a slow logic loop would benefit from fast rendering? A naive interpretation would suggest that you'll just be rendering the same thing multiple times. \$\endgroup\$ Aug 30, 2013 at 4:25
  • 1
    \$\begingroup\$ How would you handle multiplayer games without using delta time for the game loop update? Wouldn't this mean that on faster computers user input is handled more often, thus resulting in small differences in gameplay. \$\endgroup\$
    – Thomas
    Aug 30, 2013 at 14:15
  • \$\begingroup\$ This is actually the very loop I was using previously, but the problem is that the fps was tied to the fixed speed of the game loop. I like have a fixed 20tps for game logic, but I don't like having 20fps. For now, I'm using the delta for my game movement logic but I want to move to a system like minecraft where the tps can fluctuate and be measured, so anything less than 20 tps can be considered a performance problem. \$\endgroup\$
    – BotskoNet
    Aug 30, 2013 at 16:02
3
\$\begingroup\$

Ok, so I will do the short answers before the long answer/explanation.

I'd like to have an update() and render() method to keep logic separate.

Is this an acceptable way of handling this?

Yes. Very much yes. As a professional Developer (sadly not for games) I can say that if you have a block of code that does a specific function (i.e. update game logic or draw frames) or have a block of code that is called a lot in the codebase (not at run time) making a method that is dedicated to the task is a very good idea. Try to name it something that describes what it is it does too. This makes the code MUCH more readable. It also makes debugging easier since if you know that the collision is an issue and you have the method detectCollision() you know that the issue MUST be in that method.

A few sites recommend multiplying all game element movement values by the fps delta, >but I'd rather not have to remember to always multiply movement values by this

What you could do is have a global static variable in your game client and call it whenever you need to adjust values by it. Granted this means you would still have to remember to include it in your calculations, but you wouldn't have to remember to always hard code in a value. Not hard coding a value and instead using a descriptive variable is a better practice anyways since you can change the value once and not worry about finding the hard coded value again if it ever needs to be updated.


Explaining Delta:

Have you ever played a game where either due to lag or tweeking setting in the console you just start running really REALLY fast and it becomes super hard to control and next thing you know your character is dead? Well depending on the machine running the game, bandwidth (if playing on the internet), and time on the game loop this changed "setting" might be the way your game will always play on someone's machine.

If you make it so that the frame is redrawn a minimum number of times so this is prevented most of the time. Think about it like this: if there is another process on the computer that is making your game loop run slowly and you don't have a bottom cap on the framerate, then its possible for the frame rate to drop to 0 fps for a little bit, which is no good. ESPECIALLY if you are skipping the draw step when the update takes to long. This implies that the player is in fact moving in the game, but it may not update to reflect that change in position.

Speaking from experience, a bottom cap on a game helps the player know that the game is still running and not just frozen. It can also help when testing out the game as once it is successfully implemented where your program is bottle-necking and slowing down. It's difficult to know if a movement/ability is causing problems if you can't see the results.

The purpose of delta time is actually to sync up different machines. Suppose the player is at point A and wants to get to point B in 5 seconds real time. If on a mid range computer, delta may be a negligently small number, but on a great machine or a low end machine delta may be really high or really low respectively. The point being that the result of the Update step is it appears identical to the player.

i.e.: For the following suppose the distance between A and B is 20 units and the default move "speed" is .1. NOTE: using arbitrary values for tps.

High end machine: suppose the update speed is 120 tps. well the player is going to get to point B in no time flat.

Mid range: update speed: 60. tps it will take this machine 2x the real world time to get to point B than the high end machine.

Low end: update speed: 20 tps. this machine will take 3x longer than the mid range machine.

Now what if we use a delta move so our default move "speed" is .1 x delta? NOTE: delta = realWorldTime/updateSpeed

If the game loop is running fast and you update your calculations by this new value then the distance the player will travel on the high end machine between updates is extremely small and the distance on the low end machine will be very large. The end result of which is the player seeing the character move at the same real world speed.

If you want to see a real world example of what this is like (assuming you are on a mid range computer) load up any 3D MMO and put the settings on minimum. Then notice the framerate and start running around, get a good feel of the graphics and try to understand the distance the character actually moves inbetween each frame. Now turn the settings to max and do the same thing. You may note that your framerate has dropped (unless you're running a beast of a machine) but your character still runs at the same speed in real world time. This is the result of using delta.

Hope this helps :D

\$\endgroup\$
2
  • 2
    \$\begingroup\$ Sparks, thanks for your explanation. However, this is not an answer to the posted question. If you don't have the reputation to post comments, please don't abuse the answer system to post comments. This answer section is for answers to the question asked, not questions asked in comments. I think you know enough about the topic to make an answer of your own, please edit this answer to answer the OPs question. \$\endgroup\$
    – House
    Aug 30, 2013 at 15:20
  • \$\begingroup\$ @Byte56 updated the answer to reflect the question. I left in what I had since I realized that if slightly reformatted it helps answers the question. \$\endgroup\$
    – sparks
    Aug 30, 2013 at 16:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .