Can someone explain to me why you need an update method that udpates the game 60 times / second, and why generally it’s a bad idea to run the updates in the method where you’re rendering the screen?
If anyone can link me to an article about this that’d be awesome.
You want to make your code as easily understandable as possible, trying to bake a cake by mixing the ingredients while its cooking is not ideal. We should mix the ingredients, then cook (bake) it.
In game development we should update the game then render it, not try and update it as we render it.
Another good reasoning is, we can control the updating separately to the game FPS, some games will cap the amount of updates per second, or run at a higher update rate (e.g. with physics). Having the update tied to fps would also make the game less smooth when a player has lower fps.
[quote=“Phased,post:2,topic:59427”]
Yes that’s what I mean, when you’re calling the delta time from one frame to another and using that to only update the game (not render) 60 times / second, wouldn’t that hinder performance? Or am I missing something.
Are you saying updating the game every frame is a performance hit? Of course it is, but it also can’t be helped, unless you your game never changes, at that point, it is just a single image.
If you are trying to say you want to reduce the update rate from 60 updates per second to 10 updates per second because you are using delta time, that is possible, but your game will feel not feel very responsive unless you make another update like function that processes user input / menu control / what ever else, and only let the game logic be updated at 10 updates per second (may be acceptable for a turn based game).
My quote was more towards not using delta time. Also remember, you need smarter collision detection when you are using delta time, if my character moves at 10 meters a second, and for some reason my game freezes for 10 seconds, the delta time would then mean my character moved 100 meters in the update, if you are doing collision by checking to see if your hitbox is inside of another hitbox, I would teleport over all objects that are less then 100 meters away.
So having a lower delta time for the above situation would increase the accuracy of the collision detection. So forcing 60 updates per second would ensure that the collision detection is always accurate to that precision.
[quote=“Phased,post:4,topic:59427”]
No no, I’m saying why update the game 60 times a second vs just letting it update continuously as the game is rendering. So for example why do this
The best is having game logic in another thread. Separated from game view as far as possible.
Making game logic dependent from rendering will cause for example: slowdown of logic if rendering got slowdown.
Bad implementation can cause bugs like: bad collision detection on frame drop (long time ago there were bugs in old FPS games for example), slowing rendering if logic is “hardly thinking” (freezing). Usually, you don’t want something like this.
Separation of concern in this case could make your game “thinking” not dependent from “showing” which is helping in readability a lot (as said in previous comments) and will help you with critical situations of unsuspected client behaviors (frame drop/frame kick) or game logic braindeading.
Ofc you can workaround it various ways (for example: get rid of state update -> make it as a function) with some more or less great result but it’s much better to separate your model from view.
Different devices run at different framerates. Let’s say my computer can run at 120 FPS, whereas my phone can only render 30 FPS. If I program a game for my computer, then it’ll be very slow on my phone. If I program a game for my phone, then it’ll be too fast on my computer.
The code you posted in the screenshot solves this problem by running the update function multiple times on slower devices. That way my phone will step 4 times for every drawn frame, so it will look like it’s running at the same speed as my computer.
I actually don’t like this approach, as it’s a bit hard to understand and feels a little bit hacky.
Instead, I like the approach that libGDX takes. You can update your game for each rendered frame pretty much exactly like you’re describing, but you then have to take into account the amount of time that has elapsed since the last frame and move your scene relative to that. So if you want something to move 60 pixels per second, then on my phone you have to move it 2 pixels per frame, and on my computer you’d have to move it .5 pixels per frame.
[quote=“KevinWorkman,post:8,topic:59427”]
Ah this explains it perfectly, thank you so much and thank you to everyone else that helped explain :), I understand why now.
So basically even though one machine can render 500 frames per second, if your game logic isn’t fixed to a specific number of updates per frame (so 30-60FPS), then this can cause issues with compatibility across several devices. So we have to take into consideration that we want the game to run exactly the same across devices, and not faster on some, and then slower on others.
Actually while making game logic truly independent from rendering is possible, and perhaps desirable, it needs careful architectural thought. Just been having a similar conversation with someone on the Processing forum trying to do this and running into lots of exceptions (CME, etc.) because of a lack of understanding of concurrency. Kevin’s approach on delta time is probably the best approach for most projects, at least until there’s a demonstrable benefit to be had from parallelizing this. I’m not sure bad collision detection algorithms count!
this is a gameloop with a fixed logic-timestep
and a variable render timestep:
public void gameLoop() {
float delta;
float accumulator = 0f;
float interval = 1f / targetUPS;
float alpha;
while (running) {
delta = timer.getDelta(); //eg: = timeNow - timeLastCall
accumulator += delta;
input();
while (accumulator >= interval) {
update();
accumulator -= interval;
}
alpha = accumulator / interval; // between 0 and 1, used to smooth animations and movement
render(alpha);
window.update();
}
}
It has the advantage of frame rate independent constant-time logic updates, while allowing frames to draw as fast as the client can do it.
Constant-time logic ticks are way easier to program, and avoid edge cases when the framerate drops too low or runs too fast.