factoriax.engine.envs.wrappers#
The wrappers that compose over a Factoriax environment.
- class factoriax.engine.envs.wrappers.ActionMaskWrapper(inner: Environment[Any, EnvParams], blocked_actions: set[int] | list[int] | tuple[int, ...])#
Replace a blocked action with
Action.NOOP.The wrapper rewrites a blocked action and does not remove it. The action stays in the action space and still costs a timestep. An agent that sends one therefore loses a turn, and nothing stops it from choosing that action.
- Parameters:
inner – Environment to wrap. Any gymnax-compatible environment with the state type
EnvStateworks.blocked_actions –
Actionintegers to block. The constructor captures them and writes them into the JIT graph ofstep_env(). A different set therefore needs a new environment and a new compile.
- action_space(params: EnvParams) Discrete#
Return the action space of the inner environment, unchanged.
- Parameters:
params – The method does not read this argument. It is present for the gymnax signature.
- Returns:
The action space of the inner environment, unchanged. A blocked action stays in the space, and the wrapper rewrites it instead of removing it. An agent can therefore still send it, and the output width of a policy does not depend on the mask.
- Return type:
spaces.Discrete
- get_obs(state: Any, params: EnvParams) Array#
Return the observation of the inner environment.
- Parameters:
state – State to observe.
params – Environment parameters.
- Returns:
The observation of the inner environment.
- Return type:
- is_terminal(state: Any, params: EnvParams) Array#
Ask the inner environment whether the episode is at its end.
- Parameters:
state – State to test.
params – Environment parameters.
- Returns:
Scalar bool from the inner environment.
- Return type:
- observation_space(params: EnvParams) Box#
Return the observation space of the inner environment, unchanged.
- Parameters:
params – The method does not read this argument. It is present for the gymnax signature.
- Returns:
The observation space of the inner environment, unchanged.
- Return type:
spaces.Box
- reset_env(key: Array, params: EnvParams) tuple[Array, Any]#
Reset the inner environment and return its result.
- Parameters:
key – PRNG key for the world generation.
params – Environment parameters.
- Returns:
(obs, state)from the inner environment.- Return type:
- step_env(key: Array, state: Any, action: int | Array, params: EnvParams) tuple[Array, Any, Array, Array, dict[str, Any]]#
Rewrite a blocked action to NOOP, then step the inner environment.
- Parameters:
key – PRNG key. The method passes it to the inner environment.
state – State to advance.
action – Action to take. The method rewrites it to NOOP when it is blocked.
params – Environment parameters.
- Returns:
(obs, new_state, reward, done, info)from the inner environment, after the rewrite. A blocked action still costs a timestep.- Return type:
- class factoriax.engine.envs.wrappers.AutoResetState(env_state: EnvState, reset_state: EnvState)#
State that holds a copy of the start world, for a cheap auto-reset.
The class keeps a frozen copy of the start state next to the live state. At the end of an episode,
lax.selectputs the copy back. It does not callreset_env, which runs the whole terrain generation.The cost is one extra copy of
EnvStatefor each batch element. At 32x32 that is about 12 KB for each element. At 128x128 withmax_machines=4096it grows to about 185 KB for each element, which doubles the total state memory. On a large map, lowerbatch_sizeormax_machines.- replace(**updates)#
Returns a new object replacing the specified fields with new values.
- class factoriax.engine.envs.wrappers.AutoResetWrapper(inner: FactoriaxEnv, resample: bool = False)#
A gymnax wrapper that auto-resets from a cached state.
Use this wrapper when you need an auto-reset inside a
lax.scantraining loop, such as a PPO loop in the PureJaxRL style. To manage the episodes yourself, useFactoriaxEnvdirectly.- Parameters:
inner – Core Factoriax environment to wrap.
resample – Whether a new episode builds a new world. See
__init__().
- action_space(params: EnvParams) Discrete#
Return the action space of the inner environment, unchanged.
- Parameters:
params – The method does not read this argument. It is present for the gymnax signature.
- Returns:
The action space of the inner environment, unchanged.
- Return type:
spaces.Discrete
- get_obs(state: AutoResetState, params: EnvParams) Array#
Return the observation of the inner environment.
- Parameters:
state – Wrapped state.
params – Environment parameters.
- Returns:
The observation that the inner environment makes of the live state, and not of the cached state.
- Return type:
- is_terminal(state: AutoResetState, params: EnvParams) Array#
Ask the inner environment whether the episode is at its end.
- Parameters:
state – Wrapped state.
params – Environment parameters.
- Returns:
Scalar bool from the inner environment.
- Return type:
- observation_space(params: EnvParams) Box#
Return the observation space of the inner environment, unchanged.
- Parameters:
params – The method does not read this argument. It is present for the gymnax signature.
- Returns:
The observation space of the inner environment, unchanged.
- Return type:
spaces.Box
- reset_env(key: Array, params: EnvParams) tuple[Array, AutoResetState]#
Reset, and cache the start state for the later auto-resets.
- Parameters:
key – PRNG key for the world generation.
params – Environment parameters.
- Returns:
(obs, state). The method takes the cached copy here and never replaces it. Withresample=False, every episode of the run therefore repeats this exact world.- Return type:
- step_env(key: Array, state: AutoResetState, action: int | Array, params: EnvParams) tuple[Array, AutoResetState, Array, Array, dict[str, Any]]#
Step the environment, and auto-reset from the cache at the end.
When
doneis True,lax.selectputs the cached reset state in place of the live state. No terrain generation runs.- Parameters:
key – PRNG key. The method splits it into a step key and a reset key, so the reset branch draws a new world under
resample.state – Wrapped state, which holds both the live world and the cached world.
action – Action for the selected player.
params – Environment parameters.
- Returns:
(obs, new_state, reward, done, info). Whendoneis True, the state in the result is already the first state of the next episode, andrewardanddonestill describe the step that ended. Both branches run in every step, becausejax.lax.select()evaluates both.- Return type:
- class factoriax.engine.envs.wrappers.LogEnvState(env_state: Any, episode_returns: Array, episode_lengths: Array, returned_episode_returns: Array, returned_episode_lengths: Array, timestep: Array)#
State that totals the return and the length of each episode, for the log.
Every scalar field is a JAX array, so the state is safe under vmap and under scan. The
returned_*fields hold the numbers of the last finished episode. They are non-zero only on the step wheredonebecomes True.- env_state#
State of the inner wrapper. It can be any JAX pytree.
- Type:
Any
- episode_returns#
Running return of the current episode. It returns to 0 on
done.- Type:
jax.jaxlib._jax.Array
- episode_lengths#
Running step count of the current episode. It returns to 0 on
done.- Type:
jax.jaxlib._jax.Array
- returned_episode_returns#
Return of the episode that just finished. It is 0 while an episode runs.
- Type:
jax.jaxlib._jax.Array
- returned_episode_lengths#
Length of the episode that just finished. It is 0 while an episode runs.
- Type:
jax.jaxlib._jax.Array
- timestep#
Global step counter. Nothing resets it.
- Type:
jax.jaxlib._jax.Array
- replace(**updates)#
Returns a new object replacing the specified fields with new values.
- class factoriax.engine.envs.wrappers.LogWrapper(inner: Environment[Any, EnvParams])#
Add the numbers of each episode to the
infodict in every step.This wrapper takes any gymnax-compatible environment. Every call to
step_env()adds these keys to theinfodict:"returned_episode_returns", the return of the episode that finished last. It is non-zero only on the final step of an episode."returned_episode_lengths", the length of the episode that finished last. It is non-zero only on the final step of an episode."returned_episode", which isTrueon the step where an episode ends."timestep", the global step counter, which rises with every call.
These keys follow the
LogWrapperconvention of PureJaxRL. A training loop can therefore read the episode numbers directly fromtraj_batch.info, whichjax.lax.scanreturns.Examples
>>> import factoriax >>> env, params = factoriax.make("EasyRocket-v1", auto_reset=True) >>> from factoriax.engine.envs.wrappers import LogWrapper >>> log_env = LogWrapper(env) >>> # log_env.step_env(...) now returns info["returned_episode_returns"]
- action_space(params: EnvParams) Discrete#
Return the action space of the inner environment, unchanged.
- Parameters:
params – The method does not read this argument. It is present for the gymnax signature.
- Returns:
The action space of the inner environment, unchanged.
- Return type:
spaces.Discrete
- get_obs(state: LogEnvState, params: EnvParams) Array#
Return the observation of the inner environment.
- Parameters:
state – Wrapped state.
params – Environment parameters.
- Returns:
The observation of the inner environment.
- Return type:
- is_terminal(state: LogEnvState, params: EnvParams) Array#
Ask the inner environment whether the episode is at its end.
- Parameters:
state – Wrapped state.
params – Environment parameters.
- Returns:
Scalar bool from the inner environment.
- Return type:
- observation_space(params: EnvParams) Box#
Return the observation space of the inner environment, unchanged.
- Parameters:
params – The method does not read this argument. It is present for the gymnax signature.
- Returns:
The observation space of the inner environment, unchanged.
- Return type:
spaces.Box
- reset_env(key: Array, params: EnvParams) tuple[Array, LogEnvState]#
Reset the inner environment, and set every episode counter to zero.
- Parameters:
key – PRNG key for the world generation.
params – Environment parameters.
- Returns:
(obs, state), with the running episode counters at zero.- Return type:
- step_env(key: Array, state: LogEnvState, action: int | Array, params: EnvParams) tuple[Array, LogEnvState, Array, Array, dict[str, Any]]#
Step the inner environment, and update the episode counters.
On the step where
doneis True:returned_episode_returnstakes the return that just finished.returned_episode_lengthstakes the length that just finished.episode_returnsandepisode_lengthsreturn to zero.
Every info key is always present. Use
info["returned_episode"]as a boolean mask to select the validreturned_episode_returnsentries.- Parameters:
key – PRNG key. The method passes it to the inner environment.
state – Wrapped state, which carries the running counters.
action – Action for the selected player.
params – Environment parameters.
- Returns:
(obs, new_state, reward, done, info).infocarries the return and the length of the episode. Those two have meaning only on the step wheredoneis True.- Return type: