Fixed Update with unlimited FPS?

Is there a way to have MonoGame not cap the FPS to 60, but still have some-sort of fixed-update callback?

I tried removing the FPS cap using:

 graphics.SynchronizeWithVerticalRetrace = false;
 IsFixedTimeStep = false;

And it worked (eg my FPS are no longer capped to 60) but now the Update() call frequency appears to be related to performance. Is there a good way to still have some sort of Update with fixed time?

Thanks!

There is no point to redraw the same frame. An Update is always coupled with a Draw.
If FixedTimeStep is what you need, then use FixedTimeStep.

Its common for physics, for example, not to be in sync with drawing rate. In Unity engine there’s an Update() and FixedUpdate() functions, one is coupled with drawing the other with physics.

The Game class from MonoGame doesn’t support that. You’ll either need to write your own or run a seperate thread for the other loop.

Bummer, thanks for the answer :slight_smile:

You could skip physics and update it only every 16ms or so. It’s easy to implement with a timeSpan.

You can also post on the WishList if you feel such a feature would be helpful.
Although I see a problem with it, sould FixedUpdate() be called before or after Update()? IMO it’s best to take control of things like that yourself in Update().

You can use TargetElapsedTime to set the update rate if you set the fixed time to true. However, it’s totally broken in monogame: if you set the target elapsed time to say 10 ms you should in theory get 100 fps.

However, internally sleep is used so you get ~15 ms of elapsed time.

but monogame’s GameTime (the one you get in update and draw) will lie and tell you it was 10 ms as requested.

Worse: if you PC cannot hit the 100 fps, monogame will try to wait for the frames to “resolve the lag”, not realizing that is never going to happen. So now you get ~2 fps but it will still tell you 10ms in gametime.

Just some notes. In conclusion: use a separate thread for other stuff. If you want lesss than 15ms Update rare you need to lower the internal windows clock values (or have chrome running in the background :D)

If your intent is to draw more then you update in xna the way you did this was using

PresentInterval

The default is One, Two would be 2 draws per update.
I have never tested to see if it is actually working in monogame the same as xna.

The simple Hack way to do it i suppose is simply turn is fixed time step off
Then just time err wrap the all the code in draw and update separately each in its own timer.

Thanks for all the tip and info (also @kosmonautgames and @nkast).

I ended up implementing an event I call Heartbeat which I count and invoke myself. It doesn’t guarantee to actually run every x Ms in real world time, but it’s guaranteed to execute exactly x times per second, regardless of frame rate (which is what I needed).

The nice thing about this solution is that I can set Heartbeat interval per object, which I found very useful (one object may have a beat every 10 Ms while the other every 100 Ms, different timing for different needs).

1 Like

I believe it calls Update(10ms) multiple times until it catch up to the current time. That’s also how XNA worked and it makes sense since you specified a fixed timestep. Please correct me if I am wrong here and there is bug.

PresentInterval is about VSync. It tells MG to draws on every VSync (60Hz) or every second one (30Hz) or something like that. I think you also need to set fixed timestep to 1/60 to get one update/one draw every 1/60 seconds.

PresentInterval is about VSync. It tells MG to draws on every VSync
(60Hz) or every second one (30Hz) or something like that.

Im pretty sure this is not equivalent behavior to xna or d3d, im not 100% but i think its the opposite.

It makes no sense at all to draw half as much as you update.

It may make sense to update half as much as you draw though.
or do some parts of your update half as much as other parts.
That only makes sense with is fixed time step off when doing your own timings.

Which in that case present interval 2 makes no sense to present every other update when you present two or twice per vsync. Though as you said controlling everything from update then it might make sense but to call draw twice as often or non stop.

See shawns reply to rim here in which he echo’s that thought.
https://blogs.msdn.microsoft.com/shawnhar/2007/07/25/understanding-gametime/

vysnc has only to do with the monitor back to front buffer swapchain timing signal (determined by the capability of the monitor itself) and if a present is allow during it or not which can cause tearing.
In truth vsync is a hardware operation its always on, the setting is if you intend to use it or not. It happens so fast and so often i believe it should always be used. Not using it with isFixedTimeStep off is a total waste of cpu and gpu time. Not using it with it on is just dumb.

While present itself is the call that tells the backbuffer to dump its contents to the front buffer.

The present interval im pretty sure was created for doing display interpolation smoothing with your extra time between updates at a steady rate though i could be wrong about that. Though i cant see any other reason for it to exist at all other then as a convenience towards that purpose.

I raised that point a while back in the issue where i noted that someone made present work that way half the updates for presenInterval two but i guess no one caught it.

There is no point to doing less draws then updates unless is running slowly evaluates to true in that case your in a cpu or gpu bottleneck anyways and your cutting things to catch up.

Though unless your making a million dollar game (like in the case of moto gp) and have tons of programmers i suppose it doesn’t matter just pointing out the purpose of these things.

how to fix update at 60 time per second
and draw as fast as possible?

Set SynchronizeWithVerticalRetrace=false and IsFixedTimeStep=false. Now both update and draw are called as often as possible. Then add some timing code to your update function that triggers your custom fixed-time-update-function 60 times per second.

float timer = 0;

protected override void Update(GameTime gameTime)
{
    timer += gameTime.ElapsedGameTime.TotalSeconds;
    float updateTime = 1f/60;

    while (timer >= updateTime)
    {
         FixedTimeUpdate(updateTime); 
         timer -= updateTime;
    }
}

That’s the basic concept. You probably want to add some protection for cases where your system can’t run FixedTimeUpdate as often as you ask it too. For example if FixedTimeUpdate() takes one second to execute just once, then there is no way you could ever run it at 60 fps. If you tried anyway, with just the code above, the elapsed time would grow and grow, asking for more and more FixedUpdates every frame, eventually freezing your system. You have to decide how you want to handle a situation like that. A simple solution could be to have an upper limit for how often FixedTimeUpdate can be triggered per frame.

That method should work for most use cases, it will not ensure that your FixedUpdate function get’s called at even intervals though. That means if you play a tick sound every time FixedUpdate get’s called, there will be 60 ticks per second on average, but they won’t necessarily be spaced out evenly. So the rythm could be messed up. If you need exact realtime intervals you need to do something more elaborate.

3 Likes

it worked ! thank you very much

I just got a 144hz monitor and I noticed some slight stuttering from my game which I never saw on my 60hz monitor. When I adjust the game to run without vsync and fixedtimestep, it runs smooth as butter. Same issues as everyone with update running too often now and I’ll have to some hacking bits to make it run at a more stable rate. I even tried to adjust the TargetElapsedTime without success.

I wish, maybe it can be added at some point in a new release of MG. For there to be a simple variable to be set that can control how often you want update and draw to run. So like, update every 60fps and draw at 144fps. By default both could be set to 60.

Hi to all
I think that is a bad way to try to control the rate of DRAW or UPDATE.
If your goal is to compute PHYSICS for example , the better way is to keep the ELAPSED TIME and compute your PHYSICS with it. That will give you a delay time and you can compute all the changes for the next frame. Derived functions like speeds of objects or accelerations will be linear front of the variant FPS.
Technically , you just have to multiply your constants by the ELAPSED GAMETIME
Chris

My sample code for example :
Accelleration by FPS

That’s not necessarily true. Most big budget games do just that. This is considered the mecca article for this topic: Fix Your Timestep! | Gaffer On Games

However, for the case of smaller games that don’t have so many computations, I do agree having the same updates per frame as draws is easier, and is my preferred way of doing it.

However, the physics (especially when considering collisions) can differ significantly depending on the framerate, which can lead to much different results (for example, making it across the gap vs. falling down the cliff when it thinks you hit the side of the ledge). Sweep algorithms can be used to deal with these inconsistencies, but you have to consider which one is easier and better in the long-run.

Btw, hietpas could you show the code you use for setting your TargetElapsedTime, and the code you use to multiply elapsed time on your physics?


This is where the edit starts:

I’m now realizing in context of Chris’s post, my post could be worded better (I wrote the previous part of this post on my phone on break). When I say big budget games “do just that”, I mean decoupling the physics loop from the update loop. And when I say “the same updates per frame as draws is easier”, I mean keeping the physics in the main update loop, which runs at the same rate as the draw loop is easier. Sorry if I confused with that.

Big budget games typically decouple the physics loop at a fixed rate (collisions in physics are expensive), while I’d assume that the update and draw generally run at the same rate. Much like the physics loop, other things can be decoupled too like checking inputs, AI, etc.

I doubt that your project really needs this though.

If you’re having issues with stuttering, your frame pacing might be a bit off. If you’re not using this, use:

//the desired FPS is 60f, but you can change it to 144f or whatever you'd like
this.TargetElapsedTime = TimeSpan.FromTicks((long)(TimeSpan.TicksPerSecond / 60f));

When displacing things over time in your game, if you’re not doing this, do:

//ticks seem to be the way to go over .Seconds or .Milliseconds
float deltaTime = (float)gameTime.ElapsedGameTime.Ticks / TimeSpan.TicksPerSecond;

velocity.X += walkAcceleration * deltaTime; //walking example
position += (previousVelocity + velocity) * 0.5f * deltaTime; //verlet intergration: more accurate movement over time than euler integration

Let me know if this helps the stuttering. However, I agree with Chris with you keeping the draw and update rates the same. If you really want to do physics at a fixed rate like bigger games typically do, that’s something you’d have to write, absent the defaults offered by Monogame.

1 Like

Hello HierpasGames

I think that the command graphics.SynchronizeWithVerticalRetrace set to true or false should be a good solution for your monitor frequency , and that will not penalize your game frame rate.

Chris