Repository navigation
Version 3.16.0 (October 14, 2026)
Significant new features
-
cf89a6375,4316935b3,6d98d9fab,5f17e92eb,89d59b11f,
147dc67d0Frames can now scale their contents at compile time—without modifying the
mjSpec—via the new scale, scaling, and
massscale attributes. The defaultsimilarpolicy scales all physical quantities so that
dynamics are preserved under proportionally scaled gravity, whereasgeometryscales only spatial dimensions and
inertias (and supports anisotropic scaling). Masses scale with volume unless overridden bymassscale. External
references to scaled elements—including actuators, tendons, constraints, sensors, keyframes, and deformable/mesh
assets—are scaled consistently, andmj_copyBackmaps values back into unscaled spec coordinates. See
frame/scale for details. -
592c54ad3,92b8f4b27,d4595d020Added compiler attributes
savecompiled and savecanonical (both defaulting to
"true") to preserve original authoring when saving models to XML. Settingsavecompiled="false"saves the
uncompiledmjSpecdirectly—retaining default classes, frames, and authored numeric values—so the saved XML
reloads into an identical spec. Settingsavecanonical="false"additionally preserves the original input
conventions, such as orientation representations, degree/radian units, and actuator shortcuts; see
Model Encoding & Saving.mj_copyBack(MjSpec.copy_backin Python) now updates only the
modified fields in the spec while leaving all other authored values untouched. -
9d953b40cAdded support for building MuJoCo with Bazel (initially covers core
library,simulate, plugins, and samples).
General
Warning
Breaking API changes
-
ea5e711c1mjfDecode, thedecodecallback ofmjpDecoderplugins, and
mju_decodeResourcenow takechar* error, int error_szarguments. A decoder which fails writes its
reason intoerror, which is then reported bymj_parseand in mesh compilation errors, rather than only
as a warning with a generic error.Migration: Add the two arguments to custom decoders and write failure messages into
error(if not
NULL) instead of callingmju_warning. Pass an error buffer, orNULL, 0, to
mju_decodeResource. -
2757493d9Shortened the names ofmjpResourceProviderfunctions.mjp_getResourceProvideris
renamed tomjp_findProvider, consistent with other prefix and extension lookups.Migration: Rename as follows:
|br|mjp_defaultResourceProvider→mjp_defaultProvider
|br|mjp_registerResourceProvider→mjp_registerProvider
|br|mjp_resourceProviderCount→mjp_providerCount
|br|mjp_getResourceProvider→mjp_findProvider
|br|mjp_getResourceProviderAtSlot→mjp_getProviderAtSlot
|br|mjp_registerArchiveResourceProvider→mjp_registerArchiveProvider
|br|mjp_findArchiveResourceProvider→mjp_findArchiveProvider
|br|mjp_archiveResourceProviderCount→mjp_archiveProviderCount
Engine
-
0998957cfThe contact sensor now supportslinvelandangvel
data fields for reporting relative contact velocities, and its computation stage
(mjtStage) is now inferred from the requested data and
reduce attributes. -
d823f9212mj_setConstnow computes the bounding volumes of geoms and bodies, the collision masks and
margins of bodies, and the added mass of geoms in the ellipsoid fluid model. Changes to the size,
pose, margin and gap of geoms, to the inertial frames of bodies and to the size of height fields are then safe;
previously contacts could be missed.mj_setConstalso computes the constants of sleeping bodies, which it
skipped, and resolves the automatic sleep policy of trees anew. -
52824daf6Corrected the shear contribution to solid and membrane stiffness for interpolated flexes, and the
three-point Gauss quadrature used by quadratic flexes. Material parameters now produce the standard isotropic
linear-elastic stiffness; existing models using these flexes can change behavior. -
3bc4b769aImproved numerical stability of sphere and cylinder spatial tendon
geom wrapping near wrap onset and for inside wrapping. Thanks to @M-Colley for
reporting and analyzing the issues in MJWarp issues
1713 and
1714. -
871e3725bFlex contacts are now reduced tomjMAXCONPAIRper geom only for rigid and interpolated
flexes; other flexes keep all their contacts. Previously, cloth resting on a plane or on many static geoms could be
held by at most 50 contacts and fall through. -
efffd3a5fFixed floating-point cancellation in capsule-capsule collision detection for parallel and
near-parallel axes. Thanks to @ayonga for reporting the issue in MJWarp issue
1758.
Compiler
Warning
Breaking API changes
-
592c54ad3mj_copyBackandmj_saveLastXMLnow fail, with an error which names the element,
if a value was changed in the model which the spec cannot express, for example the mass of a body when
inertiafromgeom is "true". Nothing is copied or saved then; previously such a
change was left out of the saved file without notice.mj_saveLastXMLalso fails if it is given a model
which was not compiled from the XML that was loaded last, and a save which fails no longer empties the file.Migration: Undo the change in the model, or change what makes it inexpressible, as listed for
mj_copyBack. -
2267bf299An asset added to anmjSpecthrough the API is no longer named after itsfilewhen
the spec is compiled. A mesh, height field or texture which is left without a name is now a compilation error, as
it already was for one without a file. MJCF is unaffected: the XML parser still names assets after their files.Migration: Name the asset when adding it, e.g.
spec.add_mesh(name='link', file='link.stl')in Python or
mjs_setNamein C. -
1961e8a2dKeyframes in MJCF are no longer copied by replicate: a
keyframe describes the model with all replicas in place, as in a model without replicates. Previously each
replica received a copy of every keyframe, setting only the joints of that replica, and a keyframe written for
the complete model failed to load (#3071, reported by @eholum-nasa).Migration: Write the vectors of a keyframe for the complete model. A keyframe which was written for a single
replica still loads, as one keyframe whose vectors are completed with the default configuration. -
1db889162With inertiafromgeom "true",
discardvisual is now a compilation error if a geom which it discards has mass.
Previously the first compilation kept the inertia of the discarded geoms, while compiling the same spec again, or
saving it and loading the file, dropped it.Migration: Use
inertiafromgeom="auto", the default, under which the inertia is kept as an explicit
inertial, or give the visual geoms zero mass.
-
0696cdc85flexcomp can now reference a mesh asset directly using
the mesh attribute, in place offile. Volumetric meshes (e.g. from GMSH) supply
nodes and tetrahedra directly; surface meshes can create 1D or 2D flexes or extrude to volumetric tetrahedra using
origin. Added themeshparameter to Pythonbody.make_flex; inmjs_makeFlex, thefile
parameter can also be the name of a mesh asset. -
ea019c212,0696cdc85Added procedural mesh typesgrid,box,cylinder,ellipsoid,
squareanddiscto mesh/builtin andmjs_makeMesh, generating the same
shapes as the corresponding flexcomp types, which flexcomp and geoms can use directly. Types
without volume change alegacymesh inertia toshell. Added Python convenience methodsmjsMesh.make_*. -
dc8210572,08490e897,831994e2aAddedmjs_fuseStatic, which fuses the static
bodies of anmjSpecwith their parents as an operation on the spec: each fused body becomes a frame in its
parent. The fusestatic compiler option now applies it and then compiles; previously it
fused inside compilation and left the spec inconsistent with the model. Static bodies whose fusing would change the
forces on the model (a plugin, a sleep policy, another gravcomp, a fluid), or which a flex or skin refers to, are
now kept, and cameras and lights are no longer misplaced. Elements which refer by name to a geom, site, camera or
light are no longer bound to a different one, and referencing a body by name no longer leaves other static bodies
unfused. The new fuse body attribute keeps a static body when set to "false". -
1db889162Addedmjs_discardVisual, which discards the visual elements of anmjSpecas an
operation on the spec. The discardvisual compiler option now applies it and then
compiles; previously it discarded inside compilation and left references to what it discarded in the spec, so that
some models failed to compile. Visual meshes are no longer loaded unless body inertia is inferred from them, and
geoms which use the ellipsoid fluid model are kept. -
d48b586aeAddedmjs_adoptInertial, which makes the inertial that compilation infers from the geoms
of a body part of themjSpec, so that it no longer follows later changes to the geoms. -
5558bd783The settotalmass compiler attribute is deprecated and will be
removed in a future release. It still scales the masses, and compiling a model which sets it now gives a warning.Migration: Scale the masses and densities in the model, or call
mj_setTotalmasson the compiled model,
followed bymj_setConst.
Compiler bug fixes
-
9fd6ee025Thequatof a geom, site or camera is no longer ignored when its
default class gives an orientation aseuler,axisangle,xyaxesorzaxis. -
9fd6ee025,92b8f4b27,239647a1dSaving MJCF no longer changes or loses the following:
the order of the elements of a body which has frames, which gave the saved model other ids;
class="main"inside anotherchildclass; the nchannel of a texture; the names
of energy sensors, which could not be loaded;inertiafromgeom="false", and the inertia of the bodies of an
attached model which has anotherinertiafromgeom; the frame of the surfacevel of
mesh geoms; the precision of mesh, flex, skin and height field data; and the empty cells of a
flexcomp with trilinear or quadratic dofs. -
592c54ad3mj_saveXMLandmj_saveXMLStringnow save the compiled values of anmjSpec
asmj_saveLastXMLdoes, including those which are computed at the end of compilation, such as the damping
which dampratio gives, and no longer lose the scaling of
settotalmass. -
1961e8a2dKeyframes of anmjSpecnow keep their place and their values when its
kinematic tree changes (mjs_delete,mjs_attach) and when the spec is copied; previously the next
compilation created them again, and values were lost or misplaced in several cases. A vector which is shorter than
the model is completed with the default configuration of the compiled model. -
3a35e7712mjs_attachand the attach element now apply the prefix and suffix to
the name and material of skins and to the material of tendons and meshes. Attaching a model in which one of these
has a material used to fail to compile. -
cbd16feacFixed attaching by reference, the default ofmjs_attach:mj_recompilegave the
attached elements the state of other elements of the parent, and attaching another body or frame of the same model
failed or left out the elements which refer to it. Attaching what the parent already has is now an error. -
Fixed several bugs when editing or copying an
mjSpec:-
239647a1dSaving the compiled values of a spec which was structurally edited since it was compiled
(elements added, deleted or attached) is now an error until it is compiled again; it used to crash or save wrong
values. -
2267bf299,dc8210572Compiling no longer reorders contact pairs and
excludes, writes into authored fields such as the data of a texture, or keeps references
removed since the last compilation. -
2267bf299,dc8210572mjs_findElementnow finds elements added or renamed after
compilation, and returns the named element for contact pairs, excludes and after
discardvisual. -
3a9b10a3c,3a35e7712mjs_deletenow deletes a plugin instance
together with the last element referencing it, and deleting a body removes the elements referencing it after
discardvisual or later edits. Both cases used to make the next compilation fail or
crash. -
592c54ad3mj_copyBackandmj_saveLastXMLno longer lose a change to the reference pose of
a free joint, or write out of bounds for a numeric which has less data than itssize.
-
Actuation
-
ab7f005c9Actuator shortcuts now inherit their parameters (kp,kv,area,
...) only from a default written with the same shortcut or with general,
looking up the class hierarchy for one, and otherwise use their documented defaults; mechanical attributes like
ctrlrangeandgearare inherited from any default, as before. A motor in a class with
a position default used to be a position servo (#3561). Every shortcut now sets
its full documented table, including its dynamics and activation layout, and a pid without
kphas the documented gain of 1, not 0. AddedmjsActuator.type(mjtActuator), the element an actuator
is written with.Migration: Write the gains on the actuator itself, or in a default of the same shortcut or of
general. -
fcb83a173Actuators with "fixed" or "affine" gaintype can declare what
their control is with input: a position setpoint ("pos"), a velocity setpoint ("vel")
or a pressure ("pressure"); without a declaration it is a command. The declaration does not affect the simulation.
The position, velocity, intvelocity
and cylinder shortcuts declare their inputs, which are recorded in
mjModel.actuator_ctrlspecand kept when a model is saved;mj_actuatorInputNamereturns the declaration.
An input signature inherited from a default class is now discarded when the gaintype changes. -
92b8f4b27Added the inheritrange attribute to the
general actuator, which so far only the position,
intvelocity and pid shortcuts had.
Filament Rendering
Warning
Breaking API changes
-
4419c1be6,6678efd66,39b17ef2f,6c2137fe0Renamedmjrffunctions
and types so that the owning object appears first (mjrf_<verb><Owner><Thing>) and names match MJCF attributes
and existing MuJoCo vocabulary (cf.mjr_uploadMesh,mjModel.light_active).Migration: Rename as follows:
|br|mjrf_addRenderableToScene→mjrf_addSceneRenderable
|br|mjrf_removeRenderableFromScene→mjrf_removeSceneRenderable
|br|mjrf_addLightToScene→mjrf_addSceneLight
|br|mjrf_removeLightFromScene→mjrf_removeSceneLight
|br|mjrf_setMeshData→mjrf_uploadMesh
|br|mjrf_setTextureData→mjrf_uploadTexture
|br|mjrf_setRenderableTransform→mjrf_setRenderablePose
|br|mjrf_setLightTransform→mjrf_setLightPose
|br|mjrf_setLightEnabled→mjrf_setLightActive
|br|mjrf_setLightCutoffAngle→mjrf_setLightCutoff
|br|mjrf_setLightShadowsEnabled→mjrf_setLightCastShadow
|br|mjrfReadPixelsRequest→mjrfReadRequest
|br|mjrfLightParams:spot_cone_angle→cutoff,spot_softness→softness,cast_shadows→
|br|cast_shadow
|br|mjrfRenderableParams:cast_shadows→cast_shadow,receive_shadows→receive_shadow
|br|mjrfRenderRequest:enable_post_processing,enable_reflections,enable_shadowsand
|br|enable_headlightdrop theenable_prefix
|br|mjrfContextConfig:force_software_rendering→software_rendering
|br|mjrfMaterial:decor_ux→decor
|br| Support classModelObjects→ModelResourcesPython names changed accordingly, e.g.
mjrf.ReadPixelsRequest→mjrf.ReadRequest,
Light.set_cutoff_angle→Light.set_cutoff,Light.set_shadows_enabled→Light.set_cast_shadow,
Mesh.set_data/Texture.set_data→upload,set_transform→set_pose,Light.set_enabled→
set_active,Material.decor_ux→decor,mjrf.ModelObjects→mjrf.ModelResources. -
e87cafb26Renamed custom flags for consistency, and changed enum flags to take strings
instead of integers.Migration: Rename as follows:
|br|filament.clearColor→filament.clear_color
|br|filament.fog.cutOffDistance→filament.fog.cut_off_distance
|br|filament.fog.maximumOpacity→filament.fog.maximum_opacity
|br|filament.fog.heightFalloff→filament.fog.height_falloff
|br|filament.fog.inScatteringStart→filament.fog.in_scattering_start
|br|filament.fog.inScatteringSize→filament.fog.in_scattering_sizefilament.ao.quality,filament.ao.low_pass_filter,filament.ao.upsamplingand
filament.bloom.qualitytake "low", "medium", "high" or "ultra" instead of 0-3;filament.shadows.type
takes "pcf", "vsm" or "pcss" instead of 0-2. -
e7b0bc104Removedmjrf_setLightBlurWidthandmjrfLightParams::vsm_blur_width, and their Python
counterpartsmjrf.Light.setBlurWidthandmjrf.LightParams.vsm_blur_width. This removes soft shadows with
VSM.Migration: Use PCSS shadows instead by setting the custom flag
filament.shadows.typetopcss. PCSS
shadows provide similar quality and are more performant. -
e71e9f6dbRemoved thefilament.msaa.enabledcustom flag; multi-sample anti-aliasing is now
controlled by visual/quality/offsamples (<= 1disables MSAA) and can be
changed at runtime withmjrf_setSceneMsaa. -
6c2137fe0Removedmjrf_DEBUG_drawImguiEditorfrom the public API; the ImGui scene editor is an
internal debugging aid for MuJoCo Studio.
Python bindings
43eff4c76Theopt,visandstatattributes ofMjModel, and the sub-struct attributes of
MjVisual, can now be assigned to (e.g.model.opt = new_opt); previously this raisedAttributeError.
Assignment copies the fields into the underlying C struct in place, so existing references and NumPy array views
into the destination remain valid.
Models
dc0c237dfAdded three
elastic mechanism example models
using multicell trilinear flexes: a cantilever material comparison, an elastic slider-crank, and a tendon-loaded
dipper arm. Inspired by
Miles Macklin's Reduced Elastic Links experiments.
Documentation
-
641652525Added documentation for Filament rendering. -
1b7d9e83bThe XML reference now gives the physical dimension of every real-valued
attribute, declared in the MJCF schema.