diff --git a/src/components/MapChangeHandler.tsx b/src/components/MapChangeHandler.tsx
index fe83384..e73dd68 100644
--- a/src/components/MapChangeHandler.tsx
+++ b/src/components/MapChangeHandler.tsx
@@ -1,8 +1,13 @@
 import styled from "styled-components";
 import { useDispatch, useSelector } from "react-redux";
-import { exitMap, selectPos, selectMap, setMap } from "../state/gameSlice";
+import {
+  exitMap,
+  selectPos,
+  selectMap,
+  setMap,
+  setMapWithPos,
+} from "../state/gameSlice";
 import { useEffect } from "react";
-import { MapId } from "../maps/map-types";
 import emitter, { Event } from "../app/emitter";
 import { isExit } from "../app/map-helper";
 import { selectBlackScreen, setBlackScreen } from "../state/uiSlice";
@@ -32,19 +37,19 @@ const MapChangeHandler = () => {
   useEffect(() => {
     const nextMap = map.maps[pos.y] ? map.maps[pos.y][pos.x] : null;
     const exit = isExit(map.exits, pos.x, pos.y);
+    const teleport =
+      map.teleports && map.teleports[pos.y]
+        ? map.teleports[pos.y][pos.x]
+        : null;
 
-    if (!nextMap && !exit) return;
+    if (!nextMap && !exit && !teleport) return;
     if (darkScreen) return;
 
-    const updateMap = (map_?: MapId) => {
+    const transition = (action: () => void) => {
       dispatch(setBlackScreen(true));
       setTimeout(() => {
         emitter.emit(Event.EnterDoor);
-        if (map_) {
-          dispatch(setMap(map_));
-        } else {
-          dispatch(exitMap());
-        }
+        action();
       }, 300);
       setTimeout(() => {
         dispatch(setBlackScreen(false));
@@ -52,11 +57,13 @@ const MapChangeHandler = () => {
     };
 
     if (nextMap) {
-      updateMap(nextMap);
+      transition(() => dispatch(setMap(nextMap)));
     } else if (exit) {
-      updateMap();
+      transition(() => dispatch(exitMap()));
+    } else if (teleport) {
+      transition(() => dispatch(setMapWithPos(teleport)));
     }
-  }, [pos, map.maps, dispatch, map.exits, darkScreen]);
+  }, [pos, map.maps, dispatch, map.exits, darkScreen, map.teleports]);
 
   return <Overlay $show={darkScreen} />;
 };
diff --git a/src/state/gameSlice.ts b/src/state/gameSlice.ts
index 00986bd..b7c8cc6 100644
--- a/src/state/gameSlice.ts
+++ b/src/state/gameSlice.ts
@@ -1,6 +1,6 @@
 import { createSlice, PayloadAction } from "@reduxjs/toolkit";
 import { RootState } from "./store";
-import { MapId, MapItemType, TrainerType } from "../maps/map-types";
+import { MapId, MapItemType, MapWithPos, TrainerType } from "../maps/map-types";
 import palletTown from "../maps/pallet-town";
 import { getPokemonStats } from "../app/use-pokemon-stats";
 import mapData from "../maps/map-data";
@@ -146,6 +146,10 @@ export const gameSlice = createSlice({
       const map = mapData[action.payload];
       state.pos = map.start;
     },
+    setMapWithPos: (state, action: PayloadAction<MapWithPos>) => {
+      state.map = action.payload.map;
+      state.pos = action.payload.pos;
+    },
     exitMap(state) {
       const map = mapData[state.map];
       if (!map) return;
@@ -345,6 +349,7 @@ export const {
   moveDown,
   setMap,
   setPos,
+  setMapWithPos,
   exitMap,
   setMoving,
   addInventory,