Game + Physics time steps BETA testing

On the dev branch (the alpha version of the editor), we now have support for fixed time steps for the physics, and also variable framerate for the game loop.

Our goal was to solve the framerate issues our users have experienced on machines with displays that runs faster than 60Hz.

We’d like for you to test these settings to make sure that they work as intended for your use cases.

These are the relevant settings:

  • physics.update_frequency

    • an integer setting in Hz
    • 0 means variable frame rate (default)
    • e.g. 60 means it updates 60 frames per second.
    • We recommend e.g. 30 or 60 Hz
  • display.update_frequency (integer)

    • an integer setting in Hz
    • 0 means variable frame rate (default)
    • > 0 means fixed frame rate. Capped at runtime towards the actual frame rate. I.e. you cannot update the game loop twice in an engine frame.
    • Fixed time steps may be used to simulate slower devices, or throttle the performance at runtime. E.g. set to 30 to simulate the frame rate of KaiOS.
  • display.swap_interval

    • An integer setting that sets the OpenGL swap interval
    • (doesn’t work with Vulkan)
    • 0 disables vsync
    • Default is 1
  • display.vsync (DEPRECATED)

    • boolean
    • If set to false, forces a display.swap_interval = 0
  • Use the sys.set_update_frequency(hz) to control the “display.update_frequency” at runtime.

Here’s the alpha build:

18 Likes

We haven’t heard feedback regarding this, so we’re not sure if all is working as expected, or if there are any issues.
Note that these features will land in the Beta on monday.

5 Likes

I will test it after DefoldCon, so expect my feedback soon! :grinning:

5 Likes

We did some tests yesterday on a computer with two displays (both VRR with different native refresh rates). When before the game’s speed would be incorrect and would also change if the window was moved between screens, now it behaves correctly.

We don’t use physics at all, so can’t say anything about that. We plan on putting a build on Steam with the new engine (currently waiting on a few other content fixes) and see if we still get reports from players.

8 Likes

That’s good news! Thanks for testing it out!

4 Likes

The idea of making physics time-stamp fixed is excellent! It’s substantial step forward for Defold, to be honest.

It seems that the display.update_frequency option now works as it was intended to. I mean that, previously, its behaviour wasn’t clear.

Next is physics.update_frequency. I prepared a small demo project to test it - https://github.com/aglitchman/defold-physics-131-test

In this demo balloons should stay in the middle of the screen, i.e. balloon.script constantly, every frame, compensates the gravity. Why do they fall if I set physics.update_frequency to non-zero value?

4 Likes

Plus, I’ve added two kinematic objects (a game object with a sailboat sprite :grinning: ) to count the number of collision responses per frame, which equals to the amount of physics updates. Just in case.

4 Likes

Thanks for the repro case!

In short, the fixed fixed physics timestep needs some rework :confused:

In this particular case, the initial game loop dt is large enough to make the physics tick several frames, which makes the objects accumulate velocities due to gravity (Using update_frequency = 60). Similarly, it works the other way, if we set the frequency to 30, we’ll accumulate forces that are larger than the applied gravity, and the objects will go upwards.

Ofc, we need to come up with a solution to this, and I think we need something like the FIxedUpdate() in Unity.

I’ve started looking into this now…

5 Likes

And I added a game object (the “anchor” sprite) that falls down under the gravity to test that the speed in the end of its way is the same across all combinations of new project settings. And it’s about 250 px/sec.

And I would like to have something like LateUpdate(). Its necessity has been discussed a couple of times (#1, #2 etc). The docs describe its purpose right:

For example a follow camera should always be implemented in LateUpdate because it tracks objects that might have moved inside Update.

So, in Scene3D, we have to use @totebo hack not to lag to dynamic bodies’ positions.

6 Likes

I love that I now have a hack to my name. :innocent:

5 Likes

I have a new PR up for review, and the CI is building my new branch here

Basically, I’ve added a new script function “fixed_update(self, dt)” together with a slight change in config settings. I feel it’s much more robust than before.

The thing that will change for users is the way they think about these things.
I worry a bit about the transition for existing games though.

I haven’t really discussed this with @britzl yet either, so it’s a bit experimental.

6 Likes

Question for the community:

Given a fixed update script function, what are your uses cases for it? (Other than physics related updates)

We ask since we want to know as much as possible before we add a feature.

4 Likes

Well any sort of simulation, I guess. Including custom physics simulations (for example, in a platformer, for it to feel snappy you probably want to manually simulate jumps and such.

Also, now that the physics engine is decoupled from the main loop, you don’t have a way to react to every physics state. For example, if you have some ray casting checks, that you might want to do each frame (for something like an enemy shooting you if you go out of cover, for example), you can’t guarantee fair gameplay across different framerates unless you have this fixed_update() function where you can react to every physics tick.

5 Likes

Well, the physics is the main reason for the fixed update function. The question was, what other uses there are?

3 Likes

I had cases when I wrote my fixed update for validation on the server. The game recorded certain events tied to the counter and then, roughly speaking, played the game on the server.

5 Likes

Network games need it. Since with deterministic update on client and server traffic between then can be dramatically reduced. Same for p2p games. We have our custom fixed update for this

5 Likes

Thanks!
The server updates are a good use case.

I wonder about the frequency you use in these cases?
E.g. compared to physics updates which might use 60 or 30 Hz.

3 Likes

Hmm, if you’re asking if it should be part of the physics module, I think fixed_update should exist even if the engine is compiled without a physics engine. Someone might want to implement their own physics and fixed_update is still useful in that scenario. (though concievably, one could implement the behaviour of fixed_update() using update(), it’s just more work and an extra thing to pay attention to)

As for non-physics related things, you can simulate so many non-physics things: Think Factorio, for example. Each of their tiles have particular behaviours they do each tick and ideally that shouldn’t be tied to the framerate. Or events and troop movements in a military simulation, etc…

Can these be done in a FPS-independent way using just update()? Probably yes, by implementing a similar logic as you have and calling your tick more/less times per frame depending on dt.

Is it good to have a convenience function for this? Definitely and I will be switching some simulation code for our tower defence mini-game in GMAI to fixed_update() if it gets implemented. Getting that timing behaviour right without stutters is not an easy task and I think it’s good if you give Defold users a “known good” implementation of it.

One place where fixed_update() is really necessary and no other alternative exists, is when wanting to sync up with the built-in physics engine.

7 Likes

Thank you for your input!

We’ll go for adding a new life cycle function fixed_update(), and we’re currently trying it out a bit, to better understand what the migration steps will be for our users.

5 Likes