# Using PyBoy with Gymnasium As most people opted to modify the OpenAI Gym that PyBoy used to have, we've decided to remove the Gym Env from the codebase itself and replace it with this example. To use it, copy it into your codebase, and modify it to your needs. To install the requirements, run: `pip install pyboy numpy gymnasium`. Thanks to [Nicole Faye](https://github.com/NicoleFaye/) for providing the basis for this sample code. If you have questions or improvements to the code, come and tell us on Discord. [![Discord](https://img.shields.io/discord/584149554132418570?style=for-the-badge&logo=Discord&label=PyBoy)](https://discord.gg/wUbag3KNqQ) ```python # Adopted from https://github.com/NicoleFaye/PyBoy/blob/rl-test/PokemonPinballEnv.py import gymnasium as gym from gymnasium import spaces import numpy as np from pyboy import PyBoy actions = ['','a', 'b', 'left', 'right', 'up', 'down', 'start', 'select'] matrix_shape = (16, 20) game_area_observation_space = spaces.Box(low=0, high=255, shape=matrix_shape, dtype=np.uint8) class GenericPyBoyEnv(gym.Env): def __init__(self, pyboy, debug=False): super().__init__() self.pyboy = pyboy self._fitness=0 self._previous_fitness=0 self.debug = debug if not self.debug: self.pyboy.set_emulation_speed(0) self.action_space = spaces.Discrete(len(actions)) self.observation_space = game_area_observation_space self.pyboy.game_wrapper.start_game() def step(self, action): assert self.action_space.contains(action), "%r (%s) invalid" % (action, type(action)) # Move the agent if action == 0: pass else: self.pyboy.button(actions[action]) # Consider disabling renderer when not needed to improve speed: # self.pyboy.tick(1, False) self.pyboy.tick(1) done = self.pyboy.game_wrapper.game_over self._calculate_fitness() reward=self._fitness-self._previous_fitness observation=self.pyboy.game_area() info = {} truncated = False return observation, reward, done, truncated, info def _calculate_fitness(self): self._previous_fitness=self._fitness # NOTE: Only some game wrappers will provide a score # If not, you'll have to investigate how to score the game yourself self._fitness=self.pyboy.game_wrapper.score def reset(self, **kwargs): self.pyboy.game_wrapper.reset_game() self._fitness=0 self._previous_fitness=0 observation=self.pyboy.game_area() info = {} return observation, info def render(self, mode='human'): pass def close(self): self.pyboy.stop() ```