Bugfixing
Busy week meant simply fixing bugs over the weekend. Here is my progress:
Profiling
As I have stated in previous newsletters, performance has been a bit of a roller-coaster lately with implementation of various rendering features. I had integrated Optick profiler to my codebase but it is not a very fast profiler (a 10s recording can sometimes overwhelm my computer) and it struggles with my asynchronous engine architecture; see in this screenshot how vertical slices representing frame boundaries span both the rendering and physics thread. This is because Optick doesn't support a game where different threads work at different frame/tick-rates:

However my engine is designed such that various thread groups (thread(s) processing updates of a World) can run a various rates (MultiWorld). In the case of my current game, simulation/physics World is setup to run deterministically at 100 ticks per second (at bottom of screenshot, FixedRateLimitingSystem is there to wait until enough time has passed until next tick can start) while rendering World is setup to run however fast it can for a smooth experience. Those asynchronous threads can then communicate through a producer/consumer pattern (maybe I should expand in a future post how this multi-world architecture works if readers are interested?).
So, facing those bugs with Optick I decided to replace it with Tracy, a more advanced profiler. The later is much more efficient (it can even keep running in the background for live-profiling with little performance impact). It has a little bit rougher interface but has many interesting features such has memory tracking or embedding screenshot of the game inside the captured trace. Here is what a capture look like:

Wait.. did you spot it? Tracy doesn't understand asynchronous threads either ; if both threads notify when their respective frame start, Tracy is confused. That being said, I can disable frame markers on simulation tread and it looks much better than it did in Optick (no time for screenshot, trust me).
Tickrate
Another thing to notice in those screenshot is how irregular the update of physics seems to be. Notice below how the CollisionSystem ("Co..." in blue) is sometimes updated twice back to back.

This is what I actually intended to fix at first when switching to Tracy, but I then realized there was an issue with my code. Upon investigating, it turns out to be an OS oddity: the std::this_thread::sleep_for function I was using in this FixedRateLimitingSystem only guarantees that thread will yield for specified amount of time, but it may be more.
The function is actually intended to be used by a wide range of softwares that don't require millisecond accuracy. Therefor Windows, by default, only attempts to wake up threads every 15ms or so. By telling the OS to attempt to process sleeping threads every 1ms (lowest allowed) and by spinning (dummy while loop) for the last 1ms, it ensures a better accuracy!
Physics
The next bug I intended to investigate this weekend was related to physics. In my first post in January I showed a 2025 demo of my physics which was working great and tightly. However I have since refactored a lot, including this asynchronous pattern I talked about above, and it appears I broke some physics along the way: car can clip through colliders without being pushed back and then suddenly bumps far.
To help investigate, I implemented the ability to instantly stop the car or to respawn it in a specific state. However it is almost midnight and I still haven't been able to fix the issue; here is what it look like and what I intend to fix for next week's newsletter (I'm being very mediocre with my intentions; if you know why, you know why).
RSS
Oh and also, last week's newsletter didn't send: my host had (mistakenly? :D) flagged my emails as potential scam. It should have been fixed now, but just in case (and following suggestions by two independent parties...) I figured implementing an RSS feed was the right thing to do. It should be accessible at https://drouin.io/feed but I will continue sending emails to current subscribers for the time being. Hope all works!
