Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Smoothed Delta times on Android and overall improvements #6228

Closed
obigu opened this issue Oct 15, 2020 · 2 comments · Fixed by #6233
Closed

Smoothed Delta times on Android and overall improvements #6228

obigu opened this issue Oct 15, 2020 · 2 comments · Fixed by #6233
Labels
core affecting all platforms graphics Concerning Gdx.graphics

Comments

@obigu
Copy link
Contributor

obigu commented Oct 15, 2020

Graphics has 2 different methods to get delta time, float getDeltaTime() and float getRawDeltaTime();. According to java docs, the difference is that getDeltaTime() "Might be smoothed over n frames.".

Checking all backend Graphics implementations, the only backend that does smoothing on the delta is the Android backend, that applies a simple size 5 window mean. This is probably due to legacy reasons when libGDX was created some Android devices were really unrealiable (we're talking Android 1.5 or 1.6) and my guess is that this was a workaround for those old devices with very inconsistent delta times.

Averaging the delta over 5 frames has a significant impact on how the game behaves during lag spikes. Let me show with an example.

Imagine we have the following sequence of Raw delta times
1/60 1/60 1/60 1/60 1/60 1/5 1/60 1/60 1/60 1/60 1/60

In every backend except from Android, in a typical setup in which delta is capped to 1/30 (Scene2D does that by default) the resulting deltas used by the game would be
1/60 1/60 1/60 1/60 1/60 1/30 1/60 1/60 1/60 1/60 1/60 1/60
In which only the 1/30 frame would have a "slow motion" distortion caused due to real elapsed time being higher than delta time

On Android, on the other hand, we would get
1/60 1/60 1/60 1/60 1/60 1/30 1/30 1/30 1/30 1/30 1/60
In which the first 1/30 frame would be distorted exactly like before but the next 4 1/30 ones they would be "fast forward" (as if it was catching up).

Understanding that

I think there are several things of this design decision that are worth revisiting:

  1. I'm not aware of any reason why Android should be treated differently from the other backends. Considering the algorithm applied is not particularly good (most smoothing approaches go for a weighted average or some kind of low filter) and in many scenarios the current solution will impact how lag is perceived in games and feel worse than raw delta. I think we should remove the smoothing from Android.
  2. The "maybe smoothed" version getDeltaTime() is used across libGDX code base by different systems to get the delta time (with calls to Gdx.graphics.getDeltaTime()). This means that, even if a user didn't want the smoothed delta to be used on his game, some parts of libGDX (from Scene2D to particles among others) would still use the smoothed one causing unpredictable issues.
  3. As an larger scoped improvement (that would entail breaking backwards compatibility) I think it's worth evaluating adding optional Delta capping and the ability to provide a Smoothing strategy at framework level. We could also consider having getDeltaTime() to return raw delta time and add a getSmoothedDeltaTime() (Unity has something on these lines).
@MrStahlfelge MrStahlfelge added core affecting all platforms graphics Concerning Gdx.graphics labels Oct 15, 2020
@MrStahlfelge MrStahlfelge pinned this issue Oct 15, 2020
@MrStahlfelge
Copy link
Member

I agree that it doesn't make any sense to have this on Android only, and that the current smoothing algorithm could be improved. I would prefer a simple clamping of the delta time, a common suggestion for libgdx games (related: #6093, but there was also a lot of forum and discord talk on this because such a clamp is needed on desktop if the window is resized).

Given the problem that many internal methods use getDeltaTime(), an approach could be to remove getRawDeltaTime() and add configuration options how getDeltaTime() smoothens the output (raw values, clamp, ...)

@crykn
Copy link
Member

crykn commented Oct 15, 2020

Yep, I think we should remove the smoothing in the Android backend and change the javadoc accordingly. It should also be mentioned that clamping may happen (at least on mobile platforms).

Given the problem that many internal methods use getDeltaTime(), an approach could be to remove getRawDeltaTime() and add configuration options how getDeltaTime() smoothens the output (raw values, clamp, ...)

That sounds like a good idea that allows for minimal changes in libGDX.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core affecting all platforms graphics Concerning Gdx.graphics
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants