September 12, 2025
THIS POST IS A WORK IN PROGRESS. Feedback is appreciated!
There's a lot of simulators out there, and with each simulator trying to sell itself for being the best of its kind, deciding which simulator to use is a whole task of its own.
The target audience for this post is people who, like me, are interested in using physics-based simulators for their research or fun projects, but unfamiliar with how the underlying physics engine actually works. After reading this post, you should be able to make a principled decision on which simulator to use, beyond "this seems to be what everyone else in my field uses" and hopefully away from "all my options suck so I'm building my own hahha" and encourage you to make the right tradeoffs for your simulating needs.
Typically your usage of a simulator is something like this:
scene = my_physics_engine.Scene(...)
... # scene setup
for i in range(N):
scene.step(...) # "do physics"
... # get scene info / apply controls / etc.
What's going on in a physics step though?
Given the current state of the scene q
t (this could be your robot joints, object positions, etc.),
the velocities qd
t, and optionally some control input or external action
, we compute the next state of q
t+1 and qd
t+1.
This is generally done in 3 stages: collision-free dynamics, collision detection, then constraint resolution.
def step(q, qd, action):
# 1. Collision-Free Dynamics: apply equations of motion
q_bar, qd_bar = collision_free_dynamics(q, qd, action)
# 2. Collision Detection: get contact points, where the interesting stuff is happening
collision_data = collision_detection(q_bar, qd_bar)
# 3. Constraint Solver: resolve the collisions and get realistic outputs
q, qd = solver(q_bar, qd_bar, collision_data)
In the first step, the engine uses basic Newtonian equations of motion to update all the positions and velocities.
However, when the world is discretized like it is in a computer, the numerical stability of the integration method
can affect the simulation's stability and accuracy. The simplest way to do this is to compute q += qd * dt
, which is
the Euler method. There are some variations on this that try to be more
stable, at the cost of doing slightly more computation.
The most basic way to trade off speed and accuracy is to adjust the simulation timestep dt
or the number of substeps
per frame. Smaller dt
or more substeps means more accurate and stable simulation, but at a higher computational cost.
However, beware: some solvers (especially explicit ones) can actually become less accurate or even unstable if dt
is
too small, due to floating-point errors or solver limitations.
For articulated rigid bodies like robots, the engine also needs to account for joint constraints and kinematics. Robotics-focused engines usually do this calculation in such a way that it is invertible so that you can do motion planning, while many game-focused engines typically use a quicker algorithm that only yields the forward dynamics, which is all you need for your silly ragdoll physics.
Next, the engine needs to find where all the action is happening: the collisions. Since simulations are discretized in time, after updating the positions of all the objects we will often end up with some intersecting each other. Before we resolve these physical implausabilities, we have to detect which objects are intersecting and by how much. The detection is usually split into two phases: broad phase where we quickly rule out pairs that are definitely not colliding, and narrow phase for precisely checking the remaining pairs. Wikipedia has a good overview of this.
Once collisions are detected, the engine needs to resolve them, e.g. preventing objects from interpenetrating, enforcing joint limits, and simulating friction. Mathematically, for rigid body dynamics, this means solving the Linear Complementarity Problem (LCP). To solve this exactly is NP-hard, so most engines relax the conditions and/or use approximate solvers for this, with varying levels of accuracy and speed.
So every physics engine is essentially a packaged assortment of these 3 steps. Usually, you have the option to mix and match different algorithms for each part as well. On top of that, every algorithm has its own parameters to tune, so be mindful that you will get varying levels of speed and accuracy from one simulation platform based on how well you set up your environment as a user.
Aside these core components, there are some additional aspects that are usually baked into the engine. These features tend to be design choices that are closely tied to the core components, so it will be more difficult to simply extend an existing engine to support them. Often, you will find engines dedicated to supporting these features specifically.
A differentiable physics engine outputs smooth gradients with respect to its inputs by backpropagating through dynamics, collisions, and constraint solving. Of course, this will require at least 2x additional computation to compute the backprop, but it is usually worth it when you're doing machine learning or optimization because it allows for much faster training.
Physics engines can be parallelized at different levels. For game-focused engines where fast real-time simulation of single, complex environments is a priority, you may have per-object parallelization. On the other hand, for robot learning scenarios, multi-scene parallelization will probably dominate your training time cost much more than any optimization of a single scene. Additionally, parallelization may be handled on CPU or GPU. To support GPU, the physics engine might use lower level frameworks like Taichi or Warp to abstract kernel code (native GPU code can be painful to write).
Beyond rigid bodies, you may be interested in simulating soft deformable objects and fluids, or even temperature, electromagnetics, etc. Also, you may want your rigid objects to be able to interact with your soft objects and vice versa. Beware that anything soft will generally be much, much slower than rigid body simulation, so doing something like reinforcement learning with soft objects may not be very feasible.
A simulator might claim it can run at millions of steps per second, but that doesn't actually mean anything useful without the context. Is it on a single scene or multiple scenes? How many entities? How many contacts? With how much physical precision? There is simply no one simulator that is going to be beat all the others in all aspects. There are benchmarks, but no benchmark has wide enough coverage to be "fair". In fact, you may also find that the author of a benchmark is a developer of their own simulator, and of course, their simulator is the best in their own benchmark. It's not that the benchmark is wrong, it's simply that the developer optimized for the aspects that they care most about, and they will also test on these aspects that matter most to them. Ideally, the person running the benchmark should fully understand the design choices and tunable parameters for each simulator, otherwise the results may be misleading as it will not be reflective of the actual performance.
This contact physics consistency paper (2016) and differentiable physics simulators review (2024) are better examples of how one should approach comparing different simulators. You consider the kind of physics you care about, and how important the accuracy vs stability vs consistency is for your use case. Maybe one day we can convince aallll of the simulation developers to get in a room and battle it out on a buuunch of different scenarios... but realistically, that probably won't happen anytime soon.
Instead, as a simulation user, you should consider the intentions of the engine developers. Depending on the main use case, "speed" and performance will be optimized along different axes.
What I'm going to call a simulator is the platform/infrastructure built on top of the physics engine, kind of like all the frosting and toppings on a cake.
If there's a feature you're looking for, there's definitely a simulator out there that prides itself on it! However, it's going to be hard to find a simulator that has all the things, and there are the practical aspects to consider as well.
Unfortunately, there's a lot of for-research codebases that are no longer maintained. As a general rule of thumb, I would generally avoid codebases whose README is a paper abstract or hasn't had commits in the last year or so.
As an informed user, you're ready to shop for your simulator! Here's a table of some physics engines (core physics providers) and simulation platforms (contains additional features/ecosystem on top of a physics engine).
This is by no means an exhaustive list, and may contain some errors. Please let me know if you find any missing or incorrect information.
Or um, Ingredient List if we're still going with the cake analogy.
Acronym | Name | Description | |
---|---|---|---|
Dynamics: Integration Method |
EE | Explicit Euler | First-order integration updating positions using current velocities; fast but less stable. |
SE | Semi-implicit Euler | Updates velocity before position; almost as fast as Explicit Euler but more stable and roughly conserves energy. | |
IE | Implicit Euler | Uses derivative of next step; unconditionally stable but requires solving implicit equations. | |
RK | Runge-Kutta | Higher-order integration using intermediate evaluations; good convergence properties, slower per step but can use larger time steps. | |
Dynamics: Articulation |
CRBA | Composite Rigid Body Algorithm | Bottom-up computation of joint-space inertia; efficient for calculating dynamics terms but not accelerations directly. |
ABA | Articulated Body Algorithm | Two-pass forward dynamics algorithm; very fast for accelerations but does not directly give inertia matrices. | |
Collision Detection | - | Point | Return points of contact. |
- | Convex | Return points of deepest penetration for each pair of convex shapes in contact. | |
- | Hydroelastic | Models contact as pressure field. | |
Collision Detection: Broad Phase |
SP | Spatial Partitioning | Divides space into uniform cells; efficient for uniformly distributed objects but can degrade with clustering. |
BVH | Bounding Volume Hierarchy | Sparse tree structure; efficient for scenes with variable densities. | |
Collision Detection: Narrow Phase |
GJK | Gilbert–Johnson–Keerthi | Fast convex distance test; standard narrow phase, often paired with EPA when intersecting. |
EPA | Expanding Polytope Algorithm | Extends GJK to compute penetration depth and contact normal. | |
Constraint Solver: Constraint Problem |
LCP | Linear Complementarity Problem | Exact formulation of contact and constraints; accurate but expensive to solve at scale. |
SCM | Soft Contact Model | MuJoCo's soft contact model, which is LCP with the non-penetration constraint removed. | |
Constraint Solver: Rigid-body Solver |
PGS | Projected Gauss-Seidel | Iterative approximation of LCP; simple and fast but may converge slowly or give artifacts. |
QP | Quadratic Programming | Solves LCP using optimization; handles friction well, uses more compute. | |
SI | Sequential Impulse | Iteratively accumulates impulses on contacts; efficient and widely used in games but only approximate. | |
CG | Conjugate Gradient | First-order; cheaper per iteration than Newton but needs preconditioning and more iterations. | |
Newton | Newton's Method | Second-order with fast convergence; more stable/accurate than PGS/CG but heavier per step. | |
Soft-body or Fluid Solver | FEM | Finite Element Method | Numerical method dividing soft bodies into elements to simulate deformation and stresses accurately; very compute-intensive. |
VBD | Vertical Block Descent | Solves elastic deformations via block volume constraints; efficient but less general than FEM. | |
PBD | Position Based Dynamics | Iteratively enforces positional constraints; very stable and fast but not physically accurate; can be used to visualize cloth. | |
XPBD | Extended Position Based Dynamics | Adds compliance to PBD constraints; retains stability while improving realism. | |
SF | Stable Fluid | Grid-based incompressible flow method; unconditionally stable but diffusive compared to true Navier-Stokes. | |
MPM | Material Point Method | Particle–grid hybrid for solids and fluids; versatile and accurate but memory and compute heavy. | |
SPH | Smoothed Particle Hydrodynamics | Purely particle-based fluids/soft bodies; simple to implement but less stable and less precise. | |
IPC | Incremental Potential Contact | Robust energy-based contact solver for deformables; guarantees non-penetration but costly per step. |
Cake Recipes.
ODE | Bullet | PhysX | MuJoCo | Drake | RaiSim | Brax | Jolt | Newton | Genesis | |
---|---|---|---|---|---|---|---|---|---|---|
Integration Method | EE | SE | SE | IE, SE, RK4 | Adaptive RK | SE | SE | SE | SE | IE, SE |
Articulation | CRBA | ABA | ABA | CRBA | ABA | ABA | CRBA | ABA | CRBA | CRBA |
Collision Detection | Primitives | Convex, Point | Convex, Point | Convex, Point | Hydroelastic | Convex, Point | Point | Convex, Point | Convex, Point | Hydroelastic, Convex, Point |
Constraint Problem | LCP | LCP | LCP | SCM | LCP | (Closed source) | LCP | LCP | LCP | SCM |
Rigid-body Solver | PGS | SI, PGS | SI (Docs) | QP, PGS | QP | (Closed source) | SI, PBD | SI | QP, PGS | QP |
Soft-body or Fluid Solver | None | PBD | FEM, PBD | None | FEM | None | None | None | MPM, VBD, XPBD | FEM, IPC, MPM, PBD, SF, SPH |
Parallelization | None | Single-scene CPU | Single-scene CPU, GPU | CPU, GPU using MJX, MJWarp | No | No | GPU using MJX | No | Multi-scene GPU using MJWarp | Multi-scene GPU using Taichi. (Benchmark) |
Differentiable | No | No | No | No | No | No | Yes | No | Yes | Yes |
Developer | One guy (Russ Smith) | One guy (Erwin Coumans) | NVIDIA | Roboti LLC, acquired by Google DeepMind | MIT, funded by Toyota | For-profit spinoff from ETH Zurich | One guy (Jorrit Rouwe) | NVIDIA | Genesis AI | |
Release Year | 2001 | 2006 | 2008 | 2012 | 2014 | 2018 | 2021 | 2022 | 2025 | 2025 |
Decorated Cakes.
Isaac Sim | MuJoCo Playground | Genesis | ManiSkill | Drake | Gazebo | Webots | Unity | Unreal | Godot | |
---|---|---|---|---|---|---|---|---|---|---|
Target Use Case | Robot Learning |
Robot Learning | Robot Learning | Robot Learning | Robotics | Robotics | Robotics | Game Dev | Game Dev | Game Dev |
Physics Engine | PhysX, Newton | MuJoCo | Genesis | PhysX | Drake | Bullet, ODE | ODE | PhysX | Chaos | Jolt |
Language | C++, Python | Python | Python | Python | C++, Python | C++, Python | C++, Python, Java, MATLAB | C# | C++ | GDScript |
Graphics | Rasterizer, Raytracer | Batched Rasterizer & Raytracer | Batched Rasterizer & Raytracer | Rasterizer | Rasterizer | Rasterizer | Rasterizer | Rasterizer, Real-time Raytracer | Rasterizer, Real-time Raytracer | Rasterizer |
Release Year | 2022 | 2024 | 2025 | 2022 | 2014 | 2012 | 1998 | 2005 | 1998 | 2014 |
Last updated: 2025 September 13.
If you want to learn more about the math behind the physics, this online textbook is a great resource. Also, PhysX and MuJoCo provide a nice detailed breakdown of their choice of algorithms. Finally, if you are looking for more specific simulators, here is a larger list of simulators, maintained by Kimberly McGuire.
Cover image credit: Placid Plastic Duck Simulator