-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Add example to test the smoothness/accuracy of the timestep #4865
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
Add example to test the smoothness/accuracy of the timestep #4865
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm impressed; this should be very useful! A few administrative notes:
- Please add a module style doc comment to the top of your example.
- Please add the example to examples/README.md
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Like I suggested on Discord, I'd like to see some numbers reported periodically in the console. To start, I think "mean, standard deviation, min and max frame time" for the last 10 seconds should be enough to give testers a better sense of what's going on.
You should be able to get this information from the FrameTimeDiagnosticsPlugin (I think in a resource); ping if you can't figure it out.
@alice-i-cecile Thanks for the review! I'll add the comments/links now, and I'll look into doing math on the diags resource later this week. |
@nfagerlund you can press "Resolve Comment" on the feedback that you've addressed, which keeps the thread tidier for reviewers :) |
f2b244c
to
7e80881
Compare
@alice-i-cecile Ok! I've added some frame time analysis to the example. I had to roll my own diagnostic, since it turns out the built-in one only keeps a non-configurable 20 frames, but now it prints this every 10 seconds:
I still need to go deal with Clippy, but figured I'd paste that before the output scrolls out of my terminal. |
7e80881
to
c996988
Compare
OK, all hail clippy, TIL about |
Awesome, that's super useful both as a snippet and as a testing tool. |
Hmm, I can't tell why CI is failing.
I think those are in the prelude?? It compiles and runs?? What's going on here. |
They were renamed/refactored in this PR #4745. |
Oh, I also want to surface a question from the original post that maybe got lost — I have code in there that calls |
@hymm oh! Hmm, so the CI job must be merging or rebasing, instead of running on the branch. I'll rebase later and sort out the rename. thank you! |
IIRC you had to set this before calling .add_default_plugins, due to a quirk in the way |
Oh... huh. I mean, I'm adding the window descriptor resource before that, so the initial settings take effect just fine. But so, can they just not be changed at runtime? Why would the functions on Window exist, then? I don't think you can even get hold of a Window struct until the app's running, yeah? Maybe I should remove those config bits and just tell users to edit and recompile. :/ |
Could you change the stats to |
This is about my feeling. Can you open an issue? |
c996988
to
80580eb
Compare
Bevy's timestep is sometimes inaccurate, and sometimes it misses its frame timings. Both of these can manifest as hiccups and stutters in what should be smooth motion. This is most clearly visible when using pixel-perfect movement with large visible pixels. This new example (in the stress tests directory) scrolls a background behind a character at 120 pixels per second; by default, it makes sure to always move in whole-pixel increments. You can modify some behavior while it's running by pressing keys: - P: cycle between different `window::PresentMode`s. - W: cycle between different `window::WindowMode`s. - T: cycle between updating scroll position based on `Time.delta_seconds()`, and updating it by just assuming a 16.667 millisecond timestep (only useful in `PresentMode::Fifo` on a 60fps display). - M: cycle between whole-pixel movement and simple sub-pixel movement.
80580eb
to
af82dff
Compare
OK, I'm back!!
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! I'd be more comfortable merging this if you can drop a comment on the broken window commands linking to the issue in question.
I think it's probably worth leaving them in, if only to make it easy to test fixes to that. Other opinions would be welcome though.
Outside of that question, I'm very happy with this now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
} | ||
|
||
fn std_deviation(diagnostic: &Diagnostic) -> Option<f64> { | ||
if let Some(average) = diagnostic.average() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the average is being calculated both in this function and in the above function. Could we remove one of these?
const BG_WIDTH: f32 = 755.0; | ||
const BG_HEIGHT: f32 = 363.0; | ||
const BG_TILES: usize = 3; | ||
const BG_SPEED: f32 = 120.0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add a recommendation here to change this number for different monitors. This is always going to hit the "big jump" warning on a 30Hz monitor and will probably always look jumpy on a 144Hz monitor.
Closing as part of backlog cleanup: still seems like an interesting example, but would need significant revision and may not be as relevant as Bevy matures. |
Objective
Bevy's timestep is sometimes inaccurate, which can manifest as hiccups and stutters in what should
be smooth motion. This is most clearly visible when using pixel-perfect movement with large
visible pixels.
It would be good to have some kind of shared baseline for any conversations about hiccups, stutters, and other time-based jank!
Solution
This PR adds a new example (in the stress tests directory) that scrolls a background behind a character at 120
pixels per second; by default, it makes sure to always move in whole-pixel increments. You can modify
some behavior while it's running by pressing keys:
window::PresentMode
s. (NOTE:Window.set_present_mode()
doesn't appear to actually work at the moment! Not sure what's up there and would appreciate any hints.)window::WindowMode
s. (NOTE:Window.set_resolution()
doesn't appear to do anything? I might be using it wrong?)Time.delta_seconds()
, and updating it byjust assuming a 16.667 millisecond timestep (only useful in
PresentMode::Fifo
on a 60fps display).Changelog
Added a
time_smoothness
example (understress_tests
) for qualitatively evaluating the smoothness and accuracy of delta time.Videos
A couple of videos of weird stuttering in action on Windows.
This computer is a desktop with a Haswell Core i3-4160 (entry-level processor from 2014), 8gb of ram, and a GTX 1060 (3gb) video card, running Windows 10 Home 21H2. It's quite modest! But it runs a wide range of commercial games with solid and respectable performance, and scrolling a background probably shouldn't look as bad as it does here.
Windowed mode:
2022-05-24.00-03-43.bevy.windowed.mp4
Borderless fullscreen:
2022-05-24.00-05-52.bevy.fullscreen.mp4