Skip to main content

Super Mario Bros 2 (Europe) Gymnasium Environment

Project description

smb2-gym

Python PyPI License: MIT

A Gymnasium environment for Super Mario Bros 2 (Europe/Doki Doki Panic version) using TetaNES emulator Python bindings. Perfect for reinforcement learning experiments and research.

Features:

  • Curated action sets for faster training (simple, complex)
  • Comprehensive game state via info dict (50+ properties) and a semantic tile map
  • Multiple initialisation modes (character/level, custom ROMs, save states)
  • Human-playable interface with keyboard controls
  • Up to 350+ and 750+ FPS rendered and non-rendered respectively

Example gameplay showing Luigi in level 1-2 with semantic tile map visualisation

Installation

pip install smb2-gym

Quick Start

Basic Usage

from smb2_gym import SuperMarioBros2Env
from smb2_gym.app import InitConfig

# Create environment with character/level mode
config = InitConfig(level="1-1", character="luigi")
env = SuperMarioBros2Env(
    init_config=config,
    render_mode="human",     # "human" or None
    action_type="simple"     # "simple" (12), "complex" (16), or "all" (256)
)

# Reset environment
obs, info = env.reset()

# Run game loop
for _ in range(1000):
    action = env.action_space.sample()
    obs, reward, terminated, truncated, info = env.step(action)

    # Access game state from info dict
    print(f"Lives: {info['pc'].lives}, Hearts: {info['pc'].hearts}")
    print(f"Position: ({info['pos'].x_global}, {info['pos'].y_global})")

    if terminated or truncated:
        obs, info = env.reset()

env.close()

Initialisation Modes

from smb2_gym.app import InitConfig

# 1. Character/Level mode (default)
config = InitConfig(level="1-1", character="peach")

# 2. Built-in ROM variant mode
config = InitConfig(rom="prg0", save_state="level_1_1.sav")

# 3. Custom ROM mode
config = InitConfig(
    rom_path="/path/to/your/smb2.nes",
    save_state_path="/path/to/save.sav"  # Optional
)

Info Dict Structure

The info dict uses accessor objects for organized access to game state:

# Player Character state
info['pc'].lives
info['pc'].hearts
info['pc'].cherries
info['pc'].character  # 0=Mario, 1=Luigi, 2=Peach, 3=Toad

# Position
info['pos'].x_global
info['pos'].y_global
info['pos'].x_local
info['pos'].y_local

# Game state
info['game'].world
info['game'].level
info['game'].is_game_over

# Enemies/Objects/Projectiles (all sprites: enemies, items, projectiles, doors, etc.)
for enemy in info['enemies']:
    if enemy.is_visible:
        enemy.object_type   # EnemyId enum (SHYGUY_RED, BULLET, HEART, MUSHROOM, etc.)
        enemy.global_x
        enemy.global_y
        enemy.health
        enemy.x_velocity
        enemy.y_velocity

# Semantic tile map (15x16 structured array)
info['semantic']

Semantic Tile Map

The environment provides a semantic tile map representing the game world around the player as a structured 15x16 numpy array:

semantic_map = info['semantic']

# Access tile information
for row in range(15):
    for col in range(16):
        tile = semantic_map[row, col]

        tile_id = tile['tile_id']        # Raw BackgroundTile ID
        fine_type = tile['fine_type']    # Fine-grained FineTileType (SOLID, CLIMBABLE, etc.)
        coarse_type = tile['coarse_type'] # Coarse-grained CoarseTileType (TERRAIN, HAZARD, etc.)

        # RGB colour for visualisation
        r, g, b = tile['color_r'], tile['color_g'], tile['color_b']

The semantic map provides a structured representation of the visible game world, useful for pathfinding, collision avoidance, and spatial reasoning in RL agents.

Note: There is a plan to extend the semantic map or create a separate collision_map which has the collision properties for more detailed physical interaction information.

Example Custom Reward Function

from smb2_gym import SuperMarioBros2Env
from smb2_gym.app import InitConfig

class CustomSMB2Env(SuperMarioBros2Env):
    def step(self, action):
        obs, reward, terminated, truncated, info = super().step(action)

        # Custom reward based on x-position progress
        reward = info['pos'].x_global / 100.0

        # Bonus for collecting cherries
        reward += info['pc'].cherries * 10

        # Bonus for hearts
        reward += info['pc'].hearts * 5

        # Penalty for losing a life
        if info.get('life_lost'):
            reward -= 100

        return obs, reward, terminated, truncated, info

config = InitConfig(level="1-1", character="luigi")
env = CustomSMB2Env(init_config=config, action_type="simple")

Play as Human

The package includes a human-playable interface with multiple initialisation modes:

Character/Level Mode (Default)

smb2-play --level 1-1 --char luigi --scale 3

smb2-play --level 2-3 --char peach 

Built-in ROM Variant Mode

# Use specific ROM variant with save state
smb2-play --rom prg0_edited --save-state /path/to/save.sav

Custom ROM Mode

# Use your own ROM file
smb2-play --custom-rom /path/to/smb2.nes

# Use custom ROM with save state
smb2-play --custom-rom /path/to/smb2.nes --custom-state /path/to/save.sav

# Start from beginning without save state
smb2-play --custom-rom /path/to/smb2.nes --no-save-state

Controls

Primary Controls:

  • Arrow Keys: Move
  • Z: A button (Jump)
  • X: B button (Pick up/Throw)
  • Enter: Start
  • Right Shift: Select
  • P: Pause
  • R: Reset
  • ESC: Quit

Save States:

  • F5: Save state
  • F9: Load state

CLI Options

Character/Level Mode:

  • --level: Level to play (1-1 through 7-2, default: 1-1)
  • --char: Character (mario, luigi, peach, toad, default: luigi)

Built-in ROM Mode:

  • --rom: ROM variant (prg0, prg0_edited)
  • --save-state: Save state filename

Custom ROM Mode:

  • --custom-rom: Path to custom ROM file
  • --custom-state: Path to custom save state (optional)
  • --no-save-state: Start from beginning without loading save state

Display:

  • --scale: Display scale factor (1-4, default: 3)

Disclaimer

This project is for educational and research purposes only. Users must provide their own legally obtained ROM files.

Acknowledgements

This project builds upon invaluable reverse-engineering work from the SMB2 community:

These resources were essential for understanding the game's internals and implementing the state tracking features in this library.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

smb2_gym-0.2.14.tar.gz (916.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

smb2_gym-0.2.14-py3-none-any.whl (913.7 kB view details)

Uploaded Python 3

File details

Details for the file smb2_gym-0.2.14.tar.gz.

File metadata

  • Download URL: smb2_gym-0.2.14.tar.gz
  • Upload date:
  • Size: 916.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for smb2_gym-0.2.14.tar.gz
Algorithm Hash digest
SHA256 86781239dd1da3490494456b3abedcfd4ee81f484bd7d233f3182c20a241d6fb
MD5 fa61b383def3686662169b7be7c0007d
BLAKE2b-256 b141912ccdbd58fa7124c6d28bffefc5f0cf33d0340a0d5ca0cb70177cff8910

See more details on using hashes here.

File details

Details for the file smb2_gym-0.2.14-py3-none-any.whl.

File metadata

  • Download URL: smb2_gym-0.2.14-py3-none-any.whl
  • Upload date:
  • Size: 913.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for smb2_gym-0.2.14-py3-none-any.whl
Algorithm Hash digest
SHA256 2ba3df860c8b6a911f46735fe65d9dd2a7b2d9c417111928dc564268df972592
MD5 083f421560c1a28fa55e55f3d958fe5b
BLAKE2b-256 40f29ba640fb5dc17e3eb99673aad95105d251df4756aa531fcfd57635c75c40

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page