How to Integrate Different Environment Backends (Brax, Gymnax, and MuJoCo Playground) in EvoRL
EvoRL provides a unified Env abstraction that seamlessly integrates Brax, Gymnax, and MuJoCo Playground through a three-layer architecture of adapters, training wrappers, and a centralized factory function.
Integrating different environment backends in EvoRL allows you to leverage high-performance physics simulators while maintaining a consistent API for evolutionary reinforcement learning algorithms. The emi-group/evorl repository implements a backend-agnostic design that abstracts away simulator-specific details through standardized adapters and configurable auto-reset wrappers.
The Three-Layer Integration Architecture
EvoRL organizes environment integration into three distinct layers, each handling specific responsibilities from low-level API translation to high-level training semantics.
Adapter Layer (Backend-Specific Wrappers)
The adapter layer converts third-party environment APIs into EvoRL's standardized Env interface. Each supported backend implements a dedicated adapter class:
BraxAdapterinevorl/envs/brax.py(lines 26-60) wraps Brax environments and extractsobs,reward,done, andinfofieldsGymnaxAdapterinevorl/envs/gymnax.pyhandles Gymnax environments and converts Gymnax spaces to EvoRL spaces viagymnax_space_to_evorl_spaceMjxEnvAdapterinevorl/envs/mujoco_playground.pyintegrates MuJoCo Playground environments following the same pattern
These adapters inherit from EnvAdapter (itself a subclass of the abstract Env) and remain stateless except for storing the wrapped native environment, with all stochasticity driven by JAX PRNG keys supplied to reset and step calls.
Wrapper Layer (Training-Oriented Behaviors)
After adapter instantiation, EvoRL applies a stack of wrappers defined in evorl/envs/wrappers/training_wrapper.py that provide RL-specific functionality:
EpisodeWrapper– Tracks step counts, handles episode truncation and termination, and optionally computes episode returns- Auto-reset strategies – Controlled by the
AutoresetModeenum:NORMAL– UsesVmapAutoResetWrapperfor full reset each episodeFAST– UsesFastVmapAutoResetWrapperto reuse the first state and avoid extra random drawsENVPOOL– UsesVmapEnvPoolAutoResetWrapperadding a separate reset step andautoresetflagDISABLED– Leaves reset handling to the user
- Vectorisation –
VmapWrapperand variants replicate environmentsparalleltimes for batched training - Utility wrappers –
ActionSquashWrapperscales actions to[-1, 1]andObsFlattenWrapperflattens image observations
Factory Layer (Unified Environment Creation)
The create_env function in evorl/envs/__init__.py serves as the unified entry point, selecting the appropriate adapter and wrapper stack based on configuration parameters including env_type, env_backend, and autoreset_mode.
Core Abstraction: The Env Interface
All environment integrations implement the abstract base class defined in evorl/envs/env.py:
class Env(ABC):
@abstractmethod
def reset(self, key: chex.PRNGKey) -> EnvState: ...
@abstractmethod
def step(self, state: EnvState, action: Action) -> EnvState: ...
@property
@abstractmethod
def action_space(self) -> Space: ...
@property
@abstractmethod
def obs_space(self) -> Space: ...
The EnvState dataclass carries the raw environment state, current observation, reward, done flag, mutable info dictionary, and an internal _internal dictionary used by wrappers (e.g., storing auto-reset keys).
Backend-Specific Implementation Details
Brax Integration
The Brax adapter in evorl/envs/brax.py creates a Brax Env instance and extracts observation, reward, done, and info fields during step transitions. The create_wrapped_brax_env function (lines 31-53) constructs the full wrapper stack including episode management and vectorisation.
Gymnax Integration
Located in evorl/envs/gymnax.py, the Gymnax adapter uses gymnax.make to instantiate environments and calls reset and step_env for state transitions. It includes space conversion utilities to map Gymnax observation and action spaces to EvoRL's space definitions.
MuJoCo Playground Integration
The MuJoCo Playground adapter in evorl/envs/mujoco_playground.py follows the same stateless adapter pattern, wrapping MuJoCo Playground environments for compatibility with the EvoRL training pipeline.
Training Wrappers and Auto-Reset Modes
EvoRL provides sophisticated auto-reset capabilities through evorl/envs/wrappers/training_wrapper.py. The AutoresetMode enum determines how environments handle episode termination:
- NORMAL mode uses
VmapAutoResetWrapperto perform full environment resets when episodes end - FAST mode uses
FastVmapAutoResetWrapperto optimize reset performance by reusing initial states - ENVPOOL mode uses
VmapEnvPoolAutoResetWrapperto add explicit reset steps and autoreset flags, compatible with EnvPool-style training loops - DISABLED mode leaves reset handling entirely to the user code
The EpisodeWrapper tracks step counts, handles truncation based on episode_length, and computes episode returns when configured.
Creating Environments with the Unified Factory
The recommended approach for environment creation uses the unified factory function. Configuration is typically supplied via Hydra/OmegaConf:
env:
env_type: brax # Options: brax, gymnax, playground, jumanji, jaxmarl, envpool, gymnasium
env_name: ant
autoreset_mode: normal # normal | fast | disabled | envpool
episode_length: 1000
parallel: 8
from evorl.envs import create_env
import jax, hydra, omegaconf
@hydra.main(version_base=None, config_path=".", config_name="config")
def main(cfg: omegaconf.OmegaConf):
env = create_env(cfg.env, seed=42)
state = env.reset(jax.random.PRNGKey(0))
# Training loop proceeds here
The create_env function in evorl/envs/__init__.py matches the env_type parameter and dispatches to the appropriate create_wrapped_*_env function, handling all adapter instantiation and wrapper stacking automatically.
Extending EvoRL with New Backends
To add support for a new simulation backend:
-
Create an adapter class inheriting from
EnvAdapter(which extendsEnv). Implementreset,step,action_space, andobs_spacemethods following the interface inevorl/envs/env.py. -
Expose creator functions implementing
create_mybackend_envfor raw access andcreate_wrapped_mybackend_envthat constructs the standard wrapper stack (reuse logic from existingcreate_wrapped_*_envfunctions inevorl/envs/brax.pyor similar). -
Register in the factory by adding imports to
evorl/envs/__init__.pyand extending thematchstatement increate_envto handle your newenv_type.
Because all wrappers operate on the abstract Env interface, agents, rollout workers, and evaluators require no modifications to work with new backends.
Summary
- EvoRL uses a three-layer architecture consisting of backend-specific adapters, training-oriented wrappers, and a unified factory function to integrate Brax, Gymnax, and MuJoCo Playground.
- Adapters in
evorl/envs/brax.py,gymnax.py, andmujoco_playground.pytranslate third-party APIs into the standardEnvinterface defined inevorl/envs/env.py. - Wrappers in
evorl/envs/wrappers/training_wrapper.pyprovide episode management, four auto-reset modes (NORMAL,FAST,ENVPOOL,DISABLED), and vectorisation viaVmapWrappervariants. - Unified creation via
create_envinevorl/envs/__init__.pydispatches to backend-specific builders based onenv_typeconfiguration, supporting Hydra/OmegaConf configurations. - Extensibility follows a clear pattern: implement
EnvAdapter, create wrapped builder functions, and register in the factory match statement.
Frequently Asked Questions
What is the difference between Brax and Gymnax backends in EvoRL?
Brax environments are physics-based simulators optimized for massive parallelization on accelerators, typically used for continuous control tasks like locomotion. Gymnax provides classic control and toy text environments with a focus on simplicity and educational use. In EvoRL, both implement the same Env interface, but Brax adapters extract obs, reward, done, and info from Brax-specific state structures, while Gymnax adapters use gymnax.make and convert Gymnax spaces to EvoRL spaces.
How does the auto-reset mechanism work in EvoRL environments?
EvoRL provides four auto-reset modes controlled by the AutoresetMode enum in evorl/envs/wrappers/training_wrapper.py. NORMAL mode uses VmapAutoResetWrapper to perform full environment resets when episodes terminate. FAST mode uses FastVmapAutoResetWrapper to optimize performance by reusing the initial state instead of generating new random states. ENVPOOL mode uses VmapEnvPoolAutoResetWrapper to add explicit reset steps and autoreset flags, compatible with EnvPool-style training loops. DISABLED mode leaves reset handling to the user code.
Can I use multiple different backends in the same EvoRL training script?
Yes, EvoRL's unified Env abstraction allows mixing backends within the same training workflow. Since all backends (Brax, Gymnax, MuJoCo Playground) implement the identical Env interface defined in evorl/envs/env.py, you can instantiate different environments using create_env or specific create_wrapped_*_env functions, and use them interchangeably in rollout workers or evaluation loops. The wrapper stack ensures consistent behavior for episode management and auto-reset across all backends.
Where are the environment wrappers defined in the EvoRL codebase?
Environment wrappers are located in evorl/envs/wrappers/, with the primary training-oriented wrappers defined in evorl/envs/wrappers/training_wrapper.py. This file contains EpisodeWrapper for episode management, VmapAutoResetWrapper and FastVmapAutoResetWrapper for different auto-reset strategies, and VmapEnvPoolAutoResetWrapper for EnvPool compatibility. Additional utility wrappers like ActionSquashWrapper and ObsFlattenWrapper handle action scaling and observation flattening respectively.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →