Physics event execution order

I am looking for a documentation for Flax’s complete scripting execution order, including Physics event
(e.g : OnCollisionEnter(), etc)

So looking at Unity, the execution order in the frame when Physics is updated :
FixedUpdate() → OnCollisionXXX(), → Update()

I assume Flax is using the same execution order?
Please correct me if I’m wrong, or direct me to a full documentation for Script execution order in Flax.

Thank you.

1 Like

That Unity execution sequence can be a little misleading: Unity will attempt to deliver render updates at the best rate it can up to any target fps you have set. Each render update it executes the Update methods. Depending on load, you may not achieve that target and the frame rate will vary. The physics has a fixed time step size for the purposes of the physics calculations (default 0.02 seconds), but that is no guarantee of the physics update actually running every 0.02 seconds; it will be dependent on load.

So it is entirely possible for Unity to make several frame renders without ever running a physics update and it is also possible for it to run more than one physics update without a render update, all depending on load. You cannot rely on one happening in sync or within a specific order of the other. This is visible in the diagram you linked to as the additional closed loop around the physics section, although this is still a little misleading - it doesn’t have to wait for physics to catch up before it renders a frame.

The last time I looked at Unreal it had its physics tied to the render step, giving a variable physics solver rate.

There are pros and cons to both methods.

As Flax lets you specify a separate physics frequency, I assume (!) that it is more aligned to the Unity model: Assuming this, then there is no guaranteed execution sequence between physics and rendering.

1 Like

What @AITheSlacker stated is exactly correct. Great topic!

During my Unity time since 2012-ish I had to come to grips with this. The only way I could guarantee a 20ms is to use math for positioning/vector math then when actually needing the physics calcs part then enabling it to happen. This can off load math from the physics engine and let it perform properly. This can be fully tested (I stopped using/testing Unity in 2018 LTS and have just recently stopped using Unity 5.6.7 Pro since Flax 1.6).

For UE4/5 it has built in Substepping and the manual is correct. Devs must be understanding about this and this system is much more difficult to work around with math. Here is an excellent article (not from Epic) about all the bits and bytes, so to speak. :slight_smile:

Note: There is a Unity comparison near the bottom in details how Unity does this. It is cleaner but done differently and not easily exposed. The explanation is excellent and correct.

Everything you always wanted to know about Unreal Engine physics (but were afraid to ask) | A Clockwork Berry

As for Flax. I have only done testing in this in 1.6 and now 1.7 so my information is limited. I will say that Flax physics engine seems to be closer to UE4/5 with the more recent (1.6) addition/upgrade to nVidia PhysX 5.1. So far I have not had to worry about much, like UE4/5, but I have to be wary about substep overloading.

How to test it’s capability best? The drop cubes test and let them pile on each other. Count them and display both the CPU frame and GPU frame.

Here is a great example of what Flax should provide us as part of it’s manual. This also validates what Flax Dev’s will consider about optimizations to what is going on under Flax’s ‘hood’. We as the community can help with this but this sort of thing should not be buried. This should be a sample we can all load and watch what happens on the system we are designing for.

I would be willing to help but this is a super simple set up. I have not done this yet but have been testing in other ways. Flax’s performance should be right in line with Unity 2020 or even slightly better.

Coding Sea: Unity 2020 vs Stride 4.0

Unity 2020.3 VS Stride 4.0 3D performance benchmarks (youtube.com)

And that is all I can add. Brain dump. :slight_smile:

@AlTheSlacker @OlanderDA
First of all, Thanks guys for your feedbacks!
Really appreciate it!

So it is entirely possible for Unity to make several frame renders without ever running a physics update and it is also possible for it to run more than one physics update without a render update, all depending on load. You cannot rely on one happening in sync or within a specific order of the other.

Yes, I am aware of this.
FixedUpdate() in executed in different frequency , compared to Update() depending on the settings (both in Unity and Flax)

I’ve been running tests in Unity, when the “Sync” happens, the execution order seems to be like this :
FixedUpdate() -> OnCollisionXXX() -> Update() -> Animation -> LateUpdate() -> Render
meaning, FixedUpdate() is done before Collision, and Update() is done after Collision.
Then Animation, LateUpdate(), and lastly rendering.

Since both Unity and Flax uses PhysX,
I assume the order for FixedUpdate(), OnCollision(), Update() , etc is the same in Flax too?
Because I can’t find the complete diagram for Flax just like the one in Unity links.

1 Like

OnCollision is a callback from PhysX, so will always follow FixedUpdate (in Unity, I’m not certain how Flax handles that, but I would expect the same way) . As physics steps are effectively independent of render steps (either can be substantially and separately delayed by load, even if their target is to run at the same frequency) it is better to think of it as two overlapping workflows of:

FixedUpdate() → OnCollisionXXX()
Update() → Animation → LateUpdate() → Render

You can see the main Flax game loop here: Github

Which, at a cursory glance, suggests to be a Unity like flow (except Flax has an OnLateFixedUpdate - nice). I didn’t look into it in much detail, and I’m not sure how threading is handled.

1 Like

Thanks for the Github link!

So to summarize,

■ Both Unity and Flax has this similarity ( just like @AlTheSlacker said)

  • Pair-1 order : FixedUpdate() → OnCollisionXXX()
  • Pair-2 order : Update() → Animation → LateUpdate() → Render
    And both pair are executed in different frequency.

■ The difference between Unity and Flax is the order of FixedUpdate() and Update()
(* according to Github)

  • Unity : FixedUpdate() -> Update()
  • Flax : Update() -> FixedUpdate()

Also, having a LateFixedUpdate() in Flax is really a nice feature! I totally agree :grin:

I did some digging this morning since I have not been down this path in some time. Me being me…time to do some System Engineering to figure this out. After digging I am 99.9% sure of the findings below. Discussion like this is always welcomed and good for anyone else wanting to know. :grin: :astonished:

Your pairing order seems to be correct in execution order. This also matches the Flax manual as well, even though it is both correct and vague. :slight_smile: There should be some sort of fine print note or something stating explicitly about the Fixed Update and PhysX Delta Time and Substepping. Tool tips are also there but also vague.

@mafiesto4 Please add this to your documentation. Thank You.

I checked out the latest Flax Physics tour demo and it is a nice basic showing of examples. Simple but decent. We need a good performance loading project where we can see the physics system strained and where it drops off.

I am fairly convinced after digging that Flax runs closer to UE4 than Unity because of the ability to set the substepping (semi-fixed time step). UE5 uses a new Chaos Physics system that is likely based upon PhysX but with a lot of custom Epic things specific for UE5 needs (still semi-fixed time step).

Defaults of UE5.3 (latest) which I left at default when I started using UE5. Notice the max physics delta time is 0.0333 per frame (30.3 fps CPU) and substepping is not enabled by default. There is likely some toss off physics to the GPU to handle things without worrying about handshaking back to the CPU…speculation.
image

Since we are talking about Flax 1.6+ then I think Flax is essentially UE4 physics…CPU frame based calculations which make sense since game engines that did the GPU physics can be very buggy because of the CPU<->GPU handshake coordination. PhysX v5.1 has GPU Rigid Bodies so Flax has this as well but everything else is done on the CPU…which makes perfect sense. So this flow chart in the Flax manual is correct. Also makes sense logically why this is, because one would want to calculate any physics after vector lerps or other positional/rotational things. See below for the calcs section.

So my design is based upon 40fps (CPU) and 30fps at 1080p (GPU). My ‘frame’ is 25ms for code/logic/physics. This is a great breakpoint for performance checks and is easy to see who and where optimizations need to happen. Dips are allowed but the frame time (delta time) must return below. If your CPU frame is ever higher than 25ms you will have a lot of issues and hard to solve bugs. This was the case in Unity 4 Pro, Unity 5, up to Unity 2018 LTS, UE4 (4.18 was a painful change and 4.23 was a bit bumpy). I have had zero issues with this design…seems to be working well for Flax too but I am not far along enough yet to truly know. Getting there and no issues so far. UE5 is the exception and I stayed with the defaults.

image

The default of Flax default is too aggressive in my opinion and not really plausible is a real project.
image

Calcs…Flax (semi-fixed time step…same as UE4). These calcs work perfectly in Flax.
image

image

Calcs…Unity (Fixed time step)
image

A lot of details above but I think this was needed.

1 Like

I see that the Flax documentation has been updated! Nice !!

However, I think @OlanderDA 's diagram missed the LateFixedUpdate() part.
So I think it should be like this (the part I added is in Red text) :

@mafiesto4
@OlanderDA
Please feel free to correct me if I am wrong.
I also provide the “Fixed” diagram png here. Thank you

*) Double-Edited version, replying @AlTheSlacker the correct timing was :
OnFixedUpdate -> OnCollisionXXX (aka PhysX Step) -> OnLateFixedUpdate

Apologies, my mistake.

Looking at Github Engine.cpp it is clear that Physics::Simulate(dt); is called in the FixedUpdate code and that LateFixedUpdate fires after that. This was not what I was expecting as I thought the purpose of LateFixedUpdate was to override any changes in FixedUpdate prior to the physics simulation step. Clearly I was wrong and that is not its purpose.

1 Like

@AlTheSlacker
Actually, I was looking for a function called AFTER Collision but BEFORE Rendering,
so LateFixedUpdate() is the function fits my need if the timing above is correct.

1 Like

@TheOmnisimush
Flax Documentation looks the same in script events. The wording is very correct now so maybe that is where the documentation was updated?

I think what you are leaning on is already handled correctly by Flax. It is easy to test. Simply make some boxes (cubes) that you walk around and bump into and they bump into walls. A script with some information feedback can tell you the exact order of things happening. Combine that with a Frame Rate (CPU ms) and you have your physics update and order. Not difficult reverse engineering. Something all game designers should have to do. This test is also valuable later when the game is getting filled up with stuff and you want to see what is happening in a packed area.

With the changes I stated above in regards to the Framerate section what I have should be the defaults from Flax. I see no reason whay anyone would want to change from those values. The current Flax defaults are too aggressive in my opinion (according to the math).

Great topic! Love math. Great that this is being seriously examined.
And yes I am missing Flax.

Cheers
O

1 Like