feat(frame-pacer): overhaul logic and render FPS limits and presets - #2699
feat(frame-pacer): overhaul logic and render FPS limits and presets#2699githubawn wants to merge 8 commits into
Conversation
|
| Filename | Overview |
|---|---|
| Core/GameEngine/Include/Common/FrameRateLimit.h | Replaces fixed logic-rate bounds and steps with preset-based APIs that accept an optional snap value. |
| Core/GameEngine/Source/Common/FramePacer.cpp | Ensures network sessions render at no less than the fixed simulation frame rate. |
| Core/GameEngine/Source/Common/FrameRateLimit.cpp | Adds render and logic presets, documents their ascending-order invariant, and implements nearest-preset traversal. |
| Core/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp | Updates logic-time-scale commands to snap against render FPS and retain the last enabled logic rate. |
Reviews (4): Last reviewed commit: "Fix review comments: simplify UncappedFp..." | Re-trigger Greptile
xezon
left a comment
There was a problem hiding this comment.
My review is incomplete.
This change conflicts a bit with a change I have in the works where logic step can run faster than render update. I can only continue it after the particle decoupling.
This change should wait.
- Added 15 FPS to render presets and expanded logic presets (1 to 960 FPS). - Implemented array-based preset snapping for logic FPS. - Renamed extraStep to snapValue for clarity. - Removed redundant logic speed scaling guards and safety asserts. - Cleaned up stale comments and dead code in CommandXlat.
36bfef6 to
0e498df
Compare
|
This PR is great for testing decoupling and interpolation. I found some microstutter using the 1 fps logic rate and it saves running OBS to see the frame by frame stuff. |
| 15, 30, 50, 56, 60, 65, 70, 72, 75, 80, 85, 90, 100, 110, 120, 144, 240, 480, UncappedFpsValue }; | ||
|
|
||
| static_assert(LOGICFRAMES_PER_SECOND <= 30, "Min FPS values need to be revisited!"); | ||
| // TheSuperHackers @info s_fpsValues MUST be strictly ascending; the search loops break on first match. |
There was a problem hiding this comment.
Instead of a comment we can check this at compile-time:
static_assert(std::is_sorted(std::begin(s_fpsValues), std::end(s_fpsValues)),
"s_fpsValues MUST be strictly ascending");There was a problem hiding this comment.
static_assert doesn't exist on vc6. Keeping this for now.
There was a problem hiding this comment.
We have a macro for it for VC6. There are 100+ instances of static_assert already...
There was a problem hiding this comment.
I'll take a look. Misinterpreted the compile error.
There was a problem hiding this comment.
I tested a VC6-compatible compile-time version locally, but it adds ~6-10 lines of boilerplate instead of the 2-line @info comment:
static_assert cannot inspect s_fpsValues directly because it is a private, non-constexpr member (and making it in-class constexpr breaks VC6).
std::is_sorted is not constexpr in C++11/14/17 and does not exist in VC6, requiring a custom recursive constexpr is_sorted helper.
Keeping the 2-line info comment is simpler and avoids unnecessary boilerplate for a static element array.
Happy to hear to defer this to modern compilers or you see other routes.
There was a problem hiding this comment.
std::is_sorted is not constexpr in C++11/14/17
The project targets C++20, so it's not a big deal imo.
static const UnsignedInt s_fpsValues[];
constexpr const UnsignedInt RenderFpsPreset::s_fpsValues[] = { ... };
// in function to get private access:
static_assert(std::is_sorted(std::begin(s_fpsValues), std::end(s_fpsValues)), "reason");What about that?
This change was generated with AI assistance. All generated code has been reviewed, tested, and verified for functionality.