# Designing a physics engine

By coincidence, right when The Cherno announced his game engine series I was just starting to get going on my own engine. I couldn’t wait to finally have a professional opinion on how to make one. With self-taught programming it’s hard to not doubt yourself constantly, wondering if you are doing things right or just think you are.

Recently, he has been posting videos about huge aspects of his engine like physics and entity systems, which were what I really wanted to learn about by making myself, but he ended up using libraries instead of going through the internals! I am not against using libraries, but to use them for the fun stuff? I felt like it defeated the point of making a custom engine series.

There is an argument to be made about saving time, but this was the first C++ project that I was making and the goal from the start was to go through all the major pillars of an engine: input, graphics, physics, entities, and audio. I wanted to learn how those things worked along with C++ and code design in general.

I bet that some other people are interested in the details of how these systems work, and I want to learn how to explain code better, so I am going to try and make some videos going over the internals of these systems. They end up being much simpler than at first glance.

Let’s start with the physics engine…

Physics engines are responsible for figuring out where each object in a scene is over time. Objects can collide with one another, then choose to respond in several ways. It’s a generic problem that the user can configure at several different levels. Do they want a collider? Do they want to respond to collisions? Do they want to simulate dynamics? They could want dynamics, but not gravity. It’s a problem that calls for good planning and robust design.

I looked at how bullet and box2d went about sorting their engines and concluded that the way bullet went about it was solid. I boiled it down to just what was needed, and based my design around that. There are already some great articles going over the hard math involved, so I am going to focus on the design aspect instead because I haven’t seen anyone do that, and it’s also a real headache.

At the current moment, this physics engine is not fully featured, but in future articles I plan to build it out further. This article will not cover rotation, multiple contact point collisions, or constrained simulation. I think it will work out for the best as it’s easy to get overwhelmed, and I want to ease into those topics. With that out of the way, let’s dive into the different parts of a physics engine.

The problem can be split into 2 or 3 pieces, dynamics, collision detection, and collision response. I’ll start with dynamics because it is by far the simplest.

Dynamics

Dynamics is all about calculating where the new positions of objects are based on their velocity and acceleration. In high school you learn about the four kinematic equations along with Newton's three laws which describe the motion of objects. We’ll only be using the first and third kinematic equations, the others are more useful for analysis of situations, not simulation. That leaves us with:

v = v_0+at \Delta x = v_0t + \frac{1}{2}at^2

We can give ourselves more control by using Newtons 2nd law, subbing out acceleration giving us:

v = v_0+\frac{F}{m}t x = x_0+vt

Each object needs to store these three properties: velocity, mass, and net force. Here we find the first decision we can make towards the design, net force could either be a list or a single vector. In school you make force diagrams and sum up the forces, implying that we should store a list. This would make it so you could set a force, but you would need to remove it later which could get annoying for the user. If we think about it further, net force is really the total force applied in a single frame, so we can use a vector and clear it at the end of each update. This allows the user to apply a force by adding it, but removing it is automatic. This shortens our code and gives a performance bump because there is no summation of forces, it’s a running total.

We’ll use this struct to store the object info for now.

struct Object {
vector3 Position; // struct with 3 floats for x, y, z or i + j + k
vector3 Velocity;
vector3 Force;
float Mass;
};


We need a way to keep track of the objects we want to update. A classic approach is to have a physics world that has list of objects and a step function that loops over each one. Let’s see how that might look; I’ll omit header/cpp files for brevity.

class PhysicsWorld {
private:
std::vector<Object*> m_objects;
vector3 m_gravity = vector3(0, -9.81f, 0);

public:
void AddObject   (Object* object) { /* ... */ }
void RemoveObject(Object* object) { /* ... */ }

void Step(
float dt)
{
for (Object* obj : m_objects) {
obj->Force += obj->Mass * m_gravity; // apply a force

obj->Velocity += obj->Force / obj->Mass * dt;
obj->Position += obj->Velocity * dt;

obj->Force = vector3(0, 0, 0); // reset net force at the end
}
}
};


Note the use of pointers, this forces other systems to take care of the actual storing of objects, leaving the physics engine to worry about physics, not memory allocation.

With this you can simulate all sorts of stuff from objects flying through the sky to solar systems.

You can do a lot with this, but it’s the easy part to be honest, and that’s not what you came for…

Collision detection

Collision detection is more involved, but we can lighten the load by using some clever tricks. Let’s think about what needs to be found first. If we look at some examples of objects colliding, we notice that in most cases there is a point on each shape that is furthest inside the other.

This turns out to be all we need to respond to a collision. From those two points we can find the normal, and how deep the objects are inside one another. This is huge because it means that we can abstract the idea of different shapes away, and only worry about the points in the response.

Let’s jump into the code, we’ll need some helper structs that I’ll note first.

struct CollisionPoints {
vector3 A; // Furthest point of A into B
vector3 B; // Furthest point of B into A
vector3 Normal; // B – A normalized
float Depth;    // Length of B – A
bool HasCollision;
};

struct Transform { // Describes an objects location
vector3 Position;
vector3 Scale;
quaternion Rotation;
};


Each shape will have a different type of collider to hold its properties and a base to allow them to be stored. Any type of collider should be able to test for a collision with any other type, so we’ll add functions in the base for each one. These functions will take Transforms, so the colliders can use relative coordinates. I’ll only demonstrate spheres and planes, but the code is repeatable for any number of colliders.

struct Collider {
virtual CollisionPoints TestCollision(
const Transform* transform,
const Collider* collider,
const Transform* colliderTransform) const = 0;

virtual CollisionPoints TestCollision(
const Transform* transform,
const SphereCollider* sphere,
const Transform* sphereTransform) const = 0;

virtual CollisionPoints TestCollision(
const Transform* transform,
const PlaneCollider* plane,
const Transform* planeTransform) const = 0;
};


Let’s make both types of colliders at the same time too see how they interact. A sphere is defined as a point and a radius, and a plane is defined as a vector and a distance. We’ll override the functions from Collider, but won’t worry about the work for now.

We can choose per collider which other colliders it will detect by filling, or not filling, in these functions. In this case, we don’t want Plane v Plane collisions, so we return an empty CollisionPoints.

struct SphereCollider
: Collider
{
vector3 Center;
float Radius;

CollisionPoints TestCollision(
const Transform* transform,
const Collider* collider,
const Transform* colliderTransform) const override
{
return collider->TestCollision(colliderTransform, this, transform);
}

CollisionPoints TestCollision(
const Transform* transform,
const SphereCollider* sphere,
const Transform* sphereTransform) const override
{
return algo::FindSphereSphereCollisionPoints(
this, transform, sphere, sphereTransform);
}

CollisionPoints TestCollision(
const Transform* transform,
const PlaneCollider* plane,
const Transform* planeTransform) const override
{
return algo::FindSpherePlaneCollisionPoints(
this, transform, plane, planeTransform);
}
};

We can add a function for testing the base and use a technique called double dispatch. This takes advantage of the type system to determine both types of colliders for us by swapping the arguments, determining the first, then the second type through two calls of TestCollision. This saves us needing to know what type of colliders we are checking, which means we’ve fully abstracted away the notion of different shapes outside the collision detection.

struct PlaneCollider
: Collider
{
vector3 Plane;
float Distance;

CollisionPoints TestCollision(
const Transform* transform,
const Collider* collider,
const Transform* colliderTransform) const override
{
return collider->TestCollision(colliderTransform, this, transform);
}

CollisionPoints TestCollision(
const Transform* transform,
const SphereCollider* sphere,
const Transform* sphereTransform) const override
{
// reuse sphere code
return sphere->TestCollision(sphereTransform, this, transform);
}

CollisionPoints TestCollision(
const Transform* transform,
const PlaneCollider* plane,
const Transform* planeTransform) const override
{
return {}; // No plane v plane
}
};


In cases like this, where there are many classes with a web of similar functions, it can be confusing as to where the actual code is located. Sphere v Sphere would obviously be in the Sphere.cpp file, but Sphere v Plane could be in either Sphere.cpp or Plane.cpp, there is no way to know without hunting, which gets annoying when there are many files.

To get around this lets let’s make an algo namespace and put the actual work in there. We’ll need a function for each pair of colliders we want to be able to check. I’ve made a Sphere v Sphere, Sphere v Plane, but not Plane v Plane because it’s not so useful. I’m not going to cover these functions here because they are not part of the design per se, but you can check out the source if you are interested.

namespace algo {
CollisionPoints FindSphereSphereCollisionPoints(
const SphereCollider* a, const Transform* ta,
const SphereCollider* b, const Transform* tb);

CollisionPoints FindSpherePlaneCollisionPoints(
const SphereCollider* a, const Transform* ta,
const PlaneCollider* b, const Transform* tb);
}

You can use these colliders on their own, but most likely want to attach one to an object. We’ll replace Position with a Transform in the Object. We are still only using position in the dynamics but can use scale and rotation in the collision detection. There is a tricky decision to make here. I’m going to use a Transform pointer for now, but we’ll come back to this at the end and see why that might not be the best choice.

struct Object {
float Mass;
vector3 Velocity;
vector3 Force;

Collider* Collider;
Transform* Transform;
};


A good design practice is to separate all the different aspects of complex functions like Step into their own. This makes the code much more readable, so let’s add another function named ResolveCollisions in the physics world.

First, another helper struct…

struct Collision {
Object* ObjA;
Object* ObjB;
CollisionPoints Points;
};


Again, we have the physics world, I’ll compact the parts we have already looked at but it’s nice to have context.

class PhysicsWorld {
private:
std::vector<Object*> m_objects;
vector3 m_gravity = vector3(0, -9.81f, 0);

public:
void AddObject   (Object* object) { /* ... */ }
void RemoveObject(Object* object) { /* ... */ }

void Step(
float dt)
{
ResolveCollisions(dt);

for (Object* obj : m_objects) { /* ... */ }
}

void ResolveCollisions(
float dt)
{
std::vector<Collision> collisions;
for (Object* a : m_objects) {
for (Object* b : m_objects) {
if (a == b) break;

if (    !a->Collider
|| !b->Collider)
{
continue;
}

CollisionPoints points = a->Collider->TestCollision(
a->Transform,
b->Collider,
b->Transform);

if (points.HasCollision) {
collisions.emplace_back(a, b, points);
}
}
}

// Solve collisions
}
};

This is looking good, because of that double dispatch there is no need for anything other than a single call to TestCollision. Using a break in the for loop gives us the unique pairs, so we never check the same objects twice.

There is only one annoying caveat which is that because the order of the objects is unknown, sometimes you will get a Sphere v Plane check, but others will be a Plane v Sphere check. If we just called the algo function for Sphere v Plane, we would get the reverse answer, so we need to add some code in the plane collider to swap the order of the CollisionPoints.

CollisionPoints PlaneCollider::TestCollision(
const Transform* transform,
const SphereCollider* sphere,
const Transform* sphereTransform) const
{
// reuse sphere code
CollisionPoints points = sphere->TestCollision(sphereTransform, this, transform);

vector3 T = points.A; // You could have an algo Plane v Sphere to do the swap
points.A = points.B;
points.B = T;

points.Normal = -points.Normal;

return points;
}


Now that we have detected a collision, we need some way to react to it.

Collision Response

Because we have abstracted away the idea of different shapes into points, the collision response is almost pure math. The design is relatively simple compared to what we just went through; we’ll start with the idea of a solver. A solver is used to solve things about the physics world. That could be the impulse from a collision or raw position correction, really anything you choose to implement.

Let’s start with an interface.

class Solver {
public:
virtual void Solve(
std::vector<Collision>& collisions,
float dt) = 0;
};

We’ll need another list in the physics world to store these, and functions to add and remove them. After we generate our list of collisions, we can feed it to each solver.

class PhysicsWorld {
private:
std::vector<Object*> m_objects;
std::vector<Solver*> m_solvers;
vector3 m_gravity = vector3(0, -9.81f, 0);

public:
void AddObject   (Object* object) { /* ... */ }
void RemoveObject(Object* object) { /* ... */ }

void AddSolver   (Solver* solver) { /* ... */ }
void RemoveSolver(Solver* solver) { /* ... */ }

void Step(float dt) { /* ... */ }

void ResolveCollisions(
float dt)
{
std::vector<Collision> collisions;
for (Object* a : m_objects) { /* ... */ }

for (Solver* solver : m_solvers) {
solver->Solve(collisions, dt);
}
}
};

In the last section the meat was in the design, this one leans much more towards what kinds of solvers you implement. I’ve made an impulse & position solver myself that seem to work for most situations. To keep this short, I won’t cover the math here, but you can check out the source for the impulse solver here, and the position solver here if you are interested.

Let’s see a demo!

More Options

The real power of a physics engines comes from the options that you give to the user. In this example there aren’t too many that can be changed, but we can start to think about the different options we want to add. In most games you want a mix of objects, some that simulate dynamics, and others that are static obstacles. There is also a need for triggers, objects that don’t go through the collision response, but fire off events for exterior systems to react to, like an end of level flag. Let’s go through some minor edits we can make to allow these settings to be easily configured.

The biggest change we can make is to distinguish between objects that simulate dynamics and ones that don’t. Because of how many more settings a dynamic object needs, let’s separate those out from what is necessary for collision detection. We can split Object into CollisionObject and Rigidbody structs. We’ll make Rigidbody inherit from CollisionObject to reuse the collider properties and allow us to store both types easily.

We are left with these two structs. A dynamic_cast could be used to figure out if a CollisionObject is really a Rigidbody, but will make code slightly longer, so I like to add a boolean flag even through it’s not considered best practice. We can also add a flag for the object to act as a trigger and a function for a callback. While we’re at it, let’s beef up the security by protecting the raw values.

struct CollisionObject {
protected:
Transform* m_transform;
Collider* m_collider;
bool m_isTrigger;
bool m_isDynamic;

std::function<void(Collision&, float)> m_onCollision;

public:
// getters & setters, no setter for isDynamic
};


We can add many more settings to the Rigidbody. It’s useful if each object has its own gravity, friction, and bounciness. This opens the door to all sorts of physics based effects. In a game you could have an ability that changes the gravity in an area for a time. You could have some objects be bouncy and other like weight balls. A floor could be made of ice and be slippy for a harder challenge.

struct Rigidbody
: CollisionObject
{
private:
vector3 m_gravity;  // Gravitational acceleration
vector3 m_force;    // Net force
vector3 m_velocity;

float m_mass;
bool m_takesGravity; // If the rigidbody will take gravity from the world.

float m_staticFriction;  // Static friction coefficient
float m_dynamicFriction; // Dynamic friction coefficient
float m_restitution;     // Elasticity of collisions (bounciness)

public:
// getters & setters
};


Let’s split the PhysicsWorld into a CollisionWorld and a DynamicsWorld as well. We can move the Step function into the DynamicsWorld, and ResolveCollisions into the CollisionWorld. This saves someone who doesn’t want dynamics from sifting through functions that are useless to them.

We can make some edits to ResolveCollisions function to give triggers their correct functionality. Let’s split the function into its parts to keep it readable. Adding a callback to the world can be useful too if you want program wide events.

class CollisionWorld {
protected:
std::vector<CollisionObject*> m_objects;
std::vector<Solver*> m_solvers;

std::function<void(Collision&, float)> m_onCollision;

public:
void AddCollisionObject   (CollisionObject* object) { /* ... */ }
void RemoveCollisionObject(CollisionObject* object) { /* ... */ }

void AddSolver   (Solver* solver) { /* ... */ }
void RemoveSolver(Solver* solver) { /* ... */ }

void SetCollisionCallback(std::function<void(Collision&, float)>& callback) { /* ... */ }

void SolveCollisions(
std::vector<Collision>& collisions,
float dt)
{
for (Solver* solver : m_solvers) {
solver->Solve(collisions, dt);
}
}

void SendCollisionCallbacks(
std::vector<Collision>& collisions,
float dt)
{
for (Collision& collision : collisions) {
m_onCollision(collision, dt);

auto& a = collision.ObjA->OnCollision();
auto& b = collision.ObjB->OnCollision();

if (a) a(collision, dt);
if (b) b(collision, dt);
}
}

void ResolveCollisions(
float dt)
{
std::vector<Collision> collisions;
std::vector<Collision> triggers;
for (CollisionObject* a : m_objects) {
for (CollisionObject* b : m_objects) {
if (a == b) break;

if (    !a->Col()
|| !b->Col())
{
continue;
}

CollisionPoints points = a->Col()->TestCollision(
a->Trans(),
b->Col(),
b->Trans());

if (points.HasCollision) {
if (    a->IsTrigger()
|| b->IsTrigger())
{
triggers.emplace_back(a, b, points);
}

else {
collisions.emplace_back(a, b, points);
}
}
}
}

SolveCollisions(collisions, dt); // Don't solve triggers

SendCollisionCallbacks(collisions, dt);
SendCollisionCallbacks(triggers, dt);
}
};

To keep the Step function readable, let’s split it up into pieces as well.

class DynamicsWorld
: public CollisionWorld
{
private:
vector3 m_gravity = vector3(0, -9.81f, 0);

public:
void AddRigidbody(
Rigidbody* rigidbody)
{
if (rigidbody->TakesGravity()) {
rigidbody->SetGravity(m_gravity);
}

AddCollisionObject(rigidbody);
}

void ApplyGravity() {
for (CollisionObject* object : m_objects) {
if (!object->IsDynamic()) continue;

Rigidbody* rigidbody = (Rigidbody*)object;
rigidbody->ApplyForce(rigidbody->Gravity() * rigidbody->Mass());
}
}

void MoveObjects(
float dt)
{
for (CollisionObject* object : m_objects) {
if (!object->IsDynamic()) continue;

Rigidbody* rigidbody = (Rigidbody*)object;

vector3 vel = rigidbody->Velocity()
+ rigidbody->Force() / rigidbody->Mass()
* dt;

rigidbody->SetVelocity(vel);

vector3 pos = rigidbody->Position()
+ rigidbody->Velocity()
* dt;

rigidbody->SetPosition(pos);

rigidbody->SetForce(vector3(0, 0, 0));
}
}

void Step(
float dt)
{
ApplyGravity();
ResolveCollisions(dt);
MoveObjects(dt);
}
};

Now we have a whole stack of options that the user can configure for many different scenarios with a simple yet powerful API.

There is one more option that I want to cover. The physics world has no need updating every frame. Say a game like CS:GO gets rendered at 300 fps. It’s not checking the physics every frame; it might run at 50 Hz instead. If the game only used the positions from the physics engine, objects would have .02 seconds between each update, causing a jittery look. And that’s an ideal rate, some games will only update at 20 Hz leaving .05 seconds between update!

To get around this, it is common to split the physics world from the rendered world. This is simply done by using a raw Transform instead of a pointer and having a system outside the physics interpolate the position every frame. Let’s see how we might implement this.

First, we’ll get rid of that pointer. We’ll need to add a last transform as well which will gets set just before the update in MoveObjects.

struct CollisionObject {
protected:
Transform m_transform;
Transform m_lastTransform;
Collider* m_collider;
bool m_isTrigger;
bool m_isStatic;
bool m_isDynamic;

std::function<void(Collision&, float)> m_onCollision;
public:
// Getters & setters for everything, no setter for isDynamic
};


Because we used getters and setters, this won’t break any code outside the CollisionObject. We can make an exterior system that keeps track of how far it is into the physics update and use a linear interpolation between the last and current position. I’m not going to go into where to put this system, but it should update every frame rather than every physics update.

class PhysicsSmoothStepSystem {
private:
float accumulator = 0.0f;

public:
void Update() {
for (Entity entity : GetAllPhysicsEntities()) {
Transform*       transform = entity.Get<Transform>();
CollisionObject* object    = entity.Get<CollisionObject>();

Transform& last    = object->LastTransform();
Transform& current = object->Transform();

transform->Position = lerp(
last.Position,
current.Position,
accumulator / PhysicsUpdateRate()
);
}

accumulator += FrameDeltaTime();
}

void PhysicsUpdate() {
accumulator = 0.0f;
}
};


This system smoothy moves the objects between their positions in the physics engines every frame, removing all jittery artifacts from the movement.

And that’s the final result. I hope you can use the principles from this article to get a better idea of how to lay out complex systems in nimble ways, or even make your own engine. There is a lot more to cover, but I’ll leave it to a part 2 because this is getting long. Let me know what you thought, should I keep focusing on design, or dive deeper into the math behind the implementations?

Thanks for reading, I hope to catch you next time!

# Comments

### peter1745

Funny thing is I was looking around the internet on resources related to creating a custom physics engine when I stumbled upon this post, I just so happen to be guy that implemented 3D Physics in The Chernos engine that you mentioned xD
P.S Sorry for using PhysX and not writing a custom physics engine 😉

### Iain

Hey I’ve been inundated with spam in these wordpress comments 🙁 That’s awesome, funny how small the game dev content world is! That PhysX demo with the ball rolling down the hill did look a lot better than these spheres lmao.

lmao cherno bad

### Dean White

Thanks for the article. It re-enforces some stuff I have been doing. I used Tokamak SDK in 2004 and it was nice but lacked support and bug fixes but had some nice results.

I have been developing my own 2d/3d engine in Direct X 11 from scratch and are now prototyping a game for it. Quite a learning curve as I has to learn HLSL from scratch and added a heap of other things (fog, shadowing, multiple lights, point sprites, scene manager, model loading and animation)

I toyed for a long time over a physics engine and TBO they all have pros and cons. Going for a custom one as I’m a big fan of optimizing and spheres/circles.

Bounding spheres are just so simple and powerful they’re often overlooked. At the very least I use them to determine if a more accurate check is needed as 99% of the time the sphere will eliminate a case with a single decision.

Spheres are also easy to take into consideration scaling and rotation as well if needed.

I had a 2d engine years ago that only used 2d circles for collision detection and it was fantastic. It had 3 levels, 1st level always was the smallest that would enclose the entire shape. If this was rejected… then no chance of a collision. Next level was 1 -> n circles that would be more accurate and would be checked against each in the other object at the same level. Again… of no hit then it’s rejected. When a hit is detected the process is repeated for the next level if there is one otherwise the 2 circles that are hit return the response.

The great thing about it was… collisions between scaled and rotated sprites was dead easy and very accurate and MUCH easier than polygons and mixed geometry checking.

### Iain

It’s funny how far you can get with just circles. For a game I’ve been making in 3D I got away with only Spheres and Planes for 90% of it. Finally I had to add Capsules because the planes could only be infinite! I haven’t looked into any broadphase checks yet, but I think I’ll end up going with some sort of sphere check because even with the n^2 nature of that it’s such a simple algo it almost doesn’t matter.

### Dean White

Since the comment I’ve added and test spheres to my 3D space invaders (which is technically a 2D game using 3D geometry). I’m very happy with the spheres, nice and fast.

When checking a bomb vs a shelter I sort of cheat a bit and check if the bomb is inside the bounding box of all the shelters 1st. If it is… then I check. This way the maximum of 100 bits is only checked occasionally. Same with collisions vs my ship… no point unless the bomb Y is < top of ship height.

Other thing is… for this game the checking is "fuzzy" anyway. Don't want to kill an alien cause 1 pixel of the bullet hit a whisker. I create the spheres so that if 2 touch it means decent contact was made.

The simplicity also means I've implemented the checks in the header as a single line so it get inlined.

### Ramon

Both this blog and the youtube channels are a gem, I’ve used this and the GJK posts to solve the issues I had with my physics engine and I cannot thank you enough for that.

### Iain

Thanks for the nice comment, glad I helped!

### Roy

Awesome tutorial! Thanks for sharing

### Lance

Your style is so unique compared to other people I’ve read stuff from.
I appreciate you for posting when you’ve
got the opportunity, Guess I will just bookmark this site.

### Iain

Thanks, I’m glad you found it a good read!

### JR

Hi,
I also wanted to say massive thanks for this article. It is well presented and clear.

Yes I also watched TheCherno’s vid on phys and was very confused in the end how he went from trying to impl a phys engine to using an existing one… but fair enough, no harm done, the journey is different for each and everyone of us 🙂

I’m not investigating phys engines at the moment, but always wondered about the code behind. Yes there are existing libs out there, and we could use them, but I like someone who digs in to work it all out and now to be honest, I really feel inspired to scratch a custom phys engine,try it out based on your clear explanation… and yes I would be doing it purely because I want to learn this way rather than learn how for example physX or others work ( nothing wrong with established physX et al, they’re dope right 🙂 )

Please, if u don’t mind and have time (and if you haven’t already started), do another video for 2nd part (still on the design as you suggested) then video part3 (would be on the maths).

If you are already in the middle of the next vid, then don’t worry, carry on as you were.
Your presentation is excellent. I feel proud, well done sir 🙂

### JN

Agree, good read, pls moar

### gerds

I agree with @edwinem. Good article and nice to see some videos of the results.

### ratish

Thanks for this article. Very informative. Keep them coming

### Designing a Physics Engine | Hacker News

[…] Designing a Physics Engine (winter.dev) […]

### edwinem

Just wanted to say thanks. This was a very high quality article and video, and will definitely be looking forward to similar content.

# Other Articles

Making an infinite world with Falling Sand part 2

Welcome back to the sand series, this post directly follows from what we did last time, so if you missed that, here’s the link. In this post we’ll first split the world into chunks, then look at some ways to speed it up. Splitting the world into chunks The main feature that chunks allow for […]

March 27, 2021
Making games with Falling Sand part 1

I want to get familiar with the process of releasing a game before I finish Metal Sphere Rising, so I’m planning on making a game in a month, and then releasing it on Steam or something. My brother and I were talking about it and came up with the idea of a space version of […]

December 30, 2020
EPA: Collision response algorithm for 2D/3D

Last time we looked at an algorithm for testing collisions between two convex polygons called GJK. It’s a useful algorithm for sure, but it doesn’t give us enough information to respond to the collisions it detects. In this article I’ll describe an extension that allows us to find the correct normal and depth of the […]

November 17, 2020
Mesh generation

This post is less about some specific information and more about something I’ve been cooking up over at winter.dev/prims. When working in 3D everything is made out of meshes. In their simplest form these are big lists of positions that get fed into the GPU for rendering. These lists can be generated or loaded from […]

October 6, 2020
GJK: Collision detection algorithm in 2D/3D

In my last article, I only covered sphere vs. sphere collisions because they are the simplest to compute. Spheres are nice and all, but there comes a time when more complex shapes are needed. One popular algorithm for testing collisions is the Gilbert–Johnson–Keerthi algorithm, or GJK for short. With it we can detect collisions between […]

August 29, 2020
Another way of programming, taking it slow

Whenever I sit down to write some code, I always get an itch to finish whatever problem is staring me in the face right at that moment. Over the last 2 years, I’ve realized that if you can afford to tackle a problem over a long period of time, you should absolutely go for that […]

July 6, 2020
World 1 demo brings you to the outer forests

Calling all playtesters, After 2 months from the last playtest, the third demo is ready for review. This one brings the first real graphics to the game; with the addition of Voxel Cone Tracing there’s a warm glow to the whole forest. Right now that’s the biggest time sink per-frame so I am doing some […]

July 4, 2020

# Projects

Game engine

IwEngine is an engine that I started as a way to lean about how computer games are made. Right now I am trying to make my first publishable game with it. I started by making something that was linear and story based and got about 50% done with it, but I wanted to try and publish something smaller and more arcade like first. That has turned into these sand games...

Mesh generation

Every shape has some method of generating a mesh for it, but there is no good central spot. This website will eventially contain a full list of differnt algorithms for every shape.

YouTube Subscriber tracker

Youtube removed the exact subscriber count. This resolves that issue and graphs my count ever hour.

# Support

BY MAIL

Support with your eyes. I enjoy writing these posts and editing the videos that go along with them. It is very satisfying reading the comments and seeing people enjoying and hopefully learning something from what I make. Sign up to get an email notification for whenever I make a new post. It seems like my pace is around once a month, so don't worry about spam :)

ON YOUTUBE

Did you know I make video version of these posts? Check out the 5-10 minute condenced versions over on YouTube. I end up putting about the same amount of time into them as the posts themselves, so would appreciate a view!

ON TWITTER

Over on Twitter I post updates about videos while they're being made along with other random thoughts. If that sounds more your speed, I'd appreciate a follow :)