Skip to content

3.16.0

Latest

Choose a tag to compare

@mmossg mmossg released this 14 Oct 09:29

Version 3.16.0 (October 14, 2026)

Significant new features

  1. cf89a6375, 4316935b3, 6d98d9fab, 5f17e92eb, 89d59b11f,
    147dc67d0 Frames can now scale their contents at compile time—without modifying the
    mjSpec—via the new scale, scaling, and
    massscale attributes. The default similar policy scales all physical quantities so that
    dynamics are preserved under proportionally scaled gravity, whereas geometry scales only spatial dimensions and
    inertias (and supports anisotropic scaling). Masses scale with volume unless overridden by massscale. External
    references to scaled elements—including actuators, tendons, constraints, sensors, keyframes, and deformable/mesh
    assets—are scaled consistently, and mj_copyBack maps values back into unscaled spec coordinates. See
    frame/scale for details.

  2. 592c54ad3, 92b8f4b27, d4595d020 Added compiler attributes
    savecompiled and savecanonical (both defaulting to
    "true") to preserve original authoring when saving models to XML. Setting savecompiled="false" saves the
    uncompiled mjSpec directly—retaining default classes, frames, and authored numeric values—so the saved XML
    reloads into an identical spec. Setting savecanonical="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_back in Python) now updates only the
    modified fields in the spec while leaving all other authored values untouched.

  3. 9d953b40c Added support for building MuJoCo with Bazel (initially covers core
    library, simulate, plugins, and samples).

General

Warning

Breaking API changes

  1. ea5e711c1 mjfDecode, the decode callback of mjpDecoder plugins, and
    mju_decodeResource now take char* error, int error_sz arguments. A decoder which fails writes its
    reason into error, which is then reported by mj_parse and 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 calling mju_warning. Pass an error buffer, or NULL, 0, to
    mju_decodeResource.

  2. 2757493d9 Shortened the names of mjpResourceProvider functions. mjp_getResourceProvider is
    renamed to mjp_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

  1. 0998957cf The contact sensor now supports linvel and angvel
    data fields for reporting relative contact velocities, and its computation stage
    (mjtStage) is now inferred from the requested data and
    reduce attributes.

  2. d823f9212 mj_setConst now 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_setConst also computes the constants of sleeping bodies, which it
    skipped, and resolves the automatic sleep policy of trees anew.

  3. 52824daf6 Corrected 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.

  4. 3bc4b769a Improved 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.

  5. 871e3725b Flex contacts are now reduced to mjMAXCONPAIR per 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.

  6. efffd3a5f Fixed 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

  1. 592c54ad3 mj_copyBack and mj_saveLastXML now 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_saveLastXML also 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.

  2. 2267bf299 An asset added to an mjSpec through the API is no longer named after its file when
    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_setName in C.

  3. 1961e8a2d Keyframes 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.

  4. 1db889162 With 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.

  1. 0696cdc85 flexcomp can now reference a mesh asset directly using
    the mesh attribute, in place of file. 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 the mesh parameter to Python body.make_flex; in mjs_makeFlex, the file
    parameter can also be the name of a mesh asset.

  2. ea019c212, 0696cdc85 Added procedural mesh types grid, box, cylinder, ellipsoid,
    square and disc to mesh/builtin and mjs_makeMesh, generating the same
    shapes as the corresponding flexcomp types, which flexcomp and geoms can use directly. Types
    without volume change a legacy mesh inertia to shell. Added Python convenience methods mjsMesh.make_*.

  3. dc8210572, 08490e897, 831994e2a Added mjs_fuseStatic, which fuses the static
    bodies of an mjSpec with 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".

  4. 1db889162 Added mjs_discardVisual, which discards the visual elements of an mjSpec as 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.

  5. d48b586ae Added mjs_adoptInertial, which makes the inertial that compilation infers from the geoms
    of a body part of the mjSpec, so that it no longer follows later changes to the geoms.

  6. 5558bd783 The 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_setTotalmass on the compiled model,
    followed by mj_setConst.

Compiler bug fixes

  1. 9fd6ee025 The quat of a geom, site or camera is no longer ignored when its
    default class gives an orientation as euler, axisangle, xyaxes or zaxis.

  2. 9fd6ee025, 92b8f4b27, 239647a1d Saving 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 another childclass; 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 another inertiafromgeom; 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.

  3. 592c54ad3 mj_saveXML and mj_saveXMLString now save the compiled values of an mjSpec
    as mj_saveLastXML does, 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.

  4. 1961e8a2d Keyframes of an mjSpec now 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.

  5. 3a35e7712 mjs_attach and 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.

  6. cbd16feac Fixed attaching by reference, the default of mjs_attach: mj_recompile gave 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.

  7. Fixed several bugs when editing or copying an mjSpec:

    • 239647a1d Saving 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, dc8210572 Compiling 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, dc8210572 mjs_findElement now finds elements added or renamed after
      compilation, and returns the named element for contact pairs, excludes and after
      discardvisual.

    • 3a9b10a3c, 3a35e7712 mjs_delete now 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.

    • 592c54ad3 mj_copyBack and mj_saveLastXML no 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 its size.

Actuation

  1. ab7f005c9 Actuator 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
    ctrlrange and gear are 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
    kp has the documented gain of 1, not 0. Added mjsActuator.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.

  2. fcb83a173 Actuators 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_ctrlspec and kept when a model is saved; mj_actuatorInputName returns the declaration.
    An input signature inherited from a default class is now discarded when the gaintype changes.

  3. 92b8f4b27 Added the inheritrange attribute to the
    general actuator, which so far only the position,
    intvelocity and pid shortcuts had.

Filament Rendering

Warning

Breaking API changes

  1. 4419c1be6, 6678efd66, 39b17ef2f, 6c2137fe0 Renamed mjrf functions
    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_shadows and
    |br| enable_headlight drop the enable_ prefix
    |br| mjrfContextConfig: force_software_rendering → software_rendering
    |br| mjrfMaterial: decor_ux → decor
    |br| Support class ModelObjects → ModelResources

    Python 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.

  2. e87cafb26 Renamed 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_size

    filament.ao.quality, filament.ao.low_pass_filter, filament.ao.upsampling and
    filament.bloom.quality take "low", "medium", "high" or "ultra" instead of 0-3; filament.shadows.type
    takes "pcf", "vsm" or "pcss" instead of 0-2.

  3. e7b0bc104 Removed mjrf_setLightBlurWidth and mjrfLightParams::vsm_blur_width, and their Python
    counterparts mjrf.Light.setBlurWidth and mjrf.LightParams.vsm_blur_width. This removes soft shadows with
    VSM.

    Migration: Use PCSS shadows instead by setting the custom flag filament.shadows.type to pcss. PCSS
    shadows provide similar quality and are more performant.

  4. e71e9f6db Removed the filament.msaa.enabled custom flag; multi-sample anti-aliasing is now
    controlled by visual/quality/offsamples (<= 1 disables MSAA) and can be
    changed at runtime with mjrf_setSceneMsaa.

  5. 6c2137fe0 Removed mjrf_DEBUG_drawImguiEditor from the public API; the ImGui scene editor is an
    internal debugging aid for MuJoCo Studio.

Python bindings

  1. 43eff4c76 The opt, vis and stat attributes of MjModel, and the sub-struct attributes of
    MjVisual, can now be assigned to (e.g. model.opt = new_opt); previously this raised AttributeError.
    Assignment copies the fields into the underlying C struct in place, so existing references and NumPy array views
    into the destination remain valid.

Models

  1. dc0c237df Added 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

  1. 641652525 Added documentation for Filament rendering.

  2. 1b7d9e83b The XML reference now gives the physical dimension of every real-valued
    attribute, declared in the MJCF schema.