September 17, 2025
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. Please note that the focus of this post is on rigid-body and optionally soft physics simulation, not, per say, for modeling biological systems or interacting in text-based environments. 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 qt (this could be your robot joints, object positions, etc.),
the velocities qdt, and optionally some control input or external action, we compute the next state of qt+1 and qdt+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.
As a user, it is very important that you consider the mesh or collision geometry that you are using as the input to the physics engine. Collision detection on simple convex meshes will always be fast and more stable than on non-convex meshes. Many engines recommend to apply convex decomposition on your mesh to get the best performance. Some simulation platforms may even do this automatically for you. It is sometimes the case that problems such as slippage are caused by poorly configured geometry, and not necessarily an issue with the engine physics.
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 bodies, 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. There are several different ways to represent and simulate soft objects, but generally anything soft will be much, much slower than rigid body simulation. Remember, supporting soft objects means implementing the dynamics, collision, and constraint solving steps specific to the soft body representation/algorithm.
A performance/speed number means nothing without the full context. Is it on a single scene or multiple scenes? How many entities? How many contacts? With how much physical precision? Just as every engine is an opinion piece which makes trade-offs for the aspects that it cares most about, every benchmark or comparison paper will only cover a subset of use cases. Ideally, the person running 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. Especially with increasing amounts of money on the line in robotics research and industry, the position/background of the authors should be carefully considered. You may find that the author of a benchmark is a developer of their own simulator, in which the developer optimized for the aspects that they care most about, and will know how to tune the parameters of their own simulator to get the best performance, but only use defaults for other simulators.
As a simulation user, you should consider the required levels of accuracy vs stability vs consistency for your use case. When looking at simulators, also consider the intentions of the engine developers. Depending on the main use case, "speed" and performance will be optimized along different axes. 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. As a general rule of thumb:
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.
By the way, the tables are horizontally scrollable (shift + scroll wheel if you're on desktop + mouse).
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: Mesh Preprocessing |
VHACD | Voxelized Hierarchical Approximate Convex Decomposition | Decomposes mesh into near convex parts. |
| CoACD | Collision-Aware Convex Decomposition | Better performance and detail preservation than VHACD. | |
| Collision Detection: Collision Model |
- | Point | Return points of 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. | |
| SAP | Sweep and Prune | Efficient for dynamic scenes with variable densities. | |
| Collision Detection: Narrow Phase |
- | Primitives | Use primitive geometries (sphere, box, etc.) for finding intersections. Fastest. |
| GJK | Gilbert–Johnson–Keerthi | For convex objects; fast distance test. | |
| EPA | Expanding Polytope Algorithm | Extends GJK to compute penetration depth and contact normal. | |
| MPR | Minkowski Portal Refinement | Alternative to GJK; similar performance, but does not give separation distance and susceptible to numerical errors. | |
| SDF | Signed Distance Fields | Uses precomputable functions instead of mesh to represent the geometry, can be much faster. | |
| Constraint Solver: Constraint Problem |
LCP | Linear Complementarity Problem | Exact formulation of contact and constraints; accurate but expensive to solve at scale. |
| CCP | Cone Complementarity Problem | LCP with relaxed complementarity constraint, which makes it a convex optimization problem. | |
| Soft | Soft Contact Model | MuJoCo's soft contact model, which is CCP with the non-penetration constraint removed. | |
| SI | Sequential Impulse | Iteratively accumulates impulses on contacts; efficient and widely used in games but only approximate. | |
| SAP | Semi-Analytic Primal | Uses linear model of compliant contact forces, faster for complex scenes, has guaranteed global convergence. | |
| Constraint Solver: Optimizer |
PGS | Projected Gauss-Seidel | Iterative approximation of LCP; simple and fast but may converge slowly or give artifacts. |
| 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 Dynamics/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. | |
| IPC | Incremental Potential Contact | Robust energy-based contact solver for deformables; guarantees non-penetration but costly per step. | |
| MPM | Material Point Method | Particle–grid hybrid for solids and fluids; versatile and accurate but memory and compute heavy. | |
| 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. | |
| SPH | Smoothed Particle Hydrodynamics | Purely particle-based fluids/soft bodies; simple to implement but less stable and less precise. |
Cake Recipes.
| ODE | Bullet | PhysX | MuJoCo | Drake | RaiSim | Brax | Jolt | Newton | Genesis | |
|---|---|---|---|---|---|---|---|---|---|---|
| Integration Method | EE | SE | SE | EE, IE, SE, RK4 | Adaptive RK | SE | SE | SE | SE | IE, SE |
| Articulation | CRBA | ABA | ABA | CRBA | ABA | ABA | CRBA | ABA | CRBA | CRBA |
| Collision Detection | Point | Point | Point | Point | Hydroelastic | Point | Point | Point | Point | Hydroelastic, Point |
| Constraint Problem | LCP | LCP, SI | SI (Docs) | Soft | CCP, SAP | (Closed source) | SI, Soft | SI | CCP, Soft | CCP, Soft |
| Rigid-body Solver | PGS | PGS | PGS | Newton, CG, PGS | Newton | (Closed source) | PBD | PGS | Newton, CG, PGS | Newton, CG, PGS |
| Soft-body or Fluid Dynamics/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 gstaichi. |
| 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: September 2025. I will try to connect these tables to a GitHub repo later.
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. This contact models comparison paper (Le Ledic et al. 2024) and differentiable physics simulators review (Newbury et al. 2024) provide more in-depth analyses across simulators for their respective topics. Finally, if you are looking for more specific simulators, here is a larger, better-maintained list of simulators.
This post may contain errors. Feedback and corrections are much appreciated.
Thanks Yiling for the simulation workshop I based this on and for the helpful feedback! 
Cover image credit: Placid Plastic Duck Simulator
