Achievement Unlocked
Necessary Miscellaneous
So as stated previously, this week's unambitious goal was to fix this annoying physics bug where car bounces inadequately on static colliders. This meant first improving my engine through various changes:
Un-DLL
My project was split in two: an Engine library (which I intend to be open source and contain most of the usual systems / glue for the engine to work and to make simple games) and the Game's binary (which I would have made private at some point, containing systems & modules specific to whichever game I am working one). For some reason (probably because it seems encouraged in Windows? maybe a bit for compilation performance?) I had made Engine library a DLL. This meant that other static libraries dealing with global states (e.g. ImGui...) were difficult to properly integrate such that both the Engine and the Game projects could use them. I decided to move away from this issue by making my Engine a static library.
Physics Debugs
As explained in last week's newsletter, the engine is formed by a Physics World and a Rendering World. Each run completely independently but can send data to each other at the end of their respective frames through exchange contexts. Since physics runs on Physics World (unexpected, right?) I figured the later would also be responsible for running a system that generates physics debug shape to render -think a sequence of lines- and that those debug lines would be transferred to Rendering world through the appropriate exchange context. The good thing is that with this approach, those physics shape/collider components don't have to even exist on rendering world, and the physics' debug system is the same whether I continue with this Multi-World approach or I merge them into a single synchronous world later/for a future project less physics-heavy.
However, to remove noise while debugging my physics bug, I realized it was necessary to control more finely what shapes are rendered or not. Suddenly, having a system in Rendering World creating an ImGui windows (ImGui windows have to be created in rendering world and even in a specific thread) to update a DebugPhysicsContext to be provided to Physics World through exchange context so physics' debug system can read this copied DebugPhysicsContext and only generate debug lines for appropriate entities... felt cumbersome.
So I moved physics' debug system to Rendering World. Two caveats: it requires duplicating collider components in Rendering World, and I must also store in Rendering World the specific transform Physics World used its last update (because presentation's transform is interpolated so it would not show exactly what is going on in physics).
Here is updated debuggin capabilities. Broadphase candidates (near enough colliders to be considered by physics) are in orange and actually collided shapes are in red:
Controls
Debugging NaN and other wrong arithmetic in physics systems can be cumbersome without proper ways to reset the system but without restarting the program/game entirely. So I implemented various helping controls you may see me use in the future:
- full break (instantly stops the car)
- step/pause/resume simulation
- respawn
Fixing The Bug
So the bug was straight forward to reproduce: ram (even slowly) into a collider. To help, I simplified both my gym map (so it would be a floor + a single world) and my car (so it would have a single body part) and then I used my recently implemented features to:
- fully break to easily place myself in near a position where bug could occur
- read physics state a bit before the bug occurs and set it as map's initial/respawn state
- move frame by frame while going full throttle towards the wall
- respawn if I go to far
This done, I was able to narrow down the issue to ... ^drumroll^ (yes I messed up my markdown interpreter and cannot use `*`) ... a vector normalization issue!
Off course, with this bug being fixed I uncovered a few other to be fixed in upcoming weeks. I think this one is somewhat of a goofy one (does it count as a nice blooper?) given what happens after (an attempt at) resetting the simulation state:
More Miscellaneous
Finally, I decided to update my programming setup/layout and I thought I would end this week's newsletter by sharing what it now looks like when I'm vibbing (forgive me if my desk is still a bit of a mess):

Named this setup Logical Navigation Arrangement (LNA).
