From c54f1fe380eec3001bad9716c7e2049879c2624c Mon Sep 17 00:00:00 2001 From: Yuval Tassa Date: Thu, 12 Feb 2026 02:10:49 -0800 Subject: [PATCH] Use semantic versioning. PiperOrigin-RevId: 869102767 Change-Id: I8b01b9343289d4ad7d15bcc3634a28e661308a90 --- README.md | 6 +++ VERSIONING.md | 75 ++++++++++++++++++++++++++++ doc/APIreference/APIglobals.rst | 11 ++-- doc/programming/index.rst | 9 ++-- include/mujoco/mujoco.h | 2 +- src/engine/engine_support.c | 2 +- unity/Runtime/Bindings/MjBindings.cs | 2 +- 7 files changed, 95 insertions(+), 12 deletions(-) create mode 100644 VERSIONING.md diff --git a/README.md b/README.md index 701fb17e..9eabc498 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,12 @@ Note that Pre-built Linux wheels target `manylinux2014`, see information such as building the bindings from source, see the [Python bindings] section of the documentation. +## Versioning + +We aim to release MuJoCo in the first week of each month. Our versioning +standards changed to modified Semantic Versioning in 3.5.0, +see [versioning](VERSIONING.md) for details. + ## Contributing We welcome community engagement: questions, requests for help, bug reports and diff --git a/VERSIONING.md b/VERSIONING.md new file mode 100644 index 00000000..8adde6fe --- /dev/null +++ b/VERSIONING.md @@ -0,0 +1,75 @@ +# MuJoCo Versioning + +MuJoCo uses custom semantic versioning from 3.5.0 onwards, see below. + +### The problem with Semantic Versioning + +The common definition of traditional [Semantic Versioning](https://semver.org/) +is + +``` +1. MAJOR: breaking changes +2. MINOR: new features +3. PATCH: bug fixes +``` + +With strict adherence to this definition, most MuJoCo releases are `MAJOR`. This +is because MuJoCo has a very large API surface, especially when considering +[MJCF](https://mujoco.readthedocs.io/en/stable/XMLreference.html) and the +related +[mjSpec](https://mujoco.readthedocs.io/en/stable/programming/modeledit.html) +API. Furthermore, the numerical properties of physics state integration mean +that despite being deterministic, numerical reproducibility across versions is +almost guaranteed to +[not hold](https://mujoco.readthedocs.io/en/stable/computation/index.html#reproducibility). + +## From 3.5.0 – semantic versioning + +From 3.5.0 onwards MuJoCo uses well-defined versioning with the following +semantics. + +### MuJoCo versioning semantics + +``` +1. SUPERMAJOR: breaking changes and/or significant new features +2. MAJOR: breaking changes, possibly new features +3. MINOR_OR_PATCH: new features or bug fixes +``` + +`MINOR_OR_PATCH` guarantees API backward compatibility, but may or may not +introduce new features; to find out, read the +[changelog](https://mujoco.readthedocs.io/en/stable/changelog.html), which will +detail the nature of the changes. The changelog will also detail pure +ABI-breaking changes, for example removing an unused attribute from a public +struct. Such changes are considered MINOR. As explained +[here](https://mujoco.readthedocs.io/en/stable/computation/index.html#reproducibility), +numerical reproducibility is *never* guaranteed. + +Additionally: + +- `mj_versionString()` works as before, returning e.g. `"4.2.1"`. +- `mj_version()` works as before, returning an integer. The corresponding + header constant `mjVERSION_HEADER` is calculated from the components as: + + ``` + mjVERSION = (SUPERMAJOR * 1e6) + (MAJOR * 1e3) + MINOR_OR_PATCH + ``` + + For example, 4.2.1 would be `4002001`. + +## Prior to 3.5.0 – no semantics + +Until 3.5.0, versioning was a sequence of increasing numbers with no +well-defined semantic, with the exception of major versions introducing +significant new features, like +[3.0.0](https://mujoco.readthedocs.io/en/stable/changelog.html#version-3-0-0-october-18-2023)'s +introduction of the JAX-based +[MJX](https://mujoco.readthedocs.io/en/stable/mjx.html) branch. Additionally: + +- The function + [`const char* mj_versionString()`](https://mujoco.readthedocs.io/en/stable/APIreference/APIfunctions.html#mj-versionstring) + returns the version in the form of a string, for example `"3.2.7"`. +- The function + [`int mj_version()`](https://mujoco.readthedocs.io/en/stable/APIreference/APIfunctions.html#mj-version) + returns an integer equal to the version digits concatenated, + for example for "3.2.7" we'd have `mjVERSION = 327`. diff --git a/doc/APIreference/APIglobals.rst b/doc/APIreference/APIglobals.rst index d47fd80e..39c1c650 100644 --- a/doc/APIreference/APIglobals.rst +++ b/doc/APIreference/APIglobals.rst @@ -527,11 +527,12 @@ shown in the table below. Their names are in the format ``mjKEY_XXX``. They corr - Maximum number of UI rectangles. Defined in `mjui.h `_. * - ``mjVERSION_HEADER`` - - 350 - - The version of the MuJoCo headers; changes with every release. This is an integer equal to 100x the software - version, so 210 corresponds to version 2.1. Defined in mujoco.h. The API function :ref:`mj_version` returns a - number with the same meaning but for the compiled library. - + - 3005000 + - The version of the MuJoCo headers. This is an integer calculated from the version string "S.M.P" + using the formula ``(S * 1e6) + (M * 1e3) + P``. For example, version 4.2.1 is represented as 4002001. + Defined in mujoco.h. The API function :ref:`mj_version` returns a number with the same meaning + but for the compiled library. See + `VERSIONING.md `__ for details. .. _Macros: diff --git a/doc/programming/index.rst b/doc/programming/index.rst index 7fbf6f6e..7d91d013 100644 --- a/doc/programming/index.rst +++ b/doc/programming/index.rst @@ -191,7 +191,7 @@ Versions and compatibility MuJoCo has been used extensively since 2010 and is quite mature (even though our version numbering scheme is quite conservative). Nevertheless it remains under active development, and we have many exciting ideas for new features and -are also making changes based on user feedback. This leads to unavoidable changes in both the modeling language in the +are also making changes based on user feedback. This leads to unavoidable changes in both the modeling language and the API. While we encourage users to upgrade to the latest version, we recognize that this is not always feasible, especially when other developers release software that relies on MuJoCo. Therefore we have introduced simple mechanisms to help avoid version conflicts, as follows. @@ -206,13 +206,14 @@ the symbol :ref:`mjVERSION_HEADER ` and the library provides the func .. code-block:: C // recommended version check - if (mjVERSION_HEADER!=mj_version()) + if (mjVERSION_HEADER != mj_version()) complain(); Note that only the main header defines this symbol. We assume that the collection of headers released with each software version will stay together and will not be mixed between versions. To avoid complications with floating-point -comparisons, the above symbol and function use integers that are 100x the version number, so for example in software -version 2.1 the symbol mjVERSION_HEADER is defined as 210. +comparisons, the above symbol and function use integers rather than floating-point numbers. See +`VERSIONING.md `__ for the encoding formula and +version semantics. .. _inNaming: diff --git a/include/mujoco/mujoco.h b/include/mujoco/mujoco.h index 672bd6e8..829ee7e8 100644 --- a/include/mujoco/mujoco.h +++ b/include/mujoco/mujoco.h @@ -16,7 +16,7 @@ #define MUJOCO_MUJOCO_H_ // header version; should match the library version as returned by mj_version() -#define mjVERSION_HEADER 350 +#define mjVERSION_HEADER 3005000 // needed to define size_t, fabs and log10 #include diff --git a/src/engine/engine_support.c b/src/engine/engine_support.c index 9f74c0b9..e4315000 100644 --- a/src/engine/engine_support.c +++ b/src/engine/engine_support.c @@ -43,7 +43,7 @@ //-------------------------- Constants ------------------------------------------------------------- - #define mjVERSION 350 + #define mjVERSION 3005000 #define mjVERSIONSTRING "3.5.0" // names of disable flags diff --git a/unity/Runtime/Bindings/MjBindings.cs b/unity/Runtime/Bindings/MjBindings.cs index 119de775..b0771c5b 100644 --- a/unity/Runtime/Bindings/MjBindings.cs +++ b/unity/Runtime/Bindings/MjBindings.cs @@ -112,7 +112,7 @@ public const int mjMAXLINEPNT = 1001; public const int mjMAXPLANEGRID = 200; public const bool THIRD_PARTY_MUJOCO_MJXMACRO_H_ = true; public const bool THIRD_PARTY_MUJOCO_MUJOCO_H_ = true; -public const int mjVERSION_HEADER = 350; +public const int mjVERSION_HEADER = 3005000; // ------------------------------------Enums------------------------------------