Skip to main content

Super Mario Bros. for Gymnasium

Project description

gym-super-mario-bros

BuildStatus PackageVersion PythonVersion Stable Format License

Mario

A Gymnasium environment for Super Mario Bros. & Super Mario Bros. 2 (Lost Levels) on The Nintendo Entertainment System (NES) using the nes-py emulator.

gym-super-mario-bros targets Gymnasium's modern reset, step, render-mode, and truncation semantics. It currently supports CPython 3.13 and 3.14 in CI.

Installation

The preferred installation of gym-super-mario-bros is from pip:

pip install gym-super-mario-bros

Python 3.13 or newer is required. The supported CI targets are CPython 3.13 and 3.14.

Because gym-super-mario-bros depends on the native nes-py emulator, Linux GLIBCXX_* loader errors and Windows compiler-toolchain failures are usually nes-py installation/runtime issues rather than wrapper bugs. See the nes-py installation notes for the current compiler and runtime expectations.

Usage

Python

You must import gym_super_mario_bros before trying to make an environment. This is because Gymnasium environments are registered at runtime. By default, gym_super_mario_bros environments use the full NES action space of 256 discrete actions. To constrain this, gym_super_mario_bros.actions provides three actions lists (RIGHT_ONLY, SIMPLE_MOVEMENT, and COMPLEX_MOVEMENT) for the nes_py.wrappers.JoypadSpace wrapper. See gym_super_mario_bros/actions.py for a breakdown of the legal actions in each of these three lists.

import gymnasium as gym
from nes_py.wrappers import JoypadSpace
import gym_super_mario_bros
from gym_super_mario_bros.actions import SIMPLE_MOVEMENT

env = gym.make('SuperMarioBros-v0', render_mode='human')
env = JoypadSpace(env, SIMPLE_MOVEMENT)

done = True
for step in range(5000):
    if done:
        state, info = env.reset(seed=123)
    state, reward, terminated, truncated, info = env.step(env.action_space.sample())
    done = terminated or truncated
    env.render()

env.close()

NOTE: gym_super_mario_bros.make is just an alias to gymnasium.make for convenience after gym_super_mario_bros is imported.

NOTE: registered environments use Gymnasium's TimeLimit wrapper with max_episode_steps=9999999 to preserve the historical cap while allowing the game logic to end normal episodes with terminated=True. Passing a shorter max_episode_steps to gymnasium.make() is the supported way to test or train with external time truncation, which returns truncated=True.

NOTE: remove calls to render in training code for a nontrivial speedup.

Command Line

gym_super_mario_bros features a command line interface for playing environments using either the keyboard, or uniform random movement.

python -m gym_super_mario_bros --env <environment ID> --mode <human|random>
gym_super_mario_bros --env <environment ID> --mode <human|random>

NOTE: by default, -e is set to SuperMarioBros-v0 and -m is set to human, --actionspace/-a is set to nes, and rendering is enabled.

Human keyboard play opens a graphical window:

gym_super_mario_bros --env SuperMarioBros-v0 --mode human --actionspace simple

Random play can be rendered or run headlessly. Use --seed to seed the first environment reset:

gym_super_mario_bros --mode random --steps 1000 --no-render --seed 123

Use --actionspace/-a to select nes, right, simple, or complex. Human mode requires rendering, so --mode human --no-render is rejected.

Print the CLI help with:

python -m gym_super_mario_bros --help

NOTE: SuperMarioBrosRandomStages-* support the --stages/-S flag for supplying the set of stages to sample from like -S 1-4 2-4 3-4 4-4.

Environments

These environments allow 3 attempts (lives) to make it through the 32 stages in the game. The environments only send reward-able game-play frames to agents; No cut-scenes, loading screens, etc. are sent from the NES emulator to an agent nor can an agent perform actions during these instances. If a cut-scene is not able to be skipped by hacking the NES's RAM, the environment will lock the Python process until the emulator is ready for the next action.

Environment Game ROM Screenshot
SuperMarioBros-v0 SMB standard
SuperMarioBros-v1 SMB downsample
SuperMarioBros-v2 SMB pixel
SuperMarioBros-v3 SMB rectangle
SuperMarioBros2-v0 SMB2 standard
SuperMarioBros2-v1 SMB2 downsample

Individual Stages

These environments allow a single attempt (life) to make it through a single stage of the game.

Use the template

SuperMarioBros-<world>-<stage>-v<version>

where:

  • <world> is a number in {1, 2, 3, 4, 5, 6, 7, 8} indicating the world
  • <stage> is a number in {1, 2, 3, 4} indicating the stage within a world
  • <version> is a number in {0, 1, 2, 3} specifying the ROM mode to use
    • 0: standard ROM
    • 1: downsampled ROM
    • 2: pixel ROM
    • 3: rectangle ROM

For example, to play 4-2 on the downsampled ROM, you would use the environment id SuperMarioBros-4-2-v1.

Random Stage Selection

The random stage selection environment randomly selects a stage and allows a single attempt to clear it. Upon a death and subsequent call to reset the environment randomly selects a new stage. This is only available for the standard Super Mario Bros. game, not Lost Levels (at the moment). To use these environments, append RandomStages to the SuperMarioBros id. For example, to use the standard ROM with random stage selection use SuperMarioBrosRandomStages-v0. To seed the random stage selection pass the seed keyword argument to the reset method directly like reset(seed=222).

In addition to randomly selecting any of the 32 original stages, a subset of user-defined stages can be specified to limit the random choice of stages to a specific subset. For example, the stage selector could be limited to only sample castle stages, water levels, underground, and more.

To specify a default subset of stages to randomly sample from, create a list of each stage to allow to be sampled and pass that list to the gymnasium.make() function. For example:

gym.make('SuperMarioBrosRandomStages-v0', stages=['1-4', '2-4', '3-4', '4-4'])

The example above will sample a random stage from 1-4, 2-4, 3-4, and 4-4 upon every call to reset. A reset call can also override the subset for one episode:

state, info = env.reset(seed=222, options={'stages': ['4-2']})

Step

Info about the rewards and info returned by the step method.

Reward Function

The reward function assumes the objective of the game is to move as far right as possible (increase the agent's x value), as fast as possible, without dying. To model this game, three separate variables compose the reward:

  1. v: the difference in agent x values between states
    • in this case this is instantaneous velocity for the given step
    • v = x1 - x0
      • x0 is the x position before the step
      • x1 is the x position after the step
    • moving right ⇔ v > 0
    • moving left ⇔ v < 0
    • not moving ⇔ v = 0
  2. c: the difference in the game clock between frames
    • the penalty prevents the agent from standing still
    • c = c0 - c1
      • c0 is the clock reading before the step
      • c1 is the clock reading after the step
    • no clock tick ⇔ c = 0
    • clock tick ⇔ c < 0
  3. d: a death penalty that penalizes the agent for dying in a state
    • this penalty encourages the agent to avoid death
    • alive ⇔ d = 0
    • dead ⇔ d = -15

r = v + c + d

The reward is clipped into the range (-15, 15).

info dictionary

The info dictionary returned by the step method contains the following keys:

Key Type Description
coins int The number of collected coins
flag_get bool True if Mario reached a flag or ax
life int The number of lives left, i.e., {3, 2, 1}
score int The cumulative in-game score
stage int The current stage, i.e., {1, ..., 4}
status str Mario's status, i.e., {'small', 'tall', 'fireball'}
time int The time left on the clock
world int The current world, i.e., {1, ..., 8}
x_pos int Mario's x position in the stage (from the left)
y_pos int Mario's y position in the stage (from the bottom)

Publishing

PyPI releases are published by the Publish to PyPI GitHub Actions workflow through PyPI trusted publishing, not by local twine credentials. Configure the PyPI project publisher with owner Kautenja, repository gym-super-mario-bros, workflow filename publish.yml, and environment pypi. Publish a release by pushing a tag that matches pyproject.toml's version, with or without a leading v, and then creating the corresponding GitHub release so the workflow can build and upload the distribution artifacts.

Citation

Please cite gym-super-mario-bros if you use it in your research.

@misc{gym-super-mario-bros,
  author = {Christian Kauten},
  howpublished = {GitHub},
  title = {{S}uper {M}ario {B}ros for {O}pen{AI} {G}ym},
  URL = {https://github.com/Kautenja/gym-super-mario-bros},
  year = {2018},
}

Project details


Release history Release notifications | RSS feed

Download files

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

Source Distribution

gym_super_mario_bros-8.0.0.tar.gz (202.9 kB view details)

Uploaded Source

Built Distribution

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

gym_super_mario_bros-8.0.0-py3-none-any.whl (200.9 kB view details)

Uploaded Python 3

File details

Details for the file gym_super_mario_bros-8.0.0.tar.gz.

File metadata

  • Download URL: gym_super_mario_bros-8.0.0.tar.gz
  • Upload date:
  • Size: 202.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for gym_super_mario_bros-8.0.0.tar.gz
Algorithm Hash digest
SHA256 0aa51763ed86fc29fdb0b8200a786112643c55de397709beb5fdc782e332ebf6
MD5 25ee755eaf110fe508f68650cd4d2578
BLAKE2b-256 f30089d84319a931eda768e41a3c56664bcc308c8319ddd9533b96c877dc1457

See more details on using hashes here.

Provenance

The following attestation bundles were made for gym_super_mario_bros-8.0.0.tar.gz:

Publisher: publish.yml on Kautenja/gym-super-mario-bros

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gym_super_mario_bros-8.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for gym_super_mario_bros-8.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1999281e7891610755c5a0477e1c8cef5de8e784dccbb3c528e80aa75e37ba66
MD5 d20f9341c43e148f331ae87feaffdc3d
BLAKE2b-256 f103e3c208e64d157bd2800ad8db3d73449851a51a6496074f0d3de92cd34809

See more details on using hashes here.

Provenance

The following attestation bundles were made for gym_super_mario_bros-8.0.0-py3-none-any.whl:

Publisher: publish.yml on Kautenja/gym-super-mario-bros

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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