Rate this Page

Maze Environment#

A gridworld maze where the agent must navigate from a start cell to an exit while avoiding walls.

Maze Layout#

The default environment ships with a single 8x8 maze:

0 0 0 0 0 1 0 0
1 1 0 1 0 1 0 1
0 0 0 1 0 0 0 1
0 1 1 1 1 1 0 0
0 0 0 0 0 0 1 0
1 0 1 1 1 0 0 0
0 0 0 0 1 0 1 0
0 1 1 0 0 0 0 0

0 is an empty cell and 1 is a wall. Coordinates are (col, row) with (0, 0) at the upper-left.

Quick Start#

The simplest way to use the Maze environment is through the MazeEnv client:

from maze_env import MazeAction, MazeEnv

try:
    # Create environment from Docker image
    env = MazeEnv.from_docker_image("maze_env-env:latest")

    # Reset to start a new episode
    result = env.reset()
    print(f"Start position: {result.observation.current_position}")
    print(f"Legal actions: {result.observation.legal_actions}")

    # Play until done
    while not result.done:
        action_id = result.observation.legal_actions[0]
        result = env.step(MazeAction(action=action_id))
        print(f"Position: {result.observation.current_position}")
        print(f"Reward: {result.reward}, Done: {result.done}")

finally:
    # Always clean up
    env.close()

That’s it! The MazeEnv.from_docker_image() method handles:

  • Starting the Docker container

  • Waiting for the server to be ready

  • Connecting to the environment

  • Container cleanup when you call close()

Building the Docker Image#

From the environment directory (envs/maze_env/):

docker build -t maze_env-env:latest -f server/Dockerfile .

Deploying to Hugging Face Spaces#

You can easily deploy your OpenEnv environment to Hugging Face Spaces using the openenv push command:

# From the environment directory (envs/maze_env/)
openenv push

# Or specify options
openenv push --namespace my-org --private

The openenv push command will:

  1. Validate that the directory is an OpenEnv environment (checks for openenv.yaml)

  2. Prepare a custom build for Hugging Face Docker space (enables web interface)

  3. Upload to Hugging Face (ensuring you’re logged in)

Prerequisites#

  • Authenticate with Hugging Face: The command will prompt for login if not already authenticated

Options#

  • --directory, -d: Directory containing the OpenEnv environment (defaults to current directory)

  • --repo-id, -r: Repository ID in format ‘username/repo-name’ (defaults to ‘username/env-name’ from openenv.yaml)

  • --base-image, -b: Base Docker image to use (overrides Dockerfile FROM)

  • --private: Deploy the space as private (default: public)

Examples#

# Push to your personal namespace (defaults to username/env-name from openenv.yaml)
openenv push

# Push to a specific repository
openenv push --repo-id my-org/maze-env

# Push with a custom base image
openenv push --base-image ghcr.io/meta-pytorch/openenv-base:latest

# Push as a private space
openenv push --private

# Combine options
openenv push --repo-id my-org/maze-env --base-image custom-base:latest --private

After deployment, your space will be available at: https://huggingface.co/spaces/<repo-id>

Running the Default Maze#

docker run -p 8000:8000 maze_env-env:latest

Environment Details#

Action#

MazeAction: Contains a single field

  • action (int) - Movement action

    • 0 = move up

    • 1 = move down

    • 2 = move left

    • 3 = move right

Observation#

MazeObservation: Per-step observation payload

  • current_position (List[int]) - Agent position as [col, row]

  • legal_actions (List[int]) - Valid actions from the current position

  • metadata (dict) - Extra info:

    • maze: 2D grid (0 = empty, 1 = wall)

    • status: “playing”, “win”, or “lose”

    • exit_cell: Exit position as [col, row]

    • step: Current step count

State#

MazeState: Server-side state snapshot

  • episode_id (str) - Unique identifier for the current episode

  • step_count (int) - Number of steps taken

  • done (bool) - Whether the episode has ended

  • current_position (List[int]) - Current agent position

  • exit_cell (List[int]) - Exit position

  • status (str) - “playing”, “win”, or “lose”

Reward#

The reward follows the underlying maze rules:

  • Small penalty for a move (-0.05)

  • Penalty for revisiting a cell (-0.25)

  • Penalty for invalid move (-0.75)

  • Reward for reaching the exit (+10.0)

Configuration#

Environment Variables#

This environment does not rely on environment variables. Customize the maze in code (see Development & Testing).

Advanced Usage#

Connecting to an Existing Server#

If you already have a Maze environment server running:

from maze_env import MazeAction, MazeEnv

# Connect to existing server
env = MazeEnv(base_url="http://localhost:8000")

# Use as normal
result = env.reset()
result = env.step(MazeAction(action=result.observation.legal_actions[0]))

# Close connection (does NOT stop the server)
env.close()

Connecting to HuggingFace Space#

from maze_env import MazeAction, MazeEnv

# Connect to remote Space
env = MazeEnv(base_url="https://your-username-maze-env.hf.space")

result = env.reset()
print(f"Position: {result.observation.current_position}")
print(f"Legal actions: {result.observation.legal_actions}")

result = env.step(MazeAction(action=result.observation.legal_actions[0]))
env.close()

Project Structure#

maze_env/
├── __init__.py            # Module exports
├── README.md              # This file
├── openenv.yaml           # OpenEnv manifest
├── pyproject.toml         # Project metadata and dependencies
├── client.py              # MazeEnv client implementation
├── models.py              # Action, Observation, and State models
└── server/
    ├── __init__.py        # Server module exports
    ├── maze.py            # Maze logic and rewards
    ├── maze_env_environment.py  # Core environment implementation
    ├── app.py             # FastAPI application
    └── Dockerfile         # Environment container

References#