Project Type: SDL2 Toy Engine
Project Timeframe: November 2023
The goal of the project was to build, from theory and whitepapers, a simple 2d physics engine that can be used to make games. Mainly as a practice project to teach myself the basics of how physics engines work.
(Linked text directs to the relevant spot in the code repository)
The start of the project was building a 2-body arbitrary shape collision solver. For this I used the Separating Axis Theorem, as it is relatively simple to implement.
With a working 2-body solver in hand, the next step was to implement an iterative multi-body solver. But this requires a lot more than a toy SAT implementation. So first I went and figured out world and object representations.
Although I really like using C for quick toy examples, I had now reached the point at which I usually switch to C++, and in hindsight that would've probably been the better option. However, my recent explorations of Rust meant that I had learned of the joy of "Trait"-style polymorphism (most comparable to C++ interfaces). So I wanted to try using those in C. For this I found an approach to implementing typeclasses in C (the article for which isn't online anymore, but I explained my version over on my blog).
The requirements for any game object to be part of the physics world is that it has to at least implement
PhysicsEntity,
which in turn requires
Transformable
to be implemented. As solving collisions requires modifying the transform of the object.
In order to be rendered, and for the update function to be called, the object also has to implement
BehaviourEntity,
which exposes the object lifetime functions spawn, update, start, and draw. And itself requires
Drop
to be implemented. Drop being pretty much the best destructor implementation you can get in C without implementing a garbage collector.
With the world represented, the work on the collision solver could start. Objects that implement PhysicsEntity can then register themselves with the
physics world.
Once an object is registered to the physics world it will use the SAT to check for collisions, and finally, that comes to the multi-body iterative collision solver.
The iterative solver
is implemented in the static functions of the PhysicsEntity typeclass.
This all then comes together in something like the
Player
struct, which implements all these typeclasses and uses them to create a platformer character. Or the
Tilemap
object that can be loaded from LDTK levels to create a renderable physics entity that can be hit and interacted with by the player.