Screen

Technical overview. The Game Boy LCD renders a 160 by 144 pixel image. PyBoy keeps the current frame in a 32-bit RGBA buffer, which is updated as emulation advances.

Using the API. Screen exposes the current frame as a Pillow image, a NumPy array, or the raw buffer, together with its dimensions and format. The image and array reference live data, so copy them when a frame must be kept after the next call to tick.

This class gives access to the frame buffer and other screen parameters of PyBoy.

class pyboy.api.screen.Screen(mb)[source]

Bases: object

As part of the emulation, we generate a screen buffer in 32-bit RGBA format. This class has several helper methods to make it possible to read this buffer out.

If you’re making an AI or bot, it’s highly recommended to _not_ use this class for detecting objects on the screen. It’s much more efficient to use pyboy.PyBoy.tilemap_background, pyboy.PyBoy.tilemap_window, and pyboy.PyBoy.get_sprite instead.

raw_buffer

Provides a raw, unfiltered bytes object with the data from the screen. Check Screen.raw_buffer_format to see which dataformat is used. The returned type and dataformat are subject to change. The screen buffer is row-major.

Use this, only if you need to bypass the overhead of Screen.image or Screen.ndarray.

Example:

>>> import numpy as np
>>> rows, cols = pyboy.screen.raw_buffer_dims
>>> ndarray = np.frombuffer(
...     pyboy.screen.raw_buffer,
...     dtype=np.uint8,
... ).reshape(rows, cols, 4) # Just an example, use pyboy.screen.ndarray instead
Returns:

92160 bytes memoryview of screen data.

Return type:

memoryview

raw_buffer_dims

Returns the dimensions of the raw screen buffer. The screen buffer is row-major.

Example:

>>> pyboy.screen.raw_buffer_dims
(144, 160)
Returns:

A two-tuple of the buffer dimensions. E.g. (144, 160).

Return type:

tuple

raw_buffer_format

Returns the color format of the raw screen buffer. This format is subject to change.

Example:

>>> from PIL import Image
>>> pyboy.screen.raw_buffer_format
'RGBA'
>>> image = Image.frombuffer(
...    pyboy.screen.raw_buffer_format,
...    pyboy.screen.raw_buffer_dims[::-1],
...    pyboy.screen.raw_buffer,
... ) # Just an example, use pyboy.screen.image instead
>>> image.save('frame.png')
Returns:

Color format of the raw screen buffer. E.g. ‘RGBA’.

Return type:

str

image

Reference to a PIL Image from the screen buffer. Remember to copy, resize or convert this object if you intend to store it. The backing buffer will update, but it will be the same PIL.Image object. Accessing this property requires Pillow; if Pillow is unavailable, access raises PyBoyDependencyError.

Convenient for screen captures, but might be a bottleneck, if you use it to train a neural network. In which case, read up on the Hardware API features, Pan Docs on tiles/sprites, and join our Discord channel for more help.

Example:

>>> image = pyboy.screen.image
>>> type(image)
<class 'PIL.Image.Image'>
>>> image.save('frame.png')
Returns:

RGBA image of (160, 144) pixels. Access requires Pillow to be installed.

Return type:

PIL.Image.Image

ndarray

References the screen data in NumPy format. Remember to copy this object if you intend to store it. The backing buffer will update, but it will be the same ndarray object.

The format is given by pyboy.api.screen.Screen.raw_buffer_format. The screen buffer is row-major.

Example:

>>> pyboy.screen.ndarray.shape
(144, 160, 4)
>>> # Display "P" on screen from the PyBoy bootrom
>>> pyboy.screen.ndarray[66:80,64:72,0]
array([[255, 255, 255, 255, 255, 255, 255, 255],
       [255,   0,   0,   0,   0,   0, 255, 255],
       [255,   0,   0,   0,   0,   0,   0, 255],
       [255,   0,   0, 255, 255,   0,   0, 255],
       [255,   0,   0, 255, 255,   0,   0, 255],
       [255,   0,   0, 255, 255,   0,   0, 255],
       [255,   0,   0,   0,   0,   0,   0, 255],
       [255,   0,   0,   0,   0,   0, 255, 255],
       [255,   0,   0, 255, 255, 255, 255, 255],
       [255,   0,   0, 255, 255, 255, 255, 255],
       [255,   0,   0, 255, 255, 255, 255, 255],
       [255,   0,   0, 255, 255, 255, 255, 255],
       [255,   0,   0, 255, 255, 255, 255, 255],
       [255, 255, 255, 255, 255, 255, 255, 255]], dtype=uint8)
Returns:

Screendata in ndarray of bytes with shape (144, 160, 4)

Return type:

numpy.ndarray

property tilemap_position_list

This property provides the screen (SCX, SCY) and window (WX - 7, WY) position for each horizontal line in the screen buffer. These parameters are often used for visual effects, and some games will reset the registers at the end of each call to pyboy.PyBoy.tick().

See Screen.get_tilemap_position for more information.

Example:

>>> pyboy.tick(25)
True
>>> swoosh = pyboy.screen.tilemap_position_list[66:77]
>>> print(*swoosh, sep=newline) # Just to pretty-print it
[0, 0, -7, 0]
[1, 0, -7, 0]
[2, 0, -7, 0]
[2, 0, -7, 0]
[2, 0, -7, 0]
[3, 0, -7, 0]
[3, 0, -7, 0]
[2, 0, -7, 0]
[1, 0, -7, 0]
[1, 0, -7, 0]
[0, 0, -7, 0]
Returns:

A list of 144 [SCX, SCY, WX - 7, WY] lists. Returns [0, 0, 0, 0] for each line when the LCD is off.

Return type:

list

get_tilemap_position()[source]

These coordinates define the tile-map offsets for the top-left corner of the screen and window. The tile map is 256x256 pixels, while the screen shows 160x144 pixels; scrolling past an edge wraps around to the other side.

For more details, see “7.4 Viewport” in the report, or the Pan Docs under LCD Position and Scrolling.

Example:

>>> pyboy.screen.get_tilemap_position()
((0, 0), (-7, 0))
Returns:

((SCX, SCY), (WX - 7, WY)).

Return type:

tuple