2D Rigid Body Collision Resolution
sassnow.ski
sassnow.ski
To give some context, this is only part one in a series of blog posts I plan on writing about rigid body physics.
The post is aimed at people like myself, who aren't game devs and don't necessarily have a strong math background. Which is why I spend so much time explaining concepts that would appear almost trivial to someone who has experience in this area.
Happy to answer any questions you might have.
Pardon my curiosity, but what tools did you use to build that page ?
Most of the physics-based example are written in WebGL using three.js. Using three.js is a little bit overkill for this because all the examples are in 2D but it's what I was familiar with. For the actual physics simulations, I'm using matter.js.
The diagrams use a library I wrote while working on the post [1].
Everything runs inside a Vue app which serves as the glue between things like the sliders and the three.js scenes and diagrams.
Would really appreciate the inclusion of an RSS feed so I can continue to follow along!
Are you planning to read/explain through XPBD (Extended Position Based Dynamics - http://mmacklin.com/xpbd.pdf) as well in future posts? The concept seems to be gaining traction and I've used it with Bevy (via https://github.com/Jondolf/bevy_xpbd) with big success so far, seems more stable than the usual approach.
Game development beginners often have the wrong impression that they need rigid body collision calculations or a 2D physics engine like Box2D to handle collisions. That's true if you want to make a game like Pool or something with collapsing stacks of crates like Angry Birds.
But for a 2D platformer you only need to detect collisions by comparing (axis-aligned) rectangles and to handle collisions by changing the moving character's X and Y coordinates (to undo an overlap) or setting the character's Y velocity (after using the jump button, or after landing on a Goomba's head).
This also makes it easier for the developer to finetune exactly how moving the character should feel like. (This includes inertia, but this inertia is usually not physically realistic.) Trying to use realistic physics as a gamedev beginner can easily lead to floaty and unsatisfying movement.
An example tutorial to start with this simple physics-free approach: https://www.love2d.org/wiki/Tutorial:Baseline_2D_Platformer
If I may ask a question, in your mind what’s the benefit of more deeply understanding these implementations when physics frameworks handle a lot of the really mathy logic behind collisions and simulations.
Either way I’m putting this in my read queue. Thanks!
Honestly, when I initially read the domain name and noticed the TLD is ".ski" I was thinking it is from the author who wrote about Mecanical Watch [1] and other cool stuff.. it turned out to be a totally different one but of similar quality. What's the secret sauce behind this ".ski" TLD :)
___________________
Author of https://ciechanow.ski – the site we all love here – is Polish programmer working for Apple.
As part of the project I was thinking we will skip game engine altogether because I wanted to teach my son a bit more about how to structure the application, etc. I thought in future we would use a ready game engine but at least once we would go through the exercise of implementing everything.
Everything was fine until we approached the problem of collision detection and handling. That's when things went downhill pretty quickly. Even with my theoretical math background I was soon consumed with just enormous amount of corner cases and finally decided to relent and use Box2d for this.
I am not a professional game developer, but I have over 20 years of development experience + math background and I still made the mistake of underestimating the problem. It really seems easy problem when you state it and just becomes exponentially more and more complex as you start digging into details.
[1]https://m.youtube.com/watch?v=lS_qeBy3aQI&pp=ygUSVmVybGV0IGl...
[2]https://m.youtube.com/watch?v=3HjO_RGIjCU&pp=ygUSdmVybGV0IGl...
https://kidscancode.org/blog/2016/08/pygame_shmup_part_3/
But if your space debris objects are supposed to collide and agglomerate realistically, and if the player ships are supposed to have difficulty pushing a cluster of heavy objects out of the way, then using a physics library is sensible.
The point is you fly in a small spaceship in an arena, you hide behind obstacles, you shoot with a small variety of weapons and you use your weapons to either shoot the enemy directly or rearrange the map to make life difficult for your them. The collisions need to be realistic because you need to be able to predict what is going to happen when you hit things a certain way.
It is just a concept we are playing with.
Another part of that concept is that this game is meant for small kids that can't read. There is not a single letter or digit in the entire game. No menu. You just start the controller and get immediately pulled into the game.
And another feature is we wanted the game fun because the control feel fun and immediate. So we are experimenting a lot with what it means for the controls to be enjoyable.
They are quite optimized and performant libaries already and there are tons of tutorials for box2d out there (thanks to iforce).
You just add some shapes of your liking and call world.step
Back when flash was everywhere.
Code: https://github.com/vandrieu/canvas-bouncing-ball (the collision logic is in src/collision.ts)
Result/Demo: https://vandrieu.github.io/canvas-bouncing-ball/
If so, could you add a license?
EDIT: If I'm incorrect, please explain how. I've written some game physics systems and seen some proper physics sim systems and these comments reflect my understanding of the situation, and if I've said something wrong, please correct me instead of just downvoting.
It's true that some commercial solvers like Ansys use spring/penalty methods, but this is due to the spring forces being easier to couple to other solvers. It's harder in the Ansys force/velocity formulation to combine things like elasticity and fluids to their rigid body solver. To deal with the instability of systems of many stiff springs they have to take many small timesteps to avoid convergence issues.
More recently techniques like XPBD have been gaining popularity, particularly in film, which use purely positional constraints and variational methods to combine many different types of physics simulations. There's a really great and approachable series of videos by Matthias Muller on youtube which goes through how to implement all this in JS https://matthias-research.github.io/pages/
Finally it's funny you should mention games, since many older games used spring methods for physics. It was only when constraint based solvers became popular after Havok/Half-Life 2 did we start to see games with real rigid body dynamics and stable stacking of boxes. Older physics games like Trespasser ( https://en.wikipedia.org/wiki/Trespasser_(video_game) ) had many bugs due to the use of hacky spring physics. For a good explanation of how games do it today look at Erin Catto's work on Box2D https://box2d.org/publications/
This is a specific reference on how constraints model contact between rigid bodies https://box2d.org/files/ErinCatto_UnderstandingConstraints_G...
Most games since Half Life 2 use constraint forces like this to solve collisions. Springs/penalty forces are still used sometimes in commercial physics solvers since they're easier to couple with other simulations, but they require many small timesteps to ensure convergence.
Making a stable engine where objects don't compress into one another or jitter is a rabbit hole without a bottom that even the most math-heavy articles I could find rarely touched.
I used a series of old articles by Christ Hecker to understand the maths myself. http://www.chrishecker.com/Rigid_Body_Dynamics
Like those old atari games where everything was little square tiles / pixels.
But little squares aren't the most expressive geometry.
How about kisrhombille?
Besides that... Beautiful page, well done!
The gnarly stuff comes in when you're trying to figure out contact points and impulse responses and apply them without blowing everything up. I've written some of this stuff for a few games now, and the resources below have stood the test of time IMO
[0] https://dyn4j.org/2010/01/sat/ [1] https://realtimecollisiondetection.net/pubs/SIGGRAPH04_Erics... [2] https://allenchou.net/2013/12/game-physics-broadphase/
And on top of that there is more to collision detection than just code IMO - setting up hitboxes that both feel right for the player and aren't visually glitchy is not as straightforward as it might seem, especially with 3D.
(Also, figuring out contact points is part of competently implemented collision detection.)
Couldn't be happier seeing more people going to same depths (or heights) to explain things to people. Will be looking forward to more articles like this as this just the very first one.