| Name | Modified | Size | Downloads / Week |
|---|---|---|---|
| Parent folder | |||
| mujoco-4.0.0-macos-universal2.dmg.sha256 | 2026-11-06 | 100 Bytes | |
| mujoco-4.0.0-macos-universal2.dmg | 2026-11-06 | 68.2 MB | |
| mujoco-4.0.0-windows-x86_64.zip.sha256 | 2026-11-06 | 98 Bytes | |
| mujoco-4.0.0-windows-x86_64.zip | 2026-11-06 | 31.0 MB | |
| mujoco-4.0.0-linux-aarch64.tar.gz.sha256 | 2026-11-06 | 100 Bytes | |
| mujoco-4.0.0-linux-aarch64.tar.gz | 2026-11-06 | 51.1 MB | |
| mujoco-4.0.0-linux-x86_64.tar.gz.sha256 | 2026-11-06 | 99 Bytes | |
| mujoco-4.0.0-linux-x86_64.tar.gz | 2026-11-06 | 52.5 MB | |
| 4.0.0 source code.tar.gz | 2026-11-06 | 77.7 MB | |
| 4.0.0 source code.zip | 2026-11-06 | 79.0 MB | |
| README.md | 2026-11-06 | 47.0 kB | |
| Totals: 11 Items | 359.5 MB | 29 | |
Version 4.0.0 (November 6, 2026)
Significant new features
89daf8d19Added the speculative enable flag for speculative contacts to prevent fast-moving convex geoms from tunneling through thin obstacles within a single timestep. On the right, one step of conservative advancement between two rotating boxes. See model/speculative/ for examples.
-
Added elasto-plasticity, with stateful plastic deformation stored in
mjData.plastic(mjSTATE_PLASTIC): -
e140c026fIdeal elasto-plasticity for joint (springyield) and tendon (spatial, fixed) springs (left). -
0c0f63b3f,c39fe6f02,e3bd72742,7cb32488bContinuum elasto-plasticity (yield) for 2D and 3D flexes, with separate stretching and bending yield strains for 2D shells, volumetric-deviatoric (von Mises $J_2$) stretching and 2D shell bending return mapping (right). -
See model/plastic/ for examples.
abaf8d518Split the Python distribution intomujoco-core(minimal bindings and C library depending only onnumpy),mujoco-studio(Studio and Filament renderer bindings), andmujoco(default package installing both). When upgrading from a pre-splitmujocoinstallation withpip, uninstall first (pip uninstall -y mujoco && pip install mujoco) or runpip install --force-reinstall --no-deps mujoco mujoco-core mujoco-studioafter upgrading sopipdoes not remove files moved tomujoco-core. To switch an existingmujocoinstallation to core-only, runpip uninstall -y mujoco mujoco-studio && pip install --force-reinstall --no-deps mujoco-core.
[!NOTE] Updated documentation for the split Python packages (
mujoco,mujoco-core,mujoco-studio) and prebuilt OpenUSD wheels (mujoco-usd/mujoco[usd]) landed shortly after the4.0.0release (39ddbb61a). Please refer to thelatestdocs for Python bindings and OpenUSD rather thanstableor4.0.0.
Engine
[!WARNING] Breaking changes
a65050166Changed the semantics of sidesite: the tendon now goes around the geom the same way as the path from the first endpoint, through the side site, to the second endpoint (thin grey line below). Formally, the tendon is the shortest path homotopic to this polyline in the wrapping plane with the geom removed.<picture>
</picture>
Previously, a half-plane test was used, which could make the tendon jump onto the geom, a discontinuity in tendon length, when the segment between the endpoints moved away from the side site while clear of the geom. It could also select the wrong side for wraps longer than 180 degrees. Top row: old rule; bottom row: new rule.
<picture>
</picture>
The new rule has a single discontinuity: when an endpoint crosses the ray opposite the side site, the path through the side site changes its winding around the geom and the tendon snaps off. This can change the behavior of existing models.
Migration: Place side sites so that the endpoints do not cross this ray over the range of motion, typically near the middle of the wrapped arc. For example, the side sites of the two-link arm were moved from directly below the joints to 45 degrees below the arm, which reproduces the previous tendon lengths exactly.
-
9a7f240f0TheRK4integrator is now fourth-order accurate for the orientations of ball and free joints. Previously, the angular velocities of the Runge-Kutta stages were combined without the Runge-Kutta-Munthe-Kaas correction, so orientations converged only at second order. This changes the simulation of models with ball or free joints that useRK4. -
9916cc5f7Addedsurfacevel[3]tomjContact, storing the relative surface velocity (geom[1]minusgeom[0]) in the contact frame(tangent1, tangent2, spin). Collision detection populates it fromgeom_surfacevelwhenmjModel.flg_surfacevelis set, and external contact generators can write it directly (settingflg_surfacevel = 1if no geom specifiessurfacevel). Contact-point visualization now draws a single relative tangential velocity arrow per active frictional contact. -
629feb74bAddedxiquat,geom_xquat, andsite_xquattomjData, storing the Cartesian quaternion orientations of body inertias, geoms, and sites alongsideximat,geom_xmat, andsite_xmat. -
64af6504fAddedmjModel.tendon_typewith values from the newmjtTendonenum, distinguishing fixed and spatial tendons. Previously, the type was implied by whether the first path element was a joint.
Deformables
[!WARNING] Breaking changes
1d6cc8ff5Removed thecableplugin (plugin/elasticity) and thecompositeelement, which are superseded by 1D flexcomp with elasticity.Migration:
countandcurve/size/vertex: use flexcompdim="1"withtype="grid",count, andspacing(ortype="circle"for closed loops), ortype="direct"withpoint. Add<edge equality="true"/>to keep edges inextensible.Geom
size(capsule radius): set flexcompradius. For geomtype="box", set<elasticity section="box" sectionsize="..."/>.Plugin
bendandtwist: set<elasticity young="..." shear="..."/>.Root attachment
initial:initial="none"maps to<pin id="0 1"/>(clamps the first edge's material frame to the parent body and omits<name>_twist_0);initial="ball"maps to<pin id="0"/>(spherical anchor at the first vertex, keeping<name>_twist_0free);initial="free"maps to no<pin/>.Plugin
flat="true": define the rod straight inqpos0(e.g.,type="grid") and set the curved initial pose viaqposor a keyframe (curves defined directly inpointare at rest inqpos0, corresponding toflat="false").Plugin
vmaxstress coloring: not supported.Integrator: use
integrator="discrete"for implicit integration (orEuler/RK4;implicitandimplicitfastare not supported for 1D rod elasticity).Body names
B_first/B_<i>/B_last: unpinned vertices create bodies<name>_<i>(pinned vertices attach directly to the parent body), plus per-edge twist bodies and joints (see the next entry).
95cf15e58Open elastic 1D flexcomps with at least two elements now create per-edge twist bodies with hinge joints<name>_twist_0, ...,<name>_twistunder the world body (omitting the joint of an edge clamped by pinning both of its points:<name>_twist_0for<pin id="0 1"/>, and<name>_twistfor the last two points of a rod with at least three elements), and store their time-parallel reference frames and reference twists inmjData.plastic. This changesnq,nv,nbody,nplasticand theqposlayout of such models, shifts the indices of bodies and joints declared after the flexcomp, and changes the simulation: rods now roll on surfaces and twist in grippers. Box sections (sectionbox) require these joints, so raw flexes with box sections now need them too, and their collisionradiusis set to the minor half-size of the section (an explicitradiusthat differs from it is now a compile error).Migration: Update keyframes and any code that indexes
qpos,qvelor bodies by number, preferably addressing vertex bodies (<name>_<i>) and twist joints by name. Save and restore rod state withmjSTATE_PLASTIC. Raw box-section flexes need hinge joints named as above (see elasticity).
7ba52b533Fixed the elastic constants of non-interpolated flexes (full and radial dofs), which now match young, poisson and thickness as documented, and the interpolated flexes:
3D Saint Venant-Kirchhoff stretching used twice the first Lamé parameter $\lambda$.
2D stretching used a quarter of the shear modulus $\mu$ and half of the 3D $\lambda$, instead of $\mu$ and the plane-stress $\lambda^* = E \nu / (1 - \nu^2)$.
2D bending used $\tfrac{3}{4}(1-\nu) D$ instead of the plate bending rigidity $D = E t^3 / (12 (1 - \nu^2))$.
Models with these flexes become stiffer, except 3D models with zero Poisson's ratio, which are unchanged.
Migration: To keep the previous behavior, use these parameters:
3D: $\nu' = 2\nu / (1 + 2\nu)$ and $E' = E (1 + \nu') / (1 + \nu)$.
2D bending only (
elastic2d="bend"): $E' = \tfrac{3}{4}(1 - \nu) E$.2D stretching (
elastic2d="stretch"or"both"): $\nu' = 2\nu$, which is exact for $\nu < 1/4$ (so that $\nu' < 1/2$). Then:
"stretch": $E' = E (1 + 2\nu) / (4 (1 + \nu))$.
"both": $t' = t \sqrt{3 (1 - 2\nu)}$ and $E' = E t (1 + 2\nu) / (4 (1 + \nu) t')$.The flex models in
model/flexwere remapped in this way, so their behavior is unchanged.
c0e6b15fd1D rod bending elasticity (dim="1"with positiveyoung) is no longer supported underimplicitandimplicitfast, matching 2D and 3D flex elasticity.Migration: Use
integrator="discrete"for implicit integration, orintegrator="Euler"with a small timestep for explicit integration.
c0e6b15fdFlex edge stiffness and damping are no longer supported underintegrator="discrete"(where they were integrated explicitly rather than in the effective metric).Migration: Use elasticity (or edge equality), or use
Euler/RK4/implicitfast.
b2577a630Unpinned flexcomp models (with full, trilinear, or quadratic dofs) now fail to compile if their parent or ancestor body has joints when no active vertices or nodes are pinned to it.Migration: Remove joints from the parent/ancestor body of an unpinned flex, or pin at least one vertex/node to the parent body with pin.
145cdc2beRemovedflexvertequality constraints (<equality><flexvert>and<edge equality="vert"/>in flexcomp), along with the associatedmjModelfields (nJfv,flex_vertedgeadr,flex_vertedgenum,flex_vertedge,flex_vertmetric,flexvert_J_rownnz,flexvert_J_rowadr,flexvert_J_colind) andmjDatafields (flexvert_length,flexvert_J).mjEQ_FLEXVERTis retained as an unsupported placeholder inmjtEqand causes an error if used.Migration: Use continuum elasticity with
integrator="discrete"or edge equality for 2D cloth models.
6f28d4adfFlexes now support per-element visual materials:mjModel.flex_matidis now(nflexelem x 1)instead of(nflex x 1), and thematerialattribute on flex and flexcomp (mjsFlex.material) is nowmjStringVecrather thanmjString(accepting either a single material name broadcast to all elements or one material name per element).Migration: Index
mjModel.flex_matidby elementm->flex_elemadr[f] + erather than by flexf. In C, setmjsFlex.materialwithmjs_setStringVec(ormjs_appendString) instead ofmjs_setString; in Python, assign a list of material names (e.g.flex.material = ['mat']).
7ba5d6732Records of 1D flexes inmjModel.flex_bendinggrow from 4 to 10 values, to store curved reference configurations and pairs of adjacent bent vertices. Previously, each record was[v_prev, v, v_next, k].Migration: Read 1D records with stride 10. A record whose fourth value is negative is a single hinge
[v0, v1, v2, -1, k1, k2 - k1, |kb0|, jnt, kt, b]: principal bending stiffnessesk1 <= k2, the twist hinge jointjntof the edge(v1, v2)(-1 if none; the joint of the first edge, when present, is that of the first record minus one), torsional stiffnesskt, and the signed minor half-sizebof a box section (0 for circular sections). Otherwise it is a hinge pair[v0, v1, v2, v3, w0, w1, om0[4]].
-
8892bf44b,0d8a109de,f9a589361SparseNewton(solver) is 1.4-3x faster on flex models, using fill-reducing DOF ordering, incremental active-set Hessian updates, direct elliptic cone folding, and pre-ordered sparse Cholesky for the 2Ddiscreteintegrator smooth solve. Most flex models inmodel/flexnow usesolver="Newton", and the experimental ipc flag now supportssolver="Newton"in addition tosolver="CG". -
57d9b960fsolver="Newton"with thediscreteintegrator now supports flex vertices and nodes (both standard and interpolated) attached to articulated bodies. Previously, such models requiredsolver="CG". Themodel/flex/gripper_trilinear.xmlgripper now usessolver="Newton". MuJoCo Warp still requiressolver="CG"for such models. -
7ba5d67321D rod bending elasticity now supports curved reference configurations and torsional stiffness: vertices bent by more than $10^{-4}$ rad inqpos0keep their reference curvature and dihedral twist angle, so that rods such as rings, arcs, and coil springs are at rest in their compiled shape. Previously, such models failed to compile. The new shear attribute optionally overrides the shear modulus used for torsion. Open rods carry per-edge twist joints (see the breaking change above) with per-edge polar inertia, frame-indifferent relative Rayleigh torsional damping, time-parallel reference frames, and frictional contact lever-arm coupling. Box sections additionally use anisotropic principal stiffnesses with equalized damping ratio ($\sqrt{k_1 k_2}$ on the weak axis) and an oriented box in the DER material frame for rendering and collision detection. See the documentation. -
9ca6b7171Volumetric interpolated flexes (trilinear or quadratic dofs withelastic2d="none") now integrate cell stiffness and lump nodal masses over the mesh volume using Finite Cell Method (FCM) subcell quadrature instead of treating every non-empty grid cell as a full cube. This changes the stiffness and nodal mass distribution of volumetric interpolated flexes whose mesh does not fill its bounding box, as well as the nodal mass distribution of multi-cell trilinear flexes. -
f9f3ee653Contacts with flex elements now distribute the contact to the element vertices with the barycentric coordinates of the point on the element closest to the contact. Previously the vertex weights were inversely proportional to the distances from the contact, which do not interpolate the contact point: the contact Jacobian measured the velocity of a different material point, and the contact force exerted a spurious torque on the element. This changes the simulation of models with flex contacts. -
115907e6dInterpolated flexes (trilinear or quadratic dofs) now support passive contact. -
51572eab0Flex edge damping is now integrated explicitly underimplicitandimplicitfast(previously it also damped rigid translation). -
9fb4eca48Fixed contact Jacobians of quadratic flexes, which dropped nodes with negative basis weights. -
b16e09838Sphere and capsule contacts with 3D flex elements are now computed analytically instead of the general convex pipeline. -
3bbf510d4Improved numerical stability of nativeccd convex collision detection and multiccd contact generation. This can slightly change contacts for models with convex or mesh collisions.
Compiler
[!WARNING] Breaking changes
00057bcefModels that include the same file through different paths, which previously loaded, are now rejected withalready included.Migration: Remove redundant
<include>elements referencing the same file.The compiler now rejects the following invalid models, which previously loaded:
b6192732bHeight fields with nrow or ncol less than 2.
a4c699040Fixed tendons referencingball/freeor duplicate joints, or with negative armature.
a4c699040Spatial tendon pulleys with non-positive divisor.
a4c699040camprojection or camera-attached rangefinder sensors referencing an invalid camera or a camera with non-positive resolution.
881e53e2emjs_makeMeshmjMESH_BUILTIN_CONEcalls with fewer than 3 edges orradiusoutside[0, 1].Migration: Ensure height fields have
nrow >= 2andncol >= 2, fixed tendons wrap distinctslideorhingejoints with non-negative armature, pulley divisors are positive, cameras referenced bycamprojectionorrangefindersensors have positive resolution, skin face indices are in[0, nvert), and cone meshes have at least 3 edges and a radius in[0, 1].
-
432376a59fullinertia and inertias inferred from geoms which are not positive definite are now bounded by boundinertia when it is positive. Previously they gave a compile error. -
a4c699040mj_encodenow supports binary MJB output formjSpecvia themodel/vnd.mujoco.mjbcontent type.
Rendering
-
1edd2c67dAdded a castshadow attribute to geom (mjsGeom.castshadow,mjModel.geom_castshadow,mjvGeom.castshadow; defaulttrue) to disable shadow casting per geom in both the classic OpenGL and Filament renderers, andmjrf_setRenderableCastShadow(mjrf.Renderable.set_cast_shadowin Python) to toggle shadow casting of Filament renderables dynamically. -
c831b97d6Added horizon haze and skybox visibility support to Filament rendering: infinite planes are centered beneath the camera and blend smoothly into the skybox horizon according to visual/map/haze and visual/rgba/haze, toggled per view viahazeandskyboxonmjrfRenderRequest(mjRND_HAZE and mjRND_SKYBOX). -
939bc882eWhen no light specifies an intensity, the fallback intensity given to each light in Filament rendering is now scaled by the brightness of its diffuse color, which is factored out of the light's color. Lights look the same, but the brightest directional light now casts the shadows, rather than an arbitrary one that could differ between runs. -
0fc0b44d6Added filament.material.base_color_type flag for configuring how the base color material parameter is interpreted. -
e19117325Addedmjrf_flush(mjrf.Context.flushin Python) to flush pending operations to the rendering backend and invoke any completed callbacks. -
93033f5baAdded mjRND_POST_PROCESSING rendering flag. -
e66b53380Allow headlight.active (mujoco.readthedocs.io) to be set to "false", "true", or "auto" while continuing to support integer values (0=false, 1=true, 2=auto). Change the default to "auto" instead of "true".
Python bindings
-
68390c316Removed support for Python 3.10, now that it's deprecated upstream. -
a1b9fce44Bundled the MuJoCo Sphinx manual (doc/**/*.rst) and agent skills (doc/skills/**/*.md) inside themujocopackage undermujoco/doc/.
Samples
[!WARNING] Breaking changes
006586d30Removedsample/record.cc; multi-frame raw RGB24 video recording is now supported by sample/render.cc (mujoco.readthedocs.io) across both the Filament and classic OpenGL backends via--durationand--fps.Migration: Replace
record model.xml T F out.rgb 0withrender model.xml out.rgb --duration=T --fps=F(or pass-as the output path to pipe top-down RGB24 frames directly toffmpeg;vflipis no longer needed).
Models
-
9647e0290Added six elasto-plasticity example models, each placing an elastic reference next to a plastic counterpart: joint and tendon springs, 2D shells and 3D continua. -
89daf8d19Added speculative contacts example models: a Newton's cradle of thin plates, an interlocking chain, and a ball struck by a hinged flipper.
Documentation
-
74ad32d20Added documentation for MuJoCo Studio, covering web and native viewers, architecture, and Python and C++ development. -
0f1092ebbAdded a Model tuning guide to the Modeling chapter---covering the fidelity--speed trade-off, tuning defaults, priority-ordered global and model-level parameters, deformables, and system identification---along with module documentation for mujoco.sysid (mujoco.readthedocs.io).
Bug fixes
-
fdf141238accelerometer and framelinacc sensors andmj_objectAccelerationon static and mocap bodies now report the gravitational proper acceleration, like a dynamic body at rest. Previously they returned zero, a regression introduced in 3.3.7. -
c4137ef7c,aeb871ba1Actuators saturated by joint or tendon actuator force limits (joint and tendonactuatorfrcrange) no longer contribute implicit actuator derivatives, changing integration underimplicit,implicitfast, anddiscrete. Because saturated actuators no longer contribute implicit damping, models with light links and no armature may need joint armature or a smaller timestep. -
aaf2abaa7,1b46a496eFixed sleep filtering bugs in history sensors (nsample,delay,interval),mj_energyPos, flex passive forces, tendon limit and frictionloss constraints, two-tree tendon armature and bias,mj_subtreeVel, and caller-suppliedmj_rnebuffers. -
13fb7844emj_setConstnow wakes all sleeping trees, since it recomputes their kinematics atqpos0andqpos_spring. Previously their cached poses could be left atqpos_spring. It also no longer overwritescam_xpos,cam_xmat,light_xposandlight_xdirinmjData, which left static cameras and lights with tracking or targeting at their fixed-mode poses. -
432376a59Contact pairs created with an undefinedmjsPair.solrefnow mix thesolrefof their geoms usingsolmixwhen both are positive, like contacts not defined by pairs. Previously they always took the element-wise minimum. -
18d65f4e0,ea6aa8214Filament depth and segmentation renders no longer apply post-processing (tone mapping, dithering), which corrupted depth values and segment ID colors; perspective depth renders now project with the finite zfar plane instead of Filament's infinite far plane, matching orthographic depth and the classic renderer; and themjr_compatibility API now respectsreadDepthMap(mjtDepthMap) onmjrContextinmjr_readPixelsand colors geoms bysegid + 1like mjRND_IDCOLOR so a geom withsegid0 no longer renders as background. -
9b19fd07c,ef34acbeeFile paths on Windows are now interpreted as UTF-8 rather than the active ANSI code page, fixing loading and saving files, plugin library discovery and loading (mj_loadPluginLibrary,mj_loadAllPluginLibraries), and simulate executable directory lookup when paths contain non-ASCII UTF-8 characters (#3139). Contribution by @mar-yan24. -
a5ff8f6c7Fixed dcmotor parameter handling: allow zero motorconst forinput="none", reject negative constants (e.g.motorconst="-a b"is now rejected instead of silently usingK = b), replace capacitance when an inconsistent thermal triple is given, clear inherited forcerange when saturation is authored, let zerosaturationorinductanceclear class defaults, and validate actdim at compile time. -
8694cc9ceImproved numerical stability of sphere and cylinder spatial tendon geom wrapping at wrap onset. Thanks to @M-Colley for reporting and analyzing the issue in MJWarp issue 1772. -
b6192732bmj_raynow scales SDF hit distances by1 / ||vec||for non-unit ray vectors, andmju_rayTrianglerejects triangle intersections behind the ray origin. -
00c19f04bmj_resetData,mj_copyData, andmj_recompilenow preserve the destinationmjDatathread pool instead of dropping and leaking it. -
a206daa42mju_mat2Rotnow normalizes the input quaternion and escapes 180-degree stationary points (saddles and minima) that do not maximize $\operatorname{tr}(R^\top M)$. -
afa16414cFixed the cotangent weight and length scale of the curved reference term of 2D flex bending (elastic2d bend or both), so out-of-plane bending forces vanish at curved rest configurations and scale consistently with model size. -
a4c699040Fixed several bugs when editing or copying anmjSpec:-
mjs_delete(MjSpec.deletein Python) now removes deleted default classes from the class lookup map instead of leaving dangling pointers. -
mj_copyBack(MjSpec.copy_backin Python) preserves materialmetallic,roughness, andtexuniformattributes. -
mjs_findChildno longer matches a non-world body against itself. -
mjs_setToMuscleacceptsNULLtimeconstandrangepointers.
-
-
00057bcefFixed several MJCF XML loading and saving bugs:-
include no longer double-prefixes the model directory on nested or relative paths.
-
Loading MJCF now applies enclosing frame transforms to flexcomp, and allows explicit
rangeor inheritrange attributes on actuator shortcuts to override conflicting defaults. -
default/tendon now accepts armature, actuatorfrclimited, and actuatorfrcrange, which were previously emitted when saving XML and then failed schema validation on reload.
-
Saving MJCF (
mj_saveLastXML,mj_saveXML,mj_saveXMLString) now preserves texture nchannel and clamps emitted gridlayout togridsize(while loading resetsgridlayoutwhen an authoredgridsizediffers from the inherited default), compares material layer textures, camera sensorsize, and light texture against default classes, and writes all attributes on plugin-backed meshes andreftype/refnameon plugin sensors.
-
-
881e53e2eLegacy.mshmeshes with mirrored scale no longer double-flip face winding (which inverted faces), and.mshfiles without vertex normals no longer populate empty face normals or reject custom normals on recompilation.

