Gold Medal Games
Gold Medal Games logo
Gameplay Made Great
Written: 12/28/2025

GMGE Physics Part 1 of 3 - Forces and movement

Introduction

Let's face it, you can't really have any sort of action games without some amount of physics. At the very least, we need to be able to detect and respond to objects colliding. The GMGE Physics Engine is not intended to build physics-style games. If you want to make a game with a lot of complex physics (described below), GMGE is definitely not the engine to use.

Did the world need a new game-physics engine? Maybe. For starters, GMGE needed a physics engine. While there are plenty to choose from, they are mostly general purpose, which means they are fairly complex. Additionally, they aren't necessarily optimized for the types of games I want to build. I wanted something that runs fast in mobile browsers and is written in Javascript. Also, I thought it would be kind of fun to try and build from a learning perspective.

In Part 1, this first article, we cover the basics of movement. We define a physics-body (typically known as a rigid-body), and apply forces to it so it moves about a game-world.

In Part 2, we'll define a collision-layer interaction matrix, and cover collision detection.

Part 3 brings it all together as we cover collision resolution.

Physics Body

This is a description of the gmgePhysicsBody object

There are 3 types of physics bodies in GMGE.

  1. Static - These objects don't move in the game world. If they have a physics collider defined, then things cannot move through them either. Typical static objects would be terrain-like things such as platforms, walls, trees, etc.
  2. Kinematic - Game logic controls movement, like the player in the game being controlled by user input, or enemies being controlled via AI. However, they still need to respond to collisions. For example, characters shouldn't be able to move through walls (typically)
  3. Dynamic - The physics engine controls the movement by applying forces like gravity. Typically something like a thrown ball, where you want it to look realistic by both being affected by forces and colliding with objects like the ground.

In order for various physics calculations to work, physics bodies also need values for the following:

There are also some "hidden" values that should not be set directly by developers. They are controlled by by the physics engine. They are all prefixed with an underscore. (In general, in GMGE, anything with an underscore prefex should not be used directly by developers. Setting them will likely break things, and reading them is not reliable because you don't know at what point during a frame they will be updated.)

Not counting the velocity or acceleration, things in a physics body are set once when the object is created. Like it typically doesn't make sense for an object to lose mass during the game. However, if you wanted to simulate an ice cube melting for example, and you modified its mass over time, you would also need to directly set _inverseMass, otherwise the phyics calculations would still be based on the original mass.


IterateForDuration

This is the main starting point for physics calculations each frame. It is passed one parameter deltaTime that represents how much time has passed since the previous call of this function. In GMGE deltaTime is a global variable, so why is it passed to IterateForDuration?

GMGE runs in a browser on a device with other things running in the background. That results in variable frame rates. Variable frame rates means non-deterministic physics results, which can be maddening while trying to debug something. By passing in a value, you can force a fixed phyics frame rate to help troubleshoot things. Of course doing this means that physics time drifts away from actual time which will result in jumpy motion. For an extreme example, if we set every physics update to be 0.1s, but the real elapsed time is 0.5s, the objects appear to move slower than they should have. Therefore, in general, for most games, passing in the global deltaTime provides the best results.

Because GMGE assumes a variable frame rate, and you could change gravity during gameplay based on your design, each frame calculates a couple gravity related variables.

The main loop is the work horse and does its thing by looping through all active game objects. Every GMGE object has an isActive member variable. If that is set to false, then it is skipped when considering physics. It is also possible to define game objects that do not have a physicsBody defined. Those are skipped as well.

For motion calculations, the physics engine only acts on active objects, with a physicsBody where its type is dynamic. Here is the main body of the physics loop (please note that obj is a reference to the current object, and pb is a reference to its physicsBody):

// Start with the object's constant acceleration // this.finalAccel.Set(pb.acceleration.x, pb.acceleration.y); // Add in acceleration due to gravity, scaled to this object // this.finalAccel.AddScaled(this.gravity, pb.gravityScale); // Apply the accumulated forces // this.finalAccel.AddScaled(pb._forceAccumulator, pb._inverseMass); // Update linear velocity based on acceleration // pb.velocity.AddScaled(this.finalAccel, deltaTime); // Apply drag // pb.velocity.Scale(Math.pow(pb._linearDamping, deltaTime)); // Clear force accumulator for next iteration // pb._forceAccumulator.Clear(); // Clamp velocity for frozen axes // pb.velocity.x = pb.freezeX ? 0 : pb.velocity.x; pb.velocity.y = pb.freezeY ? 0 : pb.velocity.y; // If the object is moving slow enough, just stop it completely // if(pb.velocity.LengthSquared() < this.motionThreshold) { pb.velocity.Clear(); } // Update the objects position // obj.transform.position.AddScaled(pb.velocity, deltaTime);

The basic gist of how it works is pretty straightforward. For every dynamic object in the scene, determine the final acceleration to be applied to it by adding its current acceleration, gravity, all external forces added during the frame, and its current velocity. Then apply any friction. (Something to note about friction. It is really simplified in GMGE. An object falling through the air has the same amount of friction as two objects sliding across each other. That is why you can scale the gravity amount for an object.)

Next it clears the external forces accumulator, so it is ready for the next frame. After that, any movement along a frozen axis, if one exists, is zeroed out. Once motion falls below a threshold, the object is stopped. This helps prevent floating point error accumulation over time, and then the object moves like 1 pixel after 5-10 seconds or something. As silly as that may sound, it really did happen, and looks quite odd when it does.

Finally, with a newly determined velocity, the object's position is updated within the game world.


Summary

Game objects that need to trigger and respond to collisions require a physicsBody. The physicsBody contains values that allow physics calculations to take place, including movement for dynamic objects. Motion for dynamic objects is controlled by the physics engine. It basically adds up all the forces: acceleration, gravity, and externally applied ones with its current velocity, scaled by deltaTime (the amount of time since the previous physics iteration) to determine the new velocity. Motion on frozen axes is zeroed out, and if the object is moving slow enough, it is stopped completely.

Its velocity is then used to update the position of the object, and the loop moves on to the next object. Once all of the dynamic objects have been moved, things go to the next phase.


What Next?

After all of the dynamic objects have moved, it is time to check for any and all collisions, and ultimately respond to them. We cover collision detection in Part 2, and collision response in Part 3.


Complex Physics - Stacks

Something that seems simple, a tall stack of boxes resting on each other, is surprisingly complicated for a physics engine. Especially if you drop another box on the top of the stack. We all know in our heads that a stack of boxes should just sit there. When you drop an additional box on top, it should land and the whole stack should just sit there still, with no motion.

What is so hard about that? For starters, each box is colliding with at least one more, and gravity is acting on all of them simultaneously. Each box is trying to move down into the one below it, so it must be pushed back out of collision every frame. Doing so likely pushes it back into collision with the one above it, and so on. You don't want to see the stack vibrating with slight verticle movements as all of those collisions are taking place and getting resolved.

When you drop another box on top, a strong force pushes what was the top box down into the one below it, and it cascades down through the entire stack. But the order of collision resolution isn't magically sorted. What this means is that a box in the middle of the stack may get resolved with virtually no motion, only to eventually receive the strong downward impulse as the shockwave of the newly dropped box works its way through the entire stack.

What is sad is that a stack of boxes is pretty boring to look at. Seeing any of the boxes vibrating is pretty annoying, and makes the game look pretty stupid.


Complex Physics - Tunnelling (Fast Moving Objects)

Any object that is moving fast enough, which in reality means something close to half its size or more in one frame, has the possibilty of completely passing through another object without ever colliding with it. In a game, this could be a bullet or something that is small moving at a high velocity. The solution for this is to treat it more like a laser.

What I mean is that fast moving objects need to cast a ray in front of them, in the direction of their velocity, and see what objects that ray intersects. However, it isn't quite that easy. The other objects can be moving too, including at high velocity.

It comes down to seeing if objects paths would cross in the current frame, which involves distance calculations that are fairly expensive to calculate, so you wouldn't want to test against the paths of all objects against every other object in every frame. So then you get into optimizations, like a broad-phase detection, then move on to a more fine-grained detection. It is all doable, and if I build a game requiring high-speed objects I will have to do something to support them.


Complex Physics - Rotation

In the real world if two objects collide, unless they hit dead-center, with respect to their center of gravity, some amount of rotation would be introduced as a result. Rotation would also occur if their surface normals don't point directly at each other.

Determining the amount of rotation requires more math, and when we are talking about rectangles the surface normals require math to figure out what direction they are pointing in.


Complex Physics - Arbitrary Shapes

GMGE physics is limited to circles and axis-aligned rectangles. As soon as you go beyond that, the physics gets complicated quickly. The two objects below are not colliding, but good luck figuring that out. And if you do figure out how to calculate that, determining the surface normals to resolve the collision is no average task either. Doing it every frame in a fraction of a millisecond becomes a problem as you add more objects into the world.