Python API#

RetroEnv#

The Python API consists primarily of retro.make(), retro.RetroEnv, and a few enums. The main function most users will want is retro.make().

retro.make(game, state=State.DEFAULT, inttype=retro.data.Integrations.DEFAULT, **kwargs)[source]#

Create a Gym environment for the specified game

class retro.RetroEnv(game, state=retro.State.DEFAULT, scenario=None, info=None, use_restricted_actions=retro.Actions.FILTERED, record=False, players=1, inttype=retro.data.Integrations.STABLE, obs_type=retro.Observations.IMAGE, render_mode='human')[source]#

Gym Retro environment class

Provides a Gym interface to classic video games

If you want to specify either the default state named in the game integration’s metadata.json or specify that you want to start from the initial power on state of the console, you can use the retro.State enum:

class retro.State(value)[source]#

Special values for setting the restart state of the environment. You can also specify a string that is the name of the .state file

DEFAULT = -1#

Start the game at the default savestate from metadata.json

NONE = 0#

Start the game at the power on screen for the emulator

Actions#

There are a few possible action spaces included with retro.RetroEnv:

class retro.Actions(value)[source]#

Different settings for the action space of the environment

ALL = 0#

MultiBinary action space with no filtered actions

DISCRETE = 2#

Discrete action space for filtered actions

MULTI_DISCRETE = 3#

MultiDiscete action space for filtered actions

You can also create your own action spaces derived from these. For an example, see discretizer.py. This file shows how to use retro.Actions.Discrete as well as how to make a custom wrapper that reduces the action space from 126 actions to 7

Observations#

The default observations are RGB images of the game, but you can view RAM values instead (often much smaller than the RGB images and also your agent can observe the game state more directly). If you want variable values, any variables defined in data.json will appear in the info dict after each step.

class retro.Observations(value)[source]#

Different settings for the observation space of the environment

IMAGE = 0#

Use RGB image observations

RAM = 1#

Use RAM observations where you can see the memory of the game instead of the screen

Multiplayer Environments#

A small number of games support multiplayer. To use this feature, pass players=<n> to retro.RetroEnv. Here is an example random agent that controls both paddles in Pong-Atari2600:

import retro


def main():
    env = retro.make(game="Pong-Atari2600", players=2)
    env.reset()
    while True:
        # action_space will by MultiBinary(16) now instead of MultiBinary(8)
        # the bottom half of the actions will be for player 1 and the top half for player 2
        obs, rew, done, info = env.step(env.action_space.sample())
        # rew will be a list of [player_1_rew, player_2_rew]
        # done and info will remain the same
        env.render()
        if done:
            env.reset()
    env.close()


if __name__ == "__main__":
    main()

Replay files#

Stable Retro can create .bk2 files which are recordings of an initial game state and a series of button presses. Because the emulators are deterministic, you will see the same output each time you play back this file. Because it only stores button presses, the file can be about 1000 times smaller than storing the full video.

In addition, if you wish to use the stored button presses for training, they may be useful. For example, there are replay files for each Sonic The Hedgehog level that were made available for the Stable Retro Contest.

You can create and view replay files using the The Integration UI (Game > Play Movie…). If you want to use replay files from Python, see the following sections.

Record#

If you have an agent playing a game, you can record the gameplay to a .bk2 file for later processing:

import retro

env = retro.make(game='Airstriker-Genesis', record='.')
env.reset()
while True:
    _, _, terminate, truncate, _ = env.step(env.action_space.sample())
    if terminate or truncate:
        break

Playback#

Given a .bk2 file you can load it in python and either play it back or use the actions for training.

import retro

movie = retro.Movie('Airstriker-Genesis-Level1-000000.bk2')
movie.step()

env = retro.make(
    game=movie.get_game(),
    state=None,
    # bk2s can contain any button presses, so allow everything
    use_restricted_actions=retro.Actions.ALL,
    players=movie.players,
)
env.initial_state = movie.get_state()
env.reset()

while movie.step():
    keys = []
    for p in range(movie.players):
        for i in range(env.num_buttons):
            keys.append(movie.get_key(i, p))
    env.step(keys)

Render to Video#

This requires ffmpeg to be installed and writes the output to the directory that the input file is located in.

python3 -m retro.scripts.playback_movie Airstriker-Genesis-Level1-000000.bk2