Custom environment¶
Add an env-client-side environment so plugrl-run-env-client <env_id> can discover and run it.
Quickstart¶
Create an env class and a config dataclass, then register both.
import dataclasses
import numpy as np
from plugrl_env_client.envs.base_env import Action, BaseEnv, BaseEnvConfig, Observation
from plugrl_env_client.utils.registration import register_env, register_env_config
UID = "custom-v1"
@register_env_config(UID)
@dataclasses.dataclass
class CustomConfig(BaseEnvConfig):
...
@register_env(UID)
class CustomEnv(BaseEnv):
def __init__(
self,
config: CustomConfig,
num_envs: int = 1,
process_id: int | None = None,
total_processes: int | None = None,
):
super().__init__(
config=config,
num_envs=num_envs,
process_id=process_id,
total_processes=total_processes,
)
def prepare_obs(self, obs: np.ndarray) -> Observation:
return Observation(images={}, states={}, text="")
def reset(self, *, seed: int | None = None, options: dict | None = None) -> tuple[Observation | None, dict]:
...
def step(self, action: Action) -> tuple[Observation | None, float, bool, bool, dict]:
...
Verify¶
Env should appear as a CLI subcommand.
Run one episode against a dummy server.
plugrl-run-server dummy-policy default dummy default
plugrl-run-env-client custom-v1 --num-episodes 1
Contract¶
- Env inherits
BaseEnv. - Config inherits
BaseEnvConfig. - Implement
resetandstep. - Convert raw env outputs into
Observationinprepare_obs. __init__takesconfig, num_envs, process_id, total_processes, the same four asBaseEnv.__init__and as the shippedMuJoCoEnv.EnvSpec.makealways passesnum_envs, andgym.make_vecforwardsprocess_idandtotal_processes. An earlier version of this page usedworker_idandtotal_workers; those names appear nowhere inplugrl-env-client, and a class with that signature raisesTypeErroron the unexpectednum_envs.
Registration¶
register_env_configregisters the config dataclass.register_envregisters the env class.register_envsupports optional parameters such asmax_episode_steps.
Troubleshooting¶
- Env ID not listed: module import did not run.
- Multi process init conflicts: try
--runner.use-env-lock.