PyBoy

Technical overview. PyBoy emulates the Game Boy and Game Boy Color system, including the CPU, memory map, graphics, audio, cartridge hardware, and input devices. The main object coordinates these components while the game advances one frame at a time.

Using the API. Create a PyBoy instance with a ROM, call tick to advance emulation, and use its properties and methods to send input or inspect hardware state. Start with the small example below and add more control only when you need it.

Minimal example

This runs a game for a few seconds and then stops the emulator:

from pyboy import PyBoy

pyboy = PyBoy("game.gb")
pyboy.tick(60 * 5)
pyboy.stop()

The tick call advances the game by 300 frames. Use a loop when you want to inspect or control the game as it runs:

from pyboy import PyBoy

pyboy = PyBoy("game.gb", window="null")
pyboy.set_emulation_speed(0)

for _ in range(60):
    pyboy.tick()

print(pyboy.cartridge_title)
pyboy.stop()

Inspecting and controlling a game

The controller exposes higher-level helpers for input and lower-level views for the emulated hardware. This example presses a button, reads a memory address, and captures the current screen:

from pyboy import PyBoy

pyboy = PyBoy("game.gb", window="null")
pyboy.set_emulation_speed(0)

pyboy.button_press("a")
pyboy.tick(30)
pyboy.button_release("a")

print("Value at C000:", pyboy.memory[0xC000])
pyboy.screen.image.save("frame.png")
pyboy.stop()

For direct memory access, see the memory view page. For CPU registers, see the register file page. The remaining sections document the full PyBoy controller API.

class pyboy.PyBoy(gamerom, *, ram_file=None, rtc_file=None, window=defaults['window'], scale=defaults['scale'], symbols=None, bootrom=None, sound_volume=100, sound_emulated=True, sound_sample_rate=None, cgb=None, gameshark=None, no_input=False, log_level=defaults['log_level'], color_palette=defaults['color_palette'], cgb_color_palette=defaults['cgb_color_palette'], title_status=False, serial_shared_memory=None, serial_interrupt_based=False, sgb_border=False, **kwargs)[source]

Bases: object

__init__(gamerom, *, ram_file=None, rtc_file=None, window=defaults['window'], scale=defaults['scale'], symbols=None, bootrom=None, sound_volume=100, sound_emulated=True, sound_sample_rate=None, cgb=None, gameshark=None, no_input=False, log_level=defaults['log_level'], color_palette=defaults['color_palette'], cgb_color_palette=defaults['cgb_color_palette'], title_status=False, serial_shared_memory=None, serial_interrupt_based=False, sgb_border=False, **kwargs)[source]

PyBoy is loadable as an object in Python. This means, it can be initialized from another script, and be controlled and probed by the script. It is supported to spawn multiple emulators, just instantiate the class multiple times.

A range of methods are exposed, which should allow for complete control of the emulator. Please open an issue on GitHub, if other methods are needed for your projects. Take a look at the files in examples/ for a crude “bots”, which interact with the game.

Only the gamerom argument is required.

If gamerom is a filepath and ram_file or rtc_file is not provided, PyBoy looks for matching .ram and .rtc files next to the game ROM. If this is not wanted, provide file-like objects explicitly.

Example:

>>> pyboy = PyBoy('game_rom.gb')
>>> for _ in range(60): # Use 'while True:' for infinite
...     pyboy.tick()
True...
>>> pyboy.stop()
Parameters:
  • gamerom (str, os.PathLike, or binary file-like object) – Path to a Game Boy or Game Boy Color ROM, or an already-open binary file.

  • ram_file (binary file-like object or None) – Existing cartridge RAM data to load. When omitted for a path-based ROM, PyBoy looks for <gamerom>.ram; pass a destination to stop to save to a stream.

  • rtc_file (binary file-like object or None) – Existing cartridge RTC data to load. When omitted for a path-based ROM, PyBoy looks for <gamerom>.rtc; pass a destination to stop to save to a stream.

  • window (str) – Window backend: “SDL2”, “OpenGL”, “GLFW”, or “null”. “headless” and “dummy” are aliases for “null”.

  • scale (int) – Window scale factor; it does not affect API image dimensions.

  • symbols (str or os.PathLike or None) – Path to a .sym or .map symbol file.

  • bootrom (str or os.PathLike or None) – Path to a boot ROM to use instead of the built-in boot ROM.

  • sound_volume (int) – Sound volume from 0 to 100. Defaults to 100.

  • sound_emulated (bool) – Whether to emulate sound. Disabling it also disables sound sampling.

  • sound_sample_rate (int or None) – Positive sound sample rate in Hz. Defaults to 48,000 Hz.

  • cgb (bool or None) – Force Game Boy Color mode (True) or original Game Boy mode (False); None auto-detects the mode from the ROM and boot ROM.

  • gameshark (str or None) – Comma-separated GameShark codes to apply at startup.

  • no_input (bool) – Disable user input, mainly for autonomous use.

  • log_level (str) – One of “CRITICAL”, “ERROR”, “WARNING”, “INFO”, or “DEBUG”.

  • color_palette (sequence[int]) – Four 24-bit RGB colors for the DMG palette.

  • cgb_color_palette (sequence[sequence[int]]) – Three palettes of four 24-bit RGB colors, in background, object palette 0, and object palette 1 order.

  • title_status (bool) – Show performance status in the window title.

  • sgb_border (bool) – Enable SGB processing and border rendering. The border is drawn by the SDL2 and GLFW windows; other windows get SGB processing without border display.

  • serial_shared_memory (object or None) – Shared-memory link buffer used to connect two emulators. The object must provide read, write, and synchronize methods.

  • serial_interrupt_based (bool) – Use interrupt-based serial transfer when serial_shared_memory is set.

  • autopause (bool) – Enable auto-pausing when window looses focus [plugin: AutoPause]

  • breakpoints (str) – Add breakpoints on start-up (internal use) [plugin: DebugPrompt]

  • printer (bool) – Enable Game Boy Printer emulation [plugin: GameBoyPrinter]

  • printer_output (str) – Output directory for printed images (default: current directory) [plugin: GameBoyPrinter]

  • record_input (bool) – Record user input and save to a file (internal use) [plugin: RecordReplay]

  • rewind (bool) – Enable rewind function [plugin: Rewind]

Plugin-specific options are listed here and can be shown with pyboy --help.

screen

This attribute provides a pyboy.api.screen.Screen object for reading the screen buffer in a variety of formats.

It’s also here you can find the screen position (SCX, SCY, WX, WY) for each scan line in the screen buffer. See pyboy.api.screen.Screen.tilemap_position_list for more information.

Example:

>>> pyboy.screen.image.show()
>>> pyboy.screen.ndarray.shape
(144, 160, 4)
>>> pyboy.screen.raw_buffer_format
'RGBA'

NOTE: See PyBoy.sound to get the sound buffer.

Returns:

A Screen object with helper functions for reading the screen buffer.

Return type:

pyboy.api.screen.Screen

sgb

This attribute provides a pyboy.api.sgb.SGB object for accessing Super Game Boy features, such as SGB detection status and border control.

Returns:

An SGB object with helper functions for accessing Super Game Boy features.

Return type:

pyboy.api.sgb.SGB

sound

This attribute provides a pyboy.api.sound.Sound object for reading the sound buffer of the latest screen frame (see PyBoy.screen).

Example:

>>> pyboy.sound.ndarray.shape[1] # Number of stereo channels
2
>>> pyboy.sound.ndarray
array([[0, 0],
       [0, 0],
       ...
       [0, 0],
       [0, 0]], dtype=int8)
Returns:

A Sound object with helper functions for accessing the sound buffer.

Return type:

pyboy.api.sound.Sound

rumble

This attribute provides a pyboy.api.rumble.Rumble object for reading the current cartridge rumble state.

Returns:

Object exposing cartridge rumble support and state.

Return type:

pyboy.api.rumble.Rumble

memory

Provides a pyboy.PyBoyMemoryView object for reading and writing the memory space of the Game Boy.

For a more comprehensive description, see the pyboy.PyBoyMemoryView class.

Example:

>>> pyboy.memory[0x0000:0x0010] # Read 16 bytes from ROM bank 0
[49, 254, 255, 33, 0, 128, 175, 34, 124, 254, 160, 32, 249, 6, 48, 33]
>>> pyboy.memory[1, 0x2000] = 12 # Override address 0x2000 from ROM bank 1 with the value 12
>>> pyboy.memory[0xC000] = 1 # Write to address 0xC000 with value 1
register_file

Provides a pyboy.PyBoyRegisterFile object for reading and writing the CPU registers of the Game Boy.

The register file is best used inside the callback registered with PyBoy.hook_register, as PyBoy.tick doesn’t return at a specific point.

For a more comprehensive description, see the pyboy.PyBoyRegisterFile class.

Example:

>>> def my_callback(register_file):
...     print("Register A:", register_file.A)
>>> pyboy.hook_register(0, 0x100, my_callback, pyboy.register_file)
>>> pyboy.tick(70)
Register A: 1
True
memory_scanner

Provides a pyboy.api.memory_scanner.MemoryScanner object for locating addresses of interest in the memory space of the Game Boy. This might require some trial and error. Values can be represented in memory in surprising ways.

_Open an issue on GitHub if you need finer control, and we will take a look at it._

Example:

>>> pyboy.memory[0xC000] = 4
>>> pyboy.memory_scanner.scan_memory(4, start_addr=0xC000, end_addr=0xC000)
[49152]
>>> pyboy.memory[0xC000] = 8
>>> from pyboy.api.memory_scanner import DynamicComparisonType
>>> addresses = pyboy.memory_scanner.rescan_memory(8, DynamicComparisonType.MATCH)
>>> print(addresses)
[49152]
tilemap_background

The Game Boy uses two tile maps at the same time to draw graphics on the screen. This attribute provides the background tile map. The game chooses whether it uses the low or the high tile map.

Read more details about it, in the Pan Docs.

Example:

>>> pyboy.tilemap_background[8,8]
1
>>> pyboy.tilemap_background[7:12,8]
[0, 1, 0, 1, 0]
>>> pyboy.tilemap_background[7:12,8:11]
[[0, 1, 0, 1, 0], [0, 2, 3, 4, 5], [0, 0, 6, 0, 0]]
Returns:

A TileMap object for the tile map.

Return type:

pyboy.api.tilemap.TileMap

tilemap_window

The Game Boy uses two tile maps at the same time to draw graphics on the screen. This attribute provides the window tile map. The game chooses whether it uses the low or the high tile map.

Read more details about it, in the Pan Docs.

Example:

>>> pyboy.tilemap_window[8,8]
1
>>> pyboy.tilemap_window[7:12,8]
[0, 1, 0, 1, 0]
>>> pyboy.tilemap_window[7:12,8:11]
[[0, 1, 0, 1, 0], [0, 2, 3, 4, 5], [0, 0, 6, 0, 0]]
Returns:

A TileMap object for the tile map.

Return type:

pyboy.api.tilemap.TileMap

cartridge_title

The title bytes read from the cartridge header up to the first NUL. The header field overlaps other metadata; PyBoy reads up to 14 bytes for CGB-compatible cartridges or 15 bytes otherwise.

Example:

>>> pyboy.cartridge_title # Title of PyBoy's default ROM
'DEFAULT-ROM'
Returns:

Game title

Return type:

str

game_wrapper

Provides an instance of a game-specific or generic wrapper. The game is detected by the cartridge’s hard-coded game title (see pyboy.PyBoy.cartridge_title).

If a game-specific wrapper is not found, a generic wrapper will be returned.

To get more information, find the wrapper for your game in Plugins.

Example:

>>> pyboy.game_wrapper.start_game()
>>> pyboy.game_wrapper.reset_game()
Returns:

A game-specific wrapper object.

Return type:

pyboy.plugins.base_plugin.PyBoyGameWrapper

gameshark

Provides an instance of the pyboy.api.gameshark.GameShark handler. This allows you to inject GameShark-based cheat codes.

Example:

>>> pyboy.gameshark.add("010138CD")
>>> pyboy.gameshark.remove("010138CD")
>>> pyboy.gameshark.clear_all()
tick(count=1, render=True, sound=True)[source]

Progresses the emulator ahead by count frame(s).

To run the emulator in real time, it needs to process about 60 frames per second. This function blocks for roughly 16.7 ms per frame unless you change the limit with PyBoy.set_emulation_speed.

If you need finer control than 1 frame, have a look at PyBoy.hook_register to inject code at a specific point in the game.

Setting render to True will make PyBoy render the screen for the last frame of this tick. This can be seen as a type of “frameskipping” optimization.

For AI training, it is advisable to use as high a count as practical, as it will otherwise reduce performance substantially. While setting render to False, you can still access the PyBoy.game_area to get a simpler representation of the game.

If render was enabled, use pyboy.api.screen.Screen to get a NumPy buffer or raw memory buffer. Set sound to False to skip sampling audio for the final frame in this call.

Example:

>>> pyboy.tick() # Progress 1 frame with rendering
True
>>> pyboy.tick(1) # Progress 1 frame with rendering
True
>>> pyboy.tick(60, False) # Progress 60 frames *without* rendering
True
>>> pyboy.tick(60, True) # Progress 60 frames and render *only the last frame*
True
>>> for _ in range(60): # Progress 60 frames and render every frame
...     if not pyboy.tick(1, True):
...         break
>>>
Parameters:
  • count (int) – Non-negative number of frames to process. Defaults to 1.

  • render (bool) – Whether to render the final frame. Defaults to True.

  • sound (bool) – Whether to sample audio for the final frame. Defaults to True.

Returns:

False if emulation has ended; otherwise True.

Return type:

bool

Raises:

PyBoyInvalidInputException – If count is not a non-negative integer.

stop(save=True, ram_file=None, rtc_file=None)[source]

Gently stops the emulator and all sub-modules.

If save is True, battery-backed cartridge RAM and RTC data are written to the supplied file-like objects, or to .ram and .rtc files next to a path-based ROM when no objects are supplied. For a ROM opened from a file-like object, provide ram_file and rtc_file destinations as needed.

Example:

>>> pyboy.stop() # Stop emulator and save game progress (cartridge RAM)
>>> pyboy.stop(False) # Stop emulator and discard game progress (cartridge RAM)
>>> import io
>>> sav = io.BytesIO()
>>> pyboy.stop(ram_file=sav) # Stop emulator and save game progress (cartridge RAM)
Parameters:
  • save (bool) – Whether to save battery-backed cartridge data while stopping. Defaults to True.

  • ram_file (binary file-like object or None) – Destination for cartridge RAM data.

  • rtc_file (binary file-like object or None) – Destination for RTC data, if the cartridge has an RTC.

button(input, delay=1)[source]

Send input to PyBoy in the form of “a”, “b”, “start”, “select”, “left”, “right”, “up” and “down”.

The button will automatically be released at the following call to PyBoy.tick.

Example:

>>> pyboy.button('a') # Press button 'a' and release after `pyboy.tick()`
>>> pyboy.tick() # Button 'a' pressed
True
>>> pyboy.tick() # Button 'a' released
True
>>> pyboy.button('a', 3) # Press button 'a' and release after 3 `pyboy.tick()`
>>> pyboy.tick() # Button 'a' pressed
True
>>> pyboy.tick() # Button 'a' still pressed
True
>>> pyboy.tick() # Button 'a' still pressed
True
>>> pyboy.tick() # Button 'a' released
True
Parameters:
  • input (str) – button to press

  • delay (int, optional) – Number of frames to delay the release. Defaults to 1

button_press(input)[source]

Send input to PyBoy in the form of “a”, “b”, “start”, “select”, “left”, “right”, “up” and “down”.

The button will remain press until explicitly released with PyBoy.button_release or PyBoy.send_input.

Example:

>>> pyboy.button_press('a') # Press button 'a' and keep pressed after `PyBoy.tick()`
>>> pyboy.tick() # Button 'a' pressed
True
>>> pyboy.tick() # Button 'a' still pressed
True
>>> pyboy.button_release('a') # Release button 'a' on next call to `PyBoy.tick()`
>>> pyboy.tick() # Button 'a' released
True
Parameters:

input (str) – button to press

button_release(input)[source]

Send input to PyBoy in the form of “a”, “b”, “start”, “select”, “left”, “right”, “up” and “down”.

This will release a button after a call to PyBoy.button_press or PyBoy.send_input.

Example:

>>> pyboy.button_press('a') # Press button 'a' and keep pressed after `PyBoy.tick()`
>>> pyboy.tick() # Button 'a' pressed
True
>>> pyboy.tick() # Button 'a' still pressed
True
>>> pyboy.button_release('a') # Release button 'a' on next call to `PyBoy.tick()`
>>> pyboy.tick() # Button 'a' released
True
Parameters:

input (str) – button to release

send_input(event, delay=0)[source]

Send a single input to control the emulator. This is both Game Boy buttons and emulator controls. See pyboy.utils.WindowEvent for which events to send.

Consider using PyBoy.button instead for easier access.

Example:

>>> from pyboy.utils import WindowEvent
>>> pyboy.send_input(WindowEvent.PRESS_BUTTON_A) # Press button 'a' and keep pressed after `PyBoy.tick()`
>>> pyboy.tick() # Button 'a' pressed
True
>>> pyboy.tick() # Button 'a' still pressed
True
>>> pyboy.send_input(WindowEvent.RELEASE_BUTTON_A) # Release button 'a' on next call to `PyBoy.tick()`
>>> pyboy.tick() # Button 'a' released
True

And even simpler with delay:

>>> from pyboy.utils import WindowEvent
>>> pyboy.send_input(WindowEvent.PRESS_BUTTON_A) # Press button 'a' and keep pressed after `PyBoy.tick()`
>>> pyboy.send_input(WindowEvent.RELEASE_BUTTON_A, 2) # Release button 'a' on third call to `PyBoy.tick()`
>>> pyboy.tick() # Button 'a' pressed
True
>>> pyboy.tick() # Button 'a' still pressed
True
>>> pyboy.tick() # Button 'a' released
True
Parameters:
  • event (int) – An event constant from pyboy.utils.WindowEvent.

  • delay (int) – 0 to queue the event immediately, or a positive number of frames to delay it. Defaults to 0.

save_state(file_like_object)[source]

Saves the complete state of the emulator. It can be called at any time, and enable you to revert any progress in a game.

You can either save it to a file, or in-memory. The following two examples will provide the file handle in each case. Remember to seek the in-memory buffer to the beginning before calling PyBoy.load_state:

>>> # Save to file
>>> with open("state_file.state", "wb") as f:
...     pyboy.save_state(f)
>>>
>>> # Save to memory
>>> import io
>>> with io.BytesIO() as f:
...     f.seek(0)
...     pyboy.save_state(f)
0
Parameters:

file_like_object (io.BufferedIOBase) – A file-like object for which to write the emulator state.

load_state(file_like_object)[source]

Restores the complete state of the emulator. It can be called at any time, and enable you to revert any progress in a game.

You can either load it from a file, or from memory. See PyBoy.save_state for how to save the state, before you can load it here.

To load a file, remember to load it as bytes:

>>> # Load file
>>> with open("state_file.state", "rb") as f:
...     pyboy.load_state(f)
>>>
Parameters:

file_like_object (io.BufferedIOBase) – A file-like object for which to read the emulator state.

game_area_dimensions(x, y, width, height, follow_scrolling=True)[source]

If using the generic game wrapper (see pyboy.PyBoy.game_wrapper), you can use this to set the section of the tilemaps to extract. This will default to the entire tilemap.

Example:

>>> pyboy.game_wrapper.shape
(32, 32)
>>> pyboy.game_area_dimensions(2, 2, 10, 18, False)
>>> pyboy.game_wrapper.shape
(10, 18)
Parameters:
  • x (int) – Left column of the game area in tile-map coordinates.

  • y (int) – Top row of the game area in tile-map coordinates.

  • width (int) – Width of the game area in tiles.

  • height (int) – Height of the game area in tiles.

  • follow_scrolling (bool) – Whether to adjust the area for SCX/SCY scrolling.

game_area_collision()[source]

Some game wrappers define a collision map. Check if your game wrapper has this feature implemented: Plugins.

The output will be unique for each game wrapper.

Example:

>>> # This example show nothing, but a supported game will
>>> pyboy.game_area_collision()
array([[0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=uint32)
Returns:

A two-dimensional collision map. Only game wrappers that implement collision data support

this method.

Return type:

numpy.ndarray

Raises:

AttributeError – If the active game wrapper does not implement collision data.

game_area_mapping(mapping, sprite_offset=0)[source]

Define custom mappings for tile identifiers in the game area.

Example of custom mapping:

>>> from pyboy.api.constants import TILES
>>> mapping = [x for x in range(TILES)] # 1:1 mapping of 384 tiles
>>> mapping[0] = 0 # Map tile identifier 0 -> 0
>>> mapping[1] = 0 # Map tile identifier 1 -> 0
>>> mapping[2] = 0 # Map tile identifier 2 -> 0
>>> mapping[3] = 0 # Map tile identifier 3 -> 0
>>> pyboy.game_area_mapping(mapping, 1000)

Some game wrappers will supply mappings as well. See the specific documentation for your game wrapper: Plugins.

>>> pyboy.game_area_mapping(pyboy.game_wrapper.mapping_one_to_one, 0)
Parameters:
  • mapping (list, ndarray, or None) – A mapping with 384 (DMG) or 768 (CGB) entries. None resets to an identity mapping.

  • sprite_offset (int) – Value added to mapped tile IDs used for sprites. Defaults to 0.

game_area()[source]

Use this method to get a matrix of the “game area” of the screen. This view is simplified to be perfect for machine learning applications.

The layout will vary from game to game. Below is an example from Tetris:

Example:

>>> pyboy.game_area()
array([[ 47,  47,  47,  47,  47,  47,  47,  47,  47,  47],
       [ 47,  47,  47,  47,  47,  47,  47,  47,  47,  47],
       [ 47,  47,  47,  47,  47,  47,  47,  47,  47,  47],
       [ 47,  47,  47,  47,  47,  47,  47,  47,  47,  47],
       [ 47,  47,  47, 130, 130,  47,  47,  47,  47,  47],
       [ 47,  47,  47,  47, 130, 130,  47,  47,  47,  47],
       [ 47,  47,  47,  47,  47,  47,  47,  47,  47,  47],
       [ 47,  47,  47,  47,  47,  47,  47,  47,  47,  47],
       [ 47,  47,  47,  47,  47,  47,  47,  47,  47,  47],
       [ 47,  47,  47,  47,  47,  47,  47,  47,  47,  47],
       [ 47,  47,  47,  47,  47,  47,  47,  47,  47,  47],
       [ 47,  47,  47,  47,  47,  47,  47,  47,  47,  47],
       [ 47,  47,  47,  47,  47,  47,  47,  47,  47,  47],
       [ 47,  47,  47,  47,  47,  47,  47,  47,  47,  47],
       [ 47,  47,  47,  47,  47,  47,  47,  47,  47,  47],
       [ 47,  47,  47,  47,  47,  47,  47,  47,  47,  47],
       [ 47,  47,  47,  47,  47,  47,  47,  47,  47,  47],
       [ 47,  47,  47,  47,  47,  47,  47,  47,  47,  47]], dtype=uint32)

If you want a “compressed”, “minimal” or raw mapping of tiles, you can change the mapping using pyboy.PyBoy.game_area_mapping. Either you’ll have to supply your own mapping, or you can find one that is built-in with the game wrapper plugin for your game. See pyboy.PyBoy.game_area_mapping.

Returns:

Two-dimensional array of mapped tile identifiers with dtype numpy.uint32 and shape (game_wrapper.shape[1], game_wrapper.shape[0]), i.e. (height, width).

Return type:

numpy.ndarray

set_color_palette(palette)[source]

Set the color palette of DMG games.

Example:

>>> pyboy.set_color_palette((0x9BBC0F, 0x8BAC0F, 0x306230, 0x0F380F))
Parameters:

palette (sequence[int]) – Four 24-bit RGB colors, ordered from lightest to darkest.

Raises:

PyBoyInvalidOperationException – If PyBoy is running in CGB mode.

printer_image()[source]

Returns the last image printed by the Game Boy Printer, if printer emulation is enabled.

Returns:

The last printed image as a PIL Image, or None if no image has been printed or the printer is not enabled.

Return type:

PIL.Image.Image or None

set_emulation_speed(target_speed)[source]

Set the target emulation speed. Timing may become less accurate at high target speeds.

The speed is defined as a multiple of real-time. I.e target_speed=2 is double speed.

A target_speed of 0 means unlimited. I.e. fastest possible execution.

Due to backwards compatibility, the null window starts at unlimited speed (i.e. target_speed=0), while others start at realtime (i.e. target_speed=1).

Example:

>>> pyboy.tick() # Delays 16.67ms
True
>>> pyboy.set_emulation_speed(0) # Disable limit
>>> pyboy.tick() # As fast as possible
True
Parameters:

target_speed (int) – Target speed as a multiple of real time. Use 0 for unlimited speed, or a positive integer for a real-time multiple.

symbol_lookup(symbol)[source]

Look up a symbol from the loaded .sym or .map file.

This can be useful in combination with PyBoy.memory or even PyBoy.hook_register.

See PyBoy.hook_register for how to load symbol into PyBoy.

Example:

>>> # Directly
>>> pyboy.memory[pyboy.symbol_lookup("Tileset")]
0
>>> # By bank and address
>>> bank, addr = pyboy.symbol_lookup("Tileset")
>>> pyboy.memory[bank, addr]
0
>>> pyboy.memory[bank, addr:addr+10]
[0, 0, 0, 0, 0, 0, 102, 102, 102, 102]
Parameters:

symbol (str) – Symbol name to look up.

Returns:

ROM/RAM bank and address.

Return type:

tuple[int, int]

Raises:

ValueError – If the symbol is not found in the loaded symbol files.

hook_register(bank, addr, callback, context)[source]

Adds a hook into a specific bank and memory address. When the Game Boy executes this address, the provided callback function will be called.

By providing an object as context, you can later get access to information inside and outside of the callback.

Example:

>>> context = "Hello from hook"
>>> def my_callback(context):
...     print(context)
>>> pyboy.hook_register(0, 0x100, my_callback, context)
>>> pyboy.tick(70)
Hello from hook
True

If a symbol file is loaded, this function can also automatically resolve a bank and address from a symbol. To enable this, you’ll need to place a .sym file next to your ROM, or provide it using: PyBoy(..., symbols="game_rom.gb.sym").

Then provide None for bank and the symbol for addr to trigger the automatic lookup.

Example:

>>> # Continued example above
>>> pyboy.hook_register(None, "Main.move", lambda x: print(x), "Hello from hook2")
>>> pyboy.tick(81)
Hello from hook2
True

NOTE:

Don’t register hooks to something that isn’t executable (graphics data etc.). This will cause your game to show weird behavior or crash. Hooks are installed by replacing the instruction at the bank and address with a special opcode (0xDB). If the address is read by the game instead of executed as code, this value will be read instead.

Parameters:
  • bank (int or None) – ROM or RAM bank (None for symbol lookup)

  • addr (int or str) – Address in the Game Boy’s address space (str for symbol lookup)

  • callback (func) – A function which takes context as argument

  • context (object) – Argument to pass to callback when hook is called

hook_deregister(bank, addr)[source]

Remove a previously registered hook from a specific bank and memory address.

Example:

>>> context = "Hello from hook"
>>> def my_callback(context):
...     print(context)
>>> pyboy.hook_register(0, 0x2000, my_callback, context)
>>> pyboy.hook_deregister(0, 0x2000)

This function can also deregister a hook based on a symbol. See PyBoy.hook_register for details.

Example:

>>> pyboy.hook_register(None, "Main", lambda x: print(x), "Hello from hook")
>>> pyboy.hook_deregister(None, "Main")
Parameters:
  • bank (int or None) – ROM or RAM bank (None for symbol lookup)

  • addr (int or str) – Address in the Game Boy’s address space (str for symbol lookup)

get_sprite(sprite_index)[source]

Provides a pyboy.api.sprite.Sprite object, which makes the OAM data more presentable. The given index corresponds to index of the sprite in the “Object Attribute Memory” (OAM).

The Game Boy supports 40 sprites in total. Read more in the Pan Docs: OAM.

>>> s = pyboy.get_sprite(12)
>>> s
Sprite [12]: Position: (-8, -16), Shape: (8, 8), Tiles: (Tile: 0), On screen: False
>>> s.on_screen
False
>>> s.tiles
[Tile: 0]
Parameters:

sprite_index (int) – Sprite index from 0 to 39.

Returns:

Sprite corresponding to the given index.

Return type:

pyboy.api.sprite.Sprite

Raises:

PyBoyOutOfBoundsException – If sprite_index is outside 0 to 39.

get_sprite_by_tile_identifier(tile_identifiers, on_screen=True)[source]

Provided a list of tile identifiers, this function will find all occurrences of sprites using the tile identifiers and return the sprite indexes where each identifier is found. Use the sprite indexes in the pyboy.PyBoy.get_sprite function to get a pyboy.api.sprite.Sprite object.

Example:

>>> print(pyboy.get_sprite_by_tile_identifier([43, 123]))
[[0, 2, 4], []]

Meaning, that tile identifier 43 is found at the sprite indexes: 0, 2, and 4, while tile identifier 123 was not found anywhere.

Parameters:
  • tile_identifiers (list[int]) – Tile identifiers to search for.

  • on_screen (bool) – Require that the matched sprite is on screen

Returns:

Sprite indices grouped by the corresponding input tile identifier.

Return type:

list[list[int]]

get_tile(identifier)[source]

The Game Boy can have 384 tiles loaded in memory at once (768 for Game Boy Color). Use this method to get a pyboy.api.tile.Tile-object for given identifier.

The identifier is a PyBoy construct, which unifies two different scopes of indexes in the Game Boy hardware. See the pyboy.api.tile.Tile object for more information.

Example:

>>> t = pyboy.get_tile(2)
>>> t
Tile: 2
>>> t.shape
(8, 8)
Parameters:

identifier (int) – Tile identifier from 0 to 383 on DMG or 0 to 767 on CGB.

Returns:

A Tile object for the given identifier.

Return type:

pyboy.api.tile.Tile

Raises:

PyBoyOutOfBoundsException – If identifier is outside the available tile range.

rtc_lock_experimental(enable)[source]

WARN: This is an experimental API and is subject to change.

Lock the Real Time Clock (RTC) of a supporting cartridge. It might be advantageous to lock the RTC when training an AI in games that use it to change behavior (i.e. day and night).

The first time the game is turned on, an .rtc file is created with the current time. This is the epoch for the RTC. When using rtc_lock_experimental, the RTC will always report this point in time. If you let the game progress first, before using rtc_lock_experimental, the internal clock will move backwards and might corrupt the game.

Example:

>>> pyboy = PyBoy('game_rom.gb')
>>> pyboy.rtc_lock_experimental(True) # RTC will not progress

WARN: This is an experimental API and is subject to change.

Parameters:

enable (bool) – True to lock RTC, False to operate normally