Game Boy emulator written in Python

Overview

If you have any questions, or just want to chat, join us on Discord.

It is highly recommended to read the report to get a light introduction to Game Boy emulation. But do be aware, that the Python implementation has changed a lot. The report is relevant, eventhough you want to contribute to another emulator, or create your own.

If you've read the report and want more explicit details, have a look at the Pan Docs.

If you are looking to make a bot or AI, you can find all the external components in the PyBoy Documentation. There is also a short example on our Wiki page Scripts, AI and Bots as well as in the examples directory. If more features are needed, or if you find a bug, don't hesitate to make an issue here on GitHub, or write on our Discord channel.


Installation

The instructions are simple, if you already have a functioning Python environment on your machine.

  1. Install SDL2 through your package manager:

    • Ubuntu: sudo apt install libsdl2-dev
    • Fedora: sudo dnf install SDL2-devel
    • macOS: brew install sdl2
  2. Install PyBoy using pip install pyboy (add --user if your system asks)

Now you're ready! Either use PyBoy directly from the terminal $ pyboy file.rom or use it in your Python scripts:

from pyboy import PyBoy
pyboy = PyBoy('ROMs/gamerom.gb')
while not pyboy.tick():
    pass

When the emulator is running, you can easily access PyBoy's API:

from pyboy import WindowEvent

pyboy.send_input(WindowEvent.PRESS_ARROW_DOWN)
pyboy.tick() # Process one frame to let the game register the input
pyboy.send_input(WindowEvent.RELEASE_ARROW_DOWN)

pil_image = pyboy.screen_image()
pil_image.save('screenshot.png')

If you need more details, or if you need to compile from source, check out the detailed installation instructions. We support: macOS, Raspberry Pi (Raspbian), Linux (Ubuntu), and Windows 10.

At the Wiki page, you will also find out how to interface with PyBoy from your own project: Wiki.

Contributors

Thanks to all the people, who have contributed to the project!

Original Developers

GitHub Collaborators

Student Projects

  • Rewind Time: Jacob Olsen - JacobO1
  • Link Cable: Jonas Flach-Jensen - thejomas
  • Game Boy Color: Christian Marslev and Jonas Grønborg - CKuke and kaff3

Contribute

Any contribution is appreciated. The currently known errors are registered in the Issues tab. Feel free to take a swing at any one of them.

For the more major features, there are the following that you can give a try. They are also described in more detail in the project list:

  • Color
  • Link Cable
  • (Experimental) AI - use the botsupport or game wrappers to train a neural network
  • (Experimental) Game Wrappers - make wrappers for popular games

If you want to implement something which is not on the list, feel free to do so anyway. If you want to merge it into our repo, then just send a pull request and we will have a look at it.

Comments
  • Implement Random RAM

    Implement Random RAM

    If the random flag is set, iterate through the existing RAM arrays and randomize the values.

    While there are no specific RAM unit tests, I played through some of the ROMs I have locally and the games seemed to be running fine.

    opened by naclander 19
  • WIP: Use scaled size for mouse events in debug windows

    WIP: Use scaled size for mouse events in debug windows

    The tile management in debug windows (hovering and clicking on squares) was not working correctly after the window was scaled. The logic for determining the tile index was relying on the original scaling of the window, resulting in the incorrect tile being targetted.

    By listening for SDL window resize events, we can keep the scaling value up-to-date. We also need to change the one-dimensional scaling value to separate horizontal/vertical scaling due to how the resizing allows the aspect ratio to change.

    Checklist for pull-requests

    1. The project is licensed under LGPL (see LICENSE.md). When merged, your code will be under the same license. So make sure you have read and understand it.
    2. Please coordinate with one of the core developers before making a big pull-request. It's a shame to make something big that doesn't fit the project.
    3. Remember to make a separate branch on your fork. This makes it a lot easier for the core developers to help getting your pull-request ready.
    4. Install pip install pre-commit. This takes care of the formatting rules when you commit your code.
    5. Add tests. We need good pytests for your code. This will help us keep the project stable.
    6. Please don't change the code style, unless it's specifically asked for.

    -->

    opened by JonathanMurray 18
  • Reworked input handling

    Reworked input handling

    I have reworked the input handling completely, in preparation for loadable scripts.

    Performance has worsened with this new input handler, hence the "WIP"-tag.

    opened by thomafred 14
  • Can't run Pokemon Red...

    Can't run Pokemon Red...

    I try to run Pokemon Red, but when I arrive in the screen to create a game, it says:

    1771008  pyboy                          ERROR    Unexpected write to 0x6000, value: 0x01
    1771009  pyboy                          ERROR    Unexpected write to 0x6000, value: 0x00
    

    I don't know why, and how to resolve it... ~~My ROM~~ [REMOVED] If you could help me...

    opened by arthur-fontaine 9
  • Implemented v1 of the Debugger's Memory Window

    Implemented v1 of the Debugger's Memory Window

    • Implemented the MemoryWindow class in pyboy/plugins/debug.py
    • Added the necessary attributes in pyboy/utils.py & pyboy/plugins/window_sdl2.py
    • Added the new memory window hot keys to the main.py output
      • J - next 0x100 bytes
      • K - back 0x100 bytes
      • Left Shift - forward 0x1000 bytes
      • Right Shift - back 0x1000 bytes
    • Added pyboy/plugins/assets/Mono_Hack_Font.ttf as the default font to use with SDL2_ttf
    • Updated the README with the package manager install instructions for each OS.
    opened by kr1tzy 9
  • Feature/gymboy

    Feature/gymboy

    Following issue #124 this is a first version to create a Gym environement from a PyBoy object There is still some tests to do ! But it's a working start !

    opened by MathisFederico 9
  • Tetris wrapper's reset_game() doesn't seem to work.

    Tetris wrapper's reset_game() doesn't seem to work.

    quiet = False 
    filename  = './roms/Tetris.gb' 
    pyboy = PyBoy(filename, window_type="headless" if quiet else "SDL2", window_scale=3, debug=True, game_wrapper=True) 
    pyboy.set_emulation_speed(0) 
    tetris = pyboy.game_wrapper() 
    tetris.start_game() 
    

    After this, calling reset_game() does nothing. Even after sending a few WindowEvents and tick().

    opened by ogabrielluiz 9
  • Running on RaspberryPi 4B error

    Running on RaspberryPi 4B error

    [email protected]:~/PyBoy $ python3 -m pyboy ../mario.nes
    1399     __main__                       INFO
    The Game Boy controls are as follows:
    
    | Keyboard key | GameBoy equivalant |
    | ---          | ---                |
    | Up           | Up                 |
    | Down         | Down               |
    | Left         | Left               |
    | Right        | Right              |
    | A            | A                  |
    | S            | B                  |
    | Return       | Start              |
    | Backspace    | Select             |
    
    The other controls for the emulator:
    
    | Keyboard key | Emulator function       |
    | ---          | ---                     |
    | Escape       | Quit                    |
    | D            | Debug                   |
    | Space        | Unlimited FPS           |
    | Z            | Save state              |
    | X            | Load state              |
    | I            | Toggle screen recording |
    | ,            | Rewind backwards        |
    | .            | Rewind forward          |
    
    See "pyboy --help" for how to enable rewind and other awesome features!
    
    Segmentation fault
    

    [email protected]:~/PyBoy $ pip3 list
    Package           Version
    ----------------- -----------
    appdirs           1.4.3
    asn1crypto        0.24.0
    astroid           2.1.0
    asttokens         1.1.13
    automationhat     0.2.0
    beautifulsoup4    4.7.1
    blinker           1.4
    blinkt            0.1.2
    buttonshim        0.0.2
    Cap1xxx           0.1.3
    certifi           2018.8.24
    chardet           3.0.4
    Click             7.0
    colorama          0.3.7
    colorzero         1.1
    cookies           2.2.1
    cryptography      2.6.1
    cycler            0.10.0
    Cython            0.29.16
    decorator         4.3.0
    docutils          0.14
    drumhat           0.1.0
    ecdsa             0.13
    entrypoints       0.3
    envirophat        1.0.0
    ExplorerHAT       0.4.2
    Flask             1.0.2
    fourletterphat    0.1.0
    gpiozero          1.5.1
    guizero           0.6.0
    html5lib          1.0.1
    idna              2.6
    ipykernel         4.9.0
    ipython           5.8.0
    ipython-genutils  0.2.0
    isort             4.3.4
    itsdangerous      0.24
    jedi              0.13.2
    Jinja2            2.10
    jupyter-client    5.2.3
    jupyter-core      4.4.0
    keyring           17.1.1
    keyrings.alt      3.1.1
    kiwisolver        1.0.1
    lazy-object-proxy 1.3.1
    logilab-common    1.4.2
    lxml              4.3.2
    MarkupSafe        1.1.0
    matplotlib        3.0.2
    mccabe            0.6.1
    microdotphat      0.2.1
    mote              0.0.4
    motephat          0.0.3
    mypy              0.670
    mypy-extensions   0.4.1
    nudatus           0.0.4
    numpy             1.16.2
    oauthlib          2.1.0
    olefile           0.46
    pantilthat        0.0.7
    parso             0.3.1
    pathlib           1.0.1
    pexpect           4.6.0
    pgzero            1.2
    phatbeat          0.1.1
    pianohat          0.1.0
    picamera          1.13
    pickleshare       0.7.5
    picraft           1.0
    piglow            1.2.5
    pigpio            1.44
    Pillow            5.4.1
    pip               20.0.2
    prompt-toolkit    1.0.15
    psutil            5.5.1
    pyaes             1.6.1
    pyboy             1.0.0
    pycairo           1.16.2
    pycodestyle       2.4.0
    pycrypto          2.6.1
    pyflakes          2.0.0
    pygame            1.9.4.post1
    Pygments          2.3.1
    PyGObject         3.30.4
    pyinotify         0.9.6
    PyJWT             1.7.0
    pylint            2.2.2
    pyOpenSSL         19.0.0
    pyparsing         2.2.0
    PySDL2            0.9.7
    pyserial          3.4
    python-apt        1.8.4.1
    python-dateutil   2.7.3
    pyudev            0.22.0
    pyxdg             0.25
    pyzmq             17.1.2
    qtconsole         4.3.1
    rainbowhat        0.1.0
    requests          2.21.0
    requests-oauthlib 1.0.0
    responses         0.9.0
    roman             2.0.0
    RPi.GPIO          0.7.0
    rshell            0.0.27
    RTIMULib          7.2.1
    scrollphat        0.0.7
    scrollphathd      1.2.1
    SecretStorage     2.3.1
    semver            2.0.1
    Send2Trash        1.5.0
    sense-emu         1.1
    sense-hat         2.2.0
    setuptools        40.8.0
    simplegeneric     0.8.1
    simplejson        3.16.0
    six               1.12.0
    skywriter         0.0.7
    sn3218            1.2.7
    soupsieve         1.8
    spidev            3.4
    ssh-import-id     5.7
    thonny            3.2.6
    tornado           5.1.1
    touchphat         0.0.1
    traitlets         4.3.2
    twython           3.7.0
    typed-ast         1.3.1
    uflash            1.2.4
    unicornhathd      0.0.4
    urllib3           1.24.1
    wcwidth           0.1.7
    webencodings      0.5.1
    websockets        8.1
    Werkzeug          0.14.1
    wheel             0.32.3
    wrapt             1.10.11
    

    [email protected]:~/PyBoy $ python3 -V
    Python 3.7.3
    [email protected]:~/PyBoy $ uname  -a
    Linux raspberrypi 4.19.97-v7l+ #1294 SMP Thu Jan 30 13:21:14 GMT 2020 armv7l GNU/Linux
    [email protected]:~/PyBoy $
    [email protected]:~/PyBoy $ lsb_release -a
    No LSB modules are available.
    Distributor ID: Raspbian
    Description:    Raspbian GNU/Linux 10 (buster)
    Release:        10
    Codename:       buster
    [email protected]:~/PyBoy $
    [email protected]:~/PyBoy $ free -m
                  total        used        free      shared  buff/cache   available
    Mem:           1939         137        1018          34         783        1677
    Swap:            99           0          99
    [email protected]:~/PyBoy $
    

    Compile from your repository, and running with an nintendo game rom called : mario.nes Dose it support Nintendo or just fit for gameboy?(GB) ?

    opened by yoyojacky 8
  • Add get_scanline_parameters method

    Add get_scanline_parameters method

    Hi,

    Not sure if this is generally useful -- this PR adds a method to retrieve the _scanlineparameters from the window object. It's implemented only for the SDLWindow and children, and returns a list of lists, one per scanline, with the position(s) in the tilemap used for each scanline per frame.

    From experimentation, this seems to work well. There's a comment on get_screen_position with a TODO about retrieving the scanline parameters instead -- not sure if this meets that requirement.

    Happy to flesh this out a bit to get it up to scratch!

    opened by marginalhours 8
  • Openai interface

    Openai interface

    Hi Mads,

    As we talked on LinkedIn, I would like to push the openai interface to this repo! To test it, you can try it from Source/main_openai.py(https://github.com/Rowing0914/PyBoy/blob/openai_interface/Source/main_openai.py)!!

    Thanks

    opened by Rowing0914 7
  • About TileViews

    About TileViews

    First, thanks for answering me before. Now, this is more a doubt than an issue... When I use the tileview I get two windows, one for the "current map without the player" and other for the HUD (the remaining time bar, power, and such). At the moment I can retreive the "on screen" sprites but I cant get the sprites in the tileviews and I need to get the sprites near the racer (in the tileview but not on screen). How should I proceed? This is what I see: https://i.imgur.com/3yrvuSg.png

    opened by ccokee 7
  • Modular Plugin Manager

    Modular Plugin Manager

    Allows for modularly adding plugins (game wrappers) to PyBoy. This is helpful so users can create their own game wrappers and add them without them having to be officially supported.

    There are still some Cython type definition things missing as that's not my specialty, but besides that, I'd like to hear your thoughts.

    P.S. my code formatter accidentally added some spaces between plus signs, so if you have an auto code formatter, you might want to run it on this branch.

    opened by hexiro 3
  • Add easy way to add plugins (game wrappers) to Plugin Manager

    Add easy way to add plugins (game wrappers) to Plugin Manager

    Hello! I've been attempted to add the WIP Pokemon Red Plugin to my local project, but I'm finding it's quite difficult due to the way the PyBoy and PluginManager classes are structured. Would you be willing to accept a PR that makes the design more modular, and allows the user to something like the following?

    game = pyboy.PyBoy(PATH, game_wrapper=True)
    game.plugin_manager.add_plugin(PLUGIN)
    

    Additionally, inside the plugin manager, there is a lot of .enabled() calls from plugins, but it appears as though that function will return the same result everytime. This can be seen by the fact that the PluginManager class has extra attributes to cache the result for all of them.

    # example:
    self.window_sdl2 = WindowSDL2(pyboy, mb, pyboy_argv)
    self.window_sdl2_enabled = self.window_sdl2.enabled()
    self.window_open_gl = WindowOpenGL(pyboy, mb, pyboy_argv)
    self.window_open_gl_enabled = self.window_open_gl.enabled()
    

    I personally think this would be structured better if the enabled function in each plugin was changed into a _enabled helper function that is called in the initializer and set to an enabled attribute, so the attribute .enabled would be available and these extra (plugin name)_enabled attributes wouldn't be needed.

    If there's conflicts with evaluating enabled state before hand, that's okay as that doesn't impact the user at the end of the day. What does though, is the ability to add custom plugins, so let me know what you think about these suggestions! :)

    opened by hexiro 11
  • Make API to extract sound stream

    Make API to extract sound stream

    We don't current have a way to get the sound output through the API. This could for example be in the form of a buffer to copy at every frame.

    This might also require some work to separate the sound implementation from SDL2.

    enhancement good first issue 
    opened by Baekalfen 4
Releases(v1.5.3)
Owner
Mads Ynddal
Bæk-alfen ― M.Sc. Computer Science, University of Copenhagen
Mads Ynddal
Algorithm to solve Wordle correctly 100% of the time within 6 attempts.

WordleSolver © Zulkarnine, 2022. Algorithm to solve Wordle 100% of the time within 6 attempts. You can go ahead and run main.py to run it for all 2315

Zulkarnine Mahmud 69 Dec 11, 2022
Code and outputs from analysis determining that the wordle game can always be won in six moves.

wordle_worst_case_analysis Code and outputs from analysis determining that the wordle game can always be won in six moves. This is for the general cas

2 Aug 19, 2022
You can play TicTacToe with the engine running UI.py with python3

TicTacToe An "Engine" for TicTacToe You can play TicTacToe with the engine running UI.py with python3. The file engine.py is designed so you can make

Ahnaf Syndeed 3 Feb 20, 2022
A first-person shooting game developed by using OpenGL

OpenGL-MazeSurvivor-FirstPerson Shooting Game This application named ‘MAZE SURVIVOR’ is a first-person shooting game that finished within a month. It

JunHong 2 Jan 04, 2023
An implementation of John Conway's Game of Life.

This is an implementation of John Conway's Game of Life in Python, and a very basic and straightforward one at that.

Mae 3 Feb 11, 2022
Minecraft Bedrock Server Control GUI

A control dashboard to monitor and control your minecraft bedrock dedicated server through an easy user interface. Created by Nathan-Busse 13 January 2022 Made with Python 3.8

Nathan Busse 3 Dec 11, 2022
Allows you to email people wordle spoilers. Very beta, not as many features

wordlespoiler Allows you to email people wordle spoilers. Very beta, not as many features How to Use 1.) Make a new gmail account. Go to settings (Man

0 Jan 04, 2023
Tic-Tac-Toe - Tic-Tac-Toe game build With Python

Tic Tac Toe This game is very popular amongst all of us and even fun to build as

PyLaboratory 0 Feb 06, 2022
Guess number game with PyQt5

Guess-Number-Project Guess number game with PyQt5 you can choose a number in your mind and then computer will guess a nummber and you guide the comput

MohammadAli.HBA 1 Nov 11, 2021
Adventure-Game - Adventure Game which is created using Python

Adventure Game 🌇 This is a Adventure Game which is created using Python. Featur

ArinjoyTheDev 1 Mar 19, 2022
python script to convert .OBJ files into Minecraft, rendering them in game with a core shader.

samples: random notes about the tool general output format: (animation not supported yet but planned) vertex id Minecraft's gl_VertexID isn't per mode

199 Jan 02, 2023
Battle of Saiyans: Goku v Vegeta is a 1 v 1, (Player vs CPU) 2D Martial arts fighting game

Battle of Saiyans: Goku v Vegeta is a 1 v 1, (Player vs CPU) 2D Martial arts fighting game inspired by the popular anime series Dragon Ball Z The game

ARZ 3 Feb 16, 2022
Flappy Bird clone utilizing facial recognition to move the

Flappy Face Flappy Bird clone utilizing facial recognition to move the "bird" How it works Flappy Face uses Facial Recognition to detect your face's p

Brady McDermott 1 Jan 11, 2022
This repository contains the Unix Game challenges and metadata

This repository contains the Unix Game challenges and metadata

Nokia 7 Apr 06, 2022
This is game 2048 created with moudle of python tkinter and OOP.

Game 2048 This is game 2048 created with moudle of python tkinter and OOP. This game build on classes. For start this game run: If you have python ver

0 Nov 02, 2021
Logo hitting the corner == best feeling ever!

Bouncing DVD logo - Pygame A little ride back to the 90s. Ah good ol' time! Didn't we all wait for the logo to hit the corners? Best feeling ever!! I

Hoang Nguyen 3 May 25, 2022
Super Mario Kart November 1991 Prototype Repair by MrL314

Super Mario Kart November 1991 Prototype Repair by MrL314

MrL314 51 Dec 26, 2022
EL JUEGO DEL GUSANITO

EL JUEGO DEL GUSANITO El juego consiste en una línea que no para de moverse, el usuario lo controla con las flechas de: → derecha ← izquierda ↑ arriba

Valeria Saidid Miranda Ibarra 0 Dec 19, 2021
pygame is a Free and Open Source python programming language library for making multimedia applications like games built on top of the excellent SDL library. C, Python, Native, OpenGL.

pygame is a Free and Open Source python programming language library for making multimedia applications like games built on top of the excellent SDL library. C, Python, Native, OpenGL.

pygame 5.6k Jan 01, 2023
The Sinclair ZX Spectrum BASIC compiler!

ZX BASIC Copyleft (K) 2008, Jose Rodriguez-Rosa (a.k.a. Boriel) http://www.boriel.com All files in this project are covered under the GPLv3 LICENSE ex

Jose Rodriguez 143 Dec 13, 2022