How to fix the rate of Draw() called but not limit the rate of Update() called?

For example, I want to fix the rate of Update() at 144FPS, but fix the rate of Draw() at 60FPS, what should I do? I would be appreciative if you give me a practical solution.

You can tell MonoGame to run at a fixed update rate of 144 fps, but I donā€™t think it provides separate options for Draw. Iā€™ve never really looked and a (very) quick Google didnā€™t show me anything, but that doesnā€™t mean you canā€™t.

Still, you could easily throttle your draws on your own. Presumably you have some entry point Draw in your engine that then tells the rest of your game objects that they need to draw. You can just put some timer code in there and early out when itā€™s not time to draw.

Iā€™ll leave the implementation to you for now but if you have questions, let me know and I can help out :slight_smile:

EDIT

Read the last post before the labels update, I thought this would link the linked comment but it links the first post :woman_shrugging:

Syncing 60fps draw rate to 144fps update is no joke. To do it properly it requires keeping two update states and interpolate in between, which is horrible can of worms. Otherwise it will cause jitter. Recommendation for new dev is simple: donā€™t.

1 Like

You can already set Game.TargetElapsedTime and FixedTimeStep = true and vsync (for 60fps rendering)

It may not be totally accurate tho as after all Update/Draw are still part of the same loop and there is several waits involved due to I/O.

Actually i think iā€™m not a new dev. Iā€™m doing a project of undertale fan rhythm game for two years. For some reasons I fixed my update rate to 144fps for the maximum, but i find when my game runs on some slow computers of the players, they may get intermittently sudden lag. Itā€™s because the 60FPS draw rate is too high. Some asked a draw rate limit option, i need to do it for them.

well then as proposed, set time step for required fps. Then write own draw logic decoupled from update. Keep two states. Interpolate in between. You can also test how it will look like without interpolation since your update rate will be way higher.

Okay thanks for your answer. Both @Ravendarke and @Trinith give the right way! Thanks again!

1 Like

For an Undertale style rhythm game, I feel like you might have to go pretty far back in hardware to see lag. I suspect the source of lag isnā€™t your draw but in your update. If your update canā€™t complete in 1/144 of a second then it will be blocking the draw call until it completes, which in turn blocks the next update. Unless your draw is extremely intensive, I suspect even a 30fps draw probably wonā€™t do much for you.

I would consider any or all of the followingā€¦

  • Investigate/profile your update and look for places you can optimize.
  • Decouple your update logic from a fixed time step and instead calculate motion based on elapsed game time.
  • Reduce your fixed update rate to something like 60 fps so you have more time per frame to process game logic.
1 Like

How do you do that fixedUpdate technique if you donā€™t mind me asking?

@Lajbert wrote a good article on it so Iā€™ll just link it :slight_smile:

The simplest implementation is just to keep track of a timer and call FixedUpdate whenever you consume the appropriate amount of time from the timer. You donā€™t really need to worry about the ALPHA stuff that heā€™s doing, unless you want it.

You can then use a similar technique for a FixedDraw, per the OPā€™s request.

1 Like

Actually my game runs very fast, the CPU and GPU usage is less than 15% in my computer. Just in few super old computer somebody may get sudden lag sometimes. Iā€™m just doing this for them. And actually the game itself has many shaders as effect. Update itself actally runs very fast, if i do not draw it can runs more than 2000FPS. I actually optimized Update a lot and i understand some algorithm optimize well because i am ACMer before.

怐Rhythm Recall怑End time div1ęœ€é«˜éš¾åŗ¦é€šå…³_单ęœŗęøøꈏēƒ­é—Øč§†é¢‘ see the game effect and you will understand why it lags on some old computers.

i just override the BeginDraw() function to depend whether to Draw, and i make the TargetElapsedTime zero, and every time the Update() is called, i accumulated it to a update time counter and draw time counter. if the update time counter (ms) is more than 1000f / 144, i do the real Update function, and when the draw counter (ms) is more than 1000f / FPS, i allow the BeginDraw() to return true.

Iā€™m saying, that might not be the case on this older hardware. You see lag when you canā€™t complete an update (or draw) inside the time you expect it to, so one of those two things is happening. Given what I see in your video, it seems unlikely to be your draw, though that doesnā€™t mean it isnā€™t. My gut is telling me here that fixing your draw rate is isnā€™t going to solve your problem but at the end of the day, my point is that you should investigate.

No disrespect to your game intended here, it looks super cool. But if you wanna support old hardware, youā€™ll need to get to the bottom of what your bottlenecks actually are. If you could get your hands on that hardware so you could do some actual profiling, that could help a lot!

Either way, best of luck :slight_smile:

Call this.SuppressDraw();' in Game1.Update()` every other step.

That will get you to 72 fps. To get to 60 fps drop an additional one of every 5 actual calls.

Oh thanks for your suggestion! I will try!

1 Like