Super Mario Bros. for Gymnasium
Project description
gym-super-mario-bros
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:
- 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
- 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
- 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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0aa51763ed86fc29fdb0b8200a786112643c55de397709beb5fdc782e332ebf6
|
|
| MD5 |
25ee755eaf110fe508f68650cd4d2578
|
|
| BLAKE2b-256 |
f30089d84319a931eda768e41a3c56664bcc308c8319ddd9533b96c877dc1457
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gym_super_mario_bros-8.0.0.tar.gz -
Subject digest:
0aa51763ed86fc29fdb0b8200a786112643c55de397709beb5fdc782e332ebf6 - Sigstore transparency entry: 1566115608
- Sigstore integration time:
-
Permalink:
Kautenja/gym-super-mario-bros@cbbae307347f7e41f8d6b30ba8ff651e2db44159 -
Branch / Tag:
refs/tags/8.0.0 - Owner: https://github.com/Kautenja
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@cbbae307347f7e41f8d6b30ba8ff651e2db44159 -
Trigger Event:
release
-
Statement type:
File details
Details for the file gym_super_mario_bros-8.0.0-py3-none-any.whl.
File metadata
- Download URL: gym_super_mario_bros-8.0.0-py3-none-any.whl
- Upload date:
- Size: 200.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1999281e7891610755c5a0477e1c8cef5de8e784dccbb3c528e80aa75e37ba66
|
|
| MD5 |
d20f9341c43e148f331ae87feaffdc3d
|
|
| BLAKE2b-256 |
f103e3c208e64d157bd2800ad8db3d73449851a51a6496074f0d3de92cd34809
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gym_super_mario_bros-8.0.0-py3-none-any.whl -
Subject digest:
1999281e7891610755c5a0477e1c8cef5de8e784dccbb3c528e80aa75e37ba66 - Sigstore transparency entry: 1566115614
- Sigstore integration time:
-
Permalink:
Kautenja/gym-super-mario-bros@cbbae307347f7e41f8d6b30ba8ff651e2db44159 -
Branch / Tag:
refs/tags/8.0.0 - Owner: https://github.com/Kautenja
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@cbbae307347f7e41f8d6b30ba8ff651e2db44159 -
Trigger Event:
release
-
Statement type: