Game + Physics time steps BETA testing

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

We use 10 Hz. But i think it is ok to fix it on 60Hz, and it can be resampled down by project individually.

3 Likes

Could fixed_update() help fix the examples above? In my project, visuals, including camera movement, lagging one frame behind is one of the recurring Defold issues I haven’t been able to solve in a good way.

2 Likes

Thanks!
I guess having it slower than the physics is easier. E.g. if the fixed frequency is a 60Hz, you’d call your server sync every 6th frame.

@totebo
We’ll most likely add another life cycle function for the post update. I’m hoping next version (after this one)

4 Likes

No, it couldn’t. We have the same problem. I would love to have the late_update(self, dt) function in scripts or an option to subscribe for the late_update message (for example, i.e. any option is OK).
Also, I’ve found that native extensions can subscribe on the pre-render callback and it can be used for late update logic (but, unfortunately, messages from that logic will be dispatched next frame). Because, broadly speaking, the purpose of the late update is to prepare your scene for rendering, i.e. move/rotate the camera or other objects that rely on the transformation of dynamic bodies. I’ll post the results of my experiments then.

Sounds great!!

4 Likes