Collisions
Why:
Whether it is for 2D or 3D games, collisions are used a lot.
Even the oldest games, like Tetris and Pacman, have some sort of collisions.
After all this time, developers have found ways to simulate even more complex collisions :
- Box2D is opensource and was made by Erin Catto, but is not 3D
- PhysX was made by NVidia, but was discontinued
- Bullet, a 3D opensource collision library
- Chaos, recently developed by Unreal Engine
- Havok, used by Nintendo, Ubisoft, and others, but being premium
- Jolt Physics, a new 3D opensource used Horizon Forbidden West
- And more…
However, since the old days, new ways to represent shapes are being used:
- 2D boxes, moving freely (example : Mario)
- 2D Sprite pixels, for pixel to pixel collisions
- Complex 2D shapes, with multiple points
- 3D triangles, the mainstream way to represent 3D models
- Sign Distance Functions, being mathematical expressions of a shape
- And even more…
The way to handle collisions is still evolving.
Some games also require custom collisions to be optimal.
Example : Minecraft only requires collisions between boxes and cylinders. The collision between chunks don’t even have to be tested.
How:
The collisions will be implemented that way (unless if specified otherwise):
struct ShapePair
{
    Shape* shape1;
    Shape* shape2;
};
class CollisionDetector
{
    std::vector<Shape> registeredShapes;
    BroadPhase broadPhase;
    NarrowPhase narrowPhase;
    void Register(const Shape& shape)
    {
        broadPhase.Register(shape);
    }
    void Unregister(const Shape& shape)
    {
        broadPhase.Unregister(shape);
    }
    void SimulateCollisions()
    {
        // A container of potentially colliding pairs
        // Could return a std::vector, std::list, etc
        auto& pairs = broadPhase.GetPotentiallyCollidingPairs();
        for (ShapePair& pair : pairs)
        {
            CollisionInfo collisionInfo;
            if (narrowPhase.AreShapesColliding(pair.shape1, pair.shape2, collisionInfo))
            {
                RunPhysicalResponse(pair.shape1, pair.shape2, collisionInfo);
            }
        }
    }
};