diff --git a/pyboy/plugins/__init__.py b/pyboy/plugins/__init__.py
index 0f8bf8565..bb88661a2 100644
--- a/pyboy/plugins/__init__.py
+++ b/pyboy/plugins/__init__.py
@@ -8,18 +8,18 @@
 
 __pdoc__ = {
     # docs exclude
-    "record_replay": False,
     "window_headless": False,
-    "manager_gen": False,
     "window_open_gl": False,
-    "debug": False,
-    "screenshot_recorder": False,
-    "manager": False,
-    "window_sdl2": False,
-    "auto_pause": False,
     "screen_recorder": False,
-    "window_dummy": False,
     "rewind": False,
+    "window_dummy": False,
     "disable_input": False,
+    "manager_gen": False,
+    "auto_pause": False,
+    "manager": False,
+    "record_replay": False,
+    "screenshot_recorder": False,
+    "debug": False,
+    "window_sdl2": False,
     # docs exclude end
 }
diff --git a/pyboy/plugins/base_plugin.pxd b/pyboy/plugins/base_plugin.pxd
index fdcd6eca1..99fe0d83d 100644
--- a/pyboy/plugins/base_plugin.pxd
+++ b/pyboy/plugins/base_plugin.pxd
@@ -4,7 +4,7 @@
 #
 
 from cpython.array cimport array
-from libc.stdint cimport uint8_t, uint32_t
+from libc.stdint cimport uint8_t, uint16_t, uint32_t
 cimport cython
 from pyboy.botsupport.tilemap cimport TileMap
 from pyboy.core.mb cimport Motherboard
@@ -42,6 +42,9 @@ cdef class PyBoyGameWrapper(PyBoyPlugin):
     cdef public shape
     cdef bint game_has_started
     cdef TileMap tilemap_background
+    cdef TileMap tilemap_window
+    cdef bint tilemap_use_background
+    cdef uint16_t sprite_offset
 
     cdef bint _tile_cache_invalid
     cdef array _cached_game_area_tiles_raw
diff --git a/pyboy/plugins/base_plugin.py b/pyboy/plugins/base_plugin.py
index 8c372426c..1e134b965 100644
--- a/pyboy/plugins/base_plugin.py
+++ b/pyboy/plugins/base_plugin.py
@@ -99,6 +99,9 @@ class PyBoyGameWrapper(PyBoyPlugin):
     def __init__(self, *args, game_area_section=(0, 0, 32, 32), game_area_wrap_around=False, **kwargs):
         super().__init__(*args, **kwargs)
         self.tilemap_background = self.pyboy.botsupport_manager().tilemap_background()
+        self.tilemap_window = self.pyboy.botsupport_manager().tilemap_window()
+        self.tilemap_use_background = True
+        self.sprite_offset = 0
         self.game_has_started = False
         self._tile_cache_invalid = True
         self._sprite_cache_invalid = True
@@ -167,12 +170,6 @@ def game_over(self):
         """
         raise NotImplementedError("game_over not implemented in game wrapper")
 
-    def game_over(self):
-        """
-        After calling `start_game`, you can call this method at any time to know if the game is over.
-        """
-        raise NotImplementedError("game_over not implemented in game wrapper")
-
     def _sprites_on_screen(self):
         if self._sprite_cache_invalid:
             self._cached_sprites_on_screen = []
@@ -199,14 +196,25 @@ def _game_area_tiles(self):
                     for x in range(width):
                         _x = (xx+x+SCX) % 32
                         _y = (yy+y+SCY) % 32
-                        self._cached_game_area_tiles[y][x] = self.tilemap_background.tile_identifier(_x, _y)
+                        if self.tilemap_use_background:
+                            self._cached_game_area_tiles[y][x] = self.tilemap_background.tile_identifier(_x, _y)
+                        else:
+                            self._cached_game_area_tiles[y][x] = self.tilemap_window.tile_identifier(_x, _y)
             else:
-                self._cached_game_area_tiles = np.asarray(
-                    self.tilemap_background[xx:xx + width, yy:yy + height], dtype=np.uint32
-                )
+                if self.tilemap_use_background:
+                    self._cached_game_area_tiles = np.asarray(
+                        self.tilemap_background[xx:xx + width, yy:yy + height], dtype=np.uint32
+                    )
+                else:
+                    self._cached_game_area_tiles = np.asarray(
+                        self.tilemap_window[xx:xx + width, yy:yy + height], dtype=np.uint32
+                    )
             self._tile_cache_invalid = False
         return self._cached_game_area_tiles
 
+    def use_background(self, value):
+        self.tilemap_use_background = value
+
     def game_area(self):
         """
         This method returns a cut-out of the screen as a simplified matrix for use in machine learning applications.
@@ -226,7 +234,8 @@ def game_area(self):
             _x = (s.x // 8) - xx
             _y = (s.y // 8) - yy
             if 0 <= _y < height and 0 <= _x < width:
-                tiles_matrix[_y][_x] = s.tile_identifier
+                tiles_matrix[_y][
+                    _x] = s.tile_identifier + self.sprite_offset # Adding offset to try to seperate sprites from tiles
         return tiles_matrix
 
     def _game_area_np(self, observation_type="tiles"):
diff --git a/pyboy/plugins/game_wrapper_pokemon_gen1.pxd b/pyboy/plugins/game_wrapper_pokemon_gen1.pxd
new file mode 100644
index 000000000..38e041e95
--- /dev/null
+++ b/pyboy/plugins/game_wrapper_pokemon_gen1.pxd
@@ -0,0 +1,10 @@
+#
+# License: See LICENSE.md file
+# GitHub: https://github.com/Baekalfen/PyBoy
+#
+from libc.stdint cimport uint8_t
+from pyboy.plugins.base_plugin cimport PyBoyGameWrapper
+cimport cython
+
+cdef class GameWrapperPokemonGen1(PyBoyGameWrapper):
+    pass
diff --git a/pyboy/plugins/game_wrapper_pokemon_gen1.py b/pyboy/plugins/game_wrapper_pokemon_gen1.py
new file mode 100644
index 000000000..b76de1be3
--- /dev/null
+++ b/pyboy/plugins/game_wrapper_pokemon_gen1.py
@@ -0,0 +1,70 @@
+#
+# License: See LICENSE.md file
+# GitHub: https://github.com/Baekalfen/PyBoy
+#
+__pdoc__ = {
+    "GameWrapperPokemonGen1.cartridge_title": False,
+    "GameWrapperPokemonGen1.post_tick": False,
+}
+
+import logging
+
+from pyboy.utils import WindowEvent
+
+from .base_plugin import PyBoyGameWrapper
+
+logger = logging.getLogger(__name__)
+
+try:
+    from cython import compiled
+    cythonmode = compiled
+except ImportError:
+    cythonmode = False
+
+
+class GameWrapperPokemonGen1(PyBoyGameWrapper):
+    """
+    This class wraps Pokemon Red/Blue, and provides basic access for AIs.
+
+    If you call `print` on an instance of this object, it will show an overview of everything this object provides.
+    """
+    cartridge_title = None
+
+    def __init__(self, *args, **kwargs):
+        self.shape = (20, 18)
+        super().__init__(*args, game_area_section=(0, 0) + self.shape, game_area_wrap_around=True, **kwargs)
+        self.sprite_offset = 0x1000
+
+    def enabled(self):
+        return self.pyboy_argv.get("game_wrapper") and ((self.pyboy.cartridge_title() == "POKEMON RED") or
+                                                        (self.pyboy.cartridge_title() == "POKEMON BLUE"))
+
+    def post_tick(self):
+        self._tile_cache_invalid = True
+        self._sprite_cache_invalid = True
+
+        scanline_parameters = self.pyboy.botsupport_manager().screen().tilemap_position_list()
+        WX = scanline_parameters[0][2]
+        WY = scanline_parameters[0][3]
+        self.use_background(WY != 0)
+
+    def __repr__(self):
+        adjust = 4
+        # yapf: disable
+        return (
+            f"Pokemon Gen 1:\n" +
+            "Sprites on screen:\n" +
+            "\n".join([str(s) for s in self._sprites_on_screen()]) +
+            "\n" +
+            "Tiles on screen:\n" +
+            " "*5 + "".join([f"{i: <4}" for i in range(10)]) + "\n" +
+            "_"*(adjust*20+4) +
+            "\n" +
+            "\n".join(
+                [
+                    f"{i: <3}| " + "".join([str(tile).ljust(adjust) for tile in line])
+                    for i, line in enumerate(self.game_area())
+                ]
+            )
+        )
+        # yapf: enable
diff --git a/pyboy/plugins/manager.pxd b/pyboy/plugins/manager.pxd
index 8ad523071..e6f24a896 100644
--- a/pyboy/plugins/manager.pxd
+++ b/pyboy/plugins/manager.pxd
@@ -19,6 +19,7 @@ from pyboy.plugins.screenshot_recorder cimport ScreenshotRecorder
 from pyboy.plugins.game_wrapper_super_mario_land cimport GameWrapperSuperMarioLand
 from pyboy.plugins.game_wrapper_tetris cimport GameWrapperTetris
 from pyboy.plugins.game_wrapper_kirby_dream_land cimport GameWrapperKirbyDreamLand
+from pyboy.plugins.game_wrapper_pokemon_gen1 cimport GameWrapperPokemonGen1
 # imports end
 from pyboy.plugins.base_plugin cimport PyBoyPlugin, PyBoyWindowPlugin
 
@@ -42,6 +43,7 @@ cdef class PluginManager:
     cdef public GameWrapperSuperMarioLand game_wrapper_super_mario_land
     cdef public GameWrapperTetris game_wrapper_tetris
     cdef public GameWrapperKirbyDreamLand game_wrapper_kirby_dream_land
+    cdef public GameWrapperPokemonGen1 game_wrapper_pokemon_gen1
     cdef bint window_sdl2_enabled
     cdef bint window_open_gl_enabled
     cdef bint window_headless_enabled
@@ -56,6 +58,7 @@ cdef class PluginManager:
     cdef bint game_wrapper_super_mario_land_enabled
     cdef bint game_wrapper_tetris_enabled
     cdef bint game_wrapper_kirby_dream_land_enabled
+    cdef bint game_wrapper_pokemon_gen1_enabled
     # plugin_cdef end
 
     cdef list handle_events(self, list)
diff --git a/pyboy/plugins/manager.py b/pyboy/plugins/manager.py
index f5e9662ea..ce37b8983 100644
--- a/pyboy/plugins/manager.py
+++ b/pyboy/plugins/manager.py
@@ -18,7 +18,9 @@
 from pyboy.plugins.game_wrapper_super_mario_land import GameWrapperSuperMarioLand # isort:skip
 from pyboy.plugins.game_wrapper_tetris import GameWrapperTetris # isort:skip
 from pyboy.plugins.game_wrapper_kirby_dream_land import GameWrapperKirbyDreamLand # isort:skip
+from pyboy.plugins.game_wrapper_pokemon_gen1 import GameWrapperPokemonGen1 # isort:skip
 # imports end
+from pyboy.plugins.base_plugin import PyBoyGameWrapper
 
 
 def parser_arguments():
@@ -37,6 +39,7 @@ def parser_arguments():
     yield GameWrapperSuperMarioLand.argv
     yield GameWrapperTetris.argv
     yield GameWrapperKirbyDreamLand.argv
+    yield GameWrapperPokemonGen1.argv
     # yield_plugins end
     pass
 
@@ -74,6 +77,8 @@ def __init__(self, pyboy, mb, pyboy_argv):
         self.game_wrapper_tetris_enabled = self.game_wrapper_tetris.enabled()
         self.game_wrapper_kirby_dream_land = GameWrapperKirbyDreamLand(pyboy, mb, pyboy_argv)
         self.game_wrapper_kirby_dream_land_enabled = self.game_wrapper_kirby_dream_land.enabled()
+        self.game_wrapper_pokemon_gen1 = GameWrapperPokemonGen1(pyboy, mb, pyboy_argv)
+        self.game_wrapper_pokemon_gen1_enabled = self.game_wrapper_pokemon_gen1.enabled()
         # plugins_enabled end
 
     def gamewrapper(self):
@@ -84,6 +89,8 @@ def gamewrapper(self):
             return self.game_wrapper_tetris
         if self.game_wrapper_kirby_dream_land_enabled:
             return self.game_wrapper_kirby_dream_land
+        if self.game_wrapper_pokemon_gen1_enabled:
+            return self.game_wrapper_pokemon_gen1
         # gamewrapper end
         return None
 
@@ -119,6 +126,8 @@ def handle_events(self, events):
             events = self.game_wrapper_tetris.handle_events(events)
         if self.game_wrapper_kirby_dream_land_enabled:
             events = self.game_wrapper_kirby_dream_land.handle_events(events)
+        if self.game_wrapper_pokemon_gen1_enabled:
+            events = self.game_wrapper_pokemon_gen1.handle_events(events)
         # foreach end
         return events
 
@@ -142,6 +151,8 @@ def post_tick(self):
             self.game_wrapper_tetris.post_tick()
         if self.game_wrapper_kirby_dream_land_enabled:
             self.game_wrapper_kirby_dream_land.post_tick()
+        if self.game_wrapper_pokemon_gen1_enabled:
+            self.game_wrapper_pokemon_gen1.post_tick()
         # foreach end
 
         self._post_tick_windows()
@@ -235,6 +246,8 @@ def window_title(self):
             title += self.game_wrapper_tetris.window_title()
         if self.game_wrapper_kirby_dream_land_enabled:
             title += self.game_wrapper_kirby_dream_land.window_title()
+        if self.game_wrapper_pokemon_gen1_enabled:
+            title += self.game_wrapper_pokemon_gen1.window_title()
         # foreach end
         return title
 
@@ -270,6 +283,8 @@ def stop(self):
             self.game_wrapper_tetris.stop()
         if self.game_wrapper_kirby_dream_land_enabled:
             self.game_wrapper_kirby_dream_land.stop()
+        if self.game_wrapper_pokemon_gen1_enabled:
+            self.game_wrapper_pokemon_gen1.stop()
         # foreach end
         pass
 
diff --git a/pyboy/plugins/manager_gen.py b/pyboy/plugins/manager_gen.py
index 4710abdf4..a6660d549 100644
--- a/pyboy/plugins/manager_gen.py
+++ b/pyboy/plugins/manager_gen.py
@@ -7,7 +7,9 @@
 # Plugins and priority!
 # E.g. DisableInput first
 windows = ["WindowSDL2", "WindowOpenGL", "WindowHeadless", "WindowDummy", "Debug"]
-game_wrappers = ["GameWrapperSuperMarioLand", "GameWrapperTetris", "GameWrapperKirbyDreamLand"]
+game_wrappers = [
+    "GameWrapperSuperMarioLand", "GameWrapperTetris", "GameWrapperKirbyDreamLand", "GameWrapperPokemonGen1"
+]
 plugins = [
     "DisableInput", "AutoPause", "RecordReplay", "Rewind", "ScreenRecorder", "ScreenshotRecorder"
 ] + game_wrappers