diff --git a/Bin/VC10/VC10.vcxproj b/Bin/VC10/VC10.vcxproj
index 6107e44..0d589d9 100644
--- a/Bin/VC10/VC10.vcxproj
+++ b/Bin/VC10/VC10.vcxproj
@@ -99,6 +99,7 @@
     <ClInclude Include="..\..\src\Level\Level.h" />
     <ClInclude Include="..\..\src\Level\MapTile.h" />
     <ClInclude Include="..\..\src\Level\Tileset.h" />
+    <ClInclude Include="..\..\Src\Level\Warp.h" />
     <ClInclude Include="..\..\src\Main\Game.h" />
     <ClInclude Include="..\..\src\Main\TitleScreen.h" />
     <ClInclude Include="..\..\src\Math\FPS.h" />
@@ -182,6 +183,11 @@
       <Project>{b4a2ecf2-d1e0-4e73-a59f-bcce49c37cc6}</Project>
     </ProjectReference>
   </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\Src\Level\Warp.cpp">
+      <FileType>Document</FileType>
+    </ClCompile>
+  </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
diff --git a/Bin/VC10/VC10.vcxproj.filters b/Bin/VC10/VC10.vcxproj.filters
index 8424bb1..c44ee77 100644
--- a/Bin/VC10/VC10.vcxproj.filters
+++ b/Bin/VC10/VC10.vcxproj.filters
@@ -195,6 +195,9 @@
     <ClInclude Include="..\..\src\UI\Menu.h">
       <Filter>UI</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\Src\Level\Warp.h">
+      <Filter>Level</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\src\Main\main.cpp">
@@ -317,5 +320,8 @@
     <ClCompile Include="..\..\src\UI\Menu.cpp">
       <Filter>UI</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\Src\Level\Warp.cpp">
+      <Filter>Level</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>
\ No newline at end of file
diff --git a/Data/Img/OpenArt/woodland_indoor_0.png b/Data/Img/OpenArt/woodland_indoor_0.png
new file mode 100644
index 0000000..d176d81
Binary files /dev/null and b/Data/Img/OpenArt/woodland_indoor_0.png differ
diff --git a/Data/Map/Ugly.tmx b/Data/Map/Ugly.tmx
index 0444e8e..c7240e3 100644
--- a/Data/Map/Ugly.tmx
+++ b/Data/Map/Ugly.tmx
@@ -57,11 +57,18 @@
    eJztl8ESwyAIRJP//+leemA6oIC7BhvejIemlV0QNb2upir3d2TnZeYyyHi5lYHWYsaWc5ha2TpFNFZ0Inn86jCY5SGf7exbK8bMm/xs/darZ3lA1yGSR0ZzpI/cvzvy8PiIxNR8ovaaxxsrDxSM+LP9dSnfIzQ1ndWY6L70ajLy0OqP0rHOCkadGHW3YiPvHQZe/dH6R+Iw8Xiovh5VPEiifrS9m723VkF4qNDj/5AHsi+eXgvpRT47ich6sOu9Yz13vEecmAdDI3IXN03TNE3zHqz3z9GoSOa/cUVOywPVJ5m5qJ5k9XamBitarF5YzaPK+RLVP+n8a5rmnXwA7bUBUA==
   </data>
  </layer>
- <objectgroup name="NPCs" width="50" height="50">
+ <objectgroup name="Events" width="50" height="50">
   <object name="NPC!!!" type="NPC" x="544" y="320" width="32" height="32">
    <properties>
     <property name="image" value="Player"/>
    </properties>
   </object>
+  <object name="Warp to house" type="warp" x="605" y="188" width="34" height="59">
+   <properties>
+    <property name="map" value="../Data/Map/house.tmx"/>
+    <property name="x" value="7"/>
+    <property name="y" value="13"/>
+   </properties>
+  </object>
  </objectgroup>
 </map>
diff --git a/Data/Map/house.tmx b/Data/Map/house.tmx
new file mode 100644
index 0000000..b384d25
--- /dev/null
+++ b/Data/Map/house.tmx
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<map version="1.0" orientation="orthogonal" width="15" height="15" tilewidth="32" tileheight="32">
+ <tileset firstgid="1" name="woodland_indoor_0" tilewidth="32" tileheight="32">
+  <image source="../Img/OpenArt/woodland_indoor_0.png" width="512" height="512"/>
+ </tileset>
+ <tileset firstgid="257" name="CollisionTileset" tilewidth="32" tileheight="32">
+  <image source="../Img/CollisionTileset.png" width="32" height="32"/>
+ </tileset>
+ <layer name="Layer 1" width="15" height="15">
+  <data encoding="base64" compression="zlib">
+   eJy10dEJgDAMBNDrCI5gZtFOou4/gvGvHHc1flh4EEJC4dIANALRUxYBps9WAabPQoDpV1R3xxdUvxlzC6pn/3CeQTXv8Y04N5ehumc1vy+zzN3zb9W7Pba0pz7Zde9IZ7omMzc2PRZ3
+  </data>
+ </layer>
+ <layer name="Layer 2" width="15" height="15">
+  <data encoding="base64" compression="zlib">
+   eJxjYEAFzAz4gRwQywOxApR/DojPA/EFIBYmoFcPiPWB2ADKvwfE94H4AQF92PS+A+L3ROjDpvcfEP8nUu8oYGBoAeJWIG7Do2YpGgaBg0A8BYinAvE0ID5Mgp0gvUugZi0jUe9QAwA5/BXY
+  </data>
+ </layer>
+ <layer name="Layer 3" width="15" height="15">
+  <data encoding="base64" compression="zlib">
+   eJxjYBheQAWIVcnUawLEplR0CzLgAWJeMvXKALEsFd1CT7AciDuAuGugHTKIAQBabAK+
+  </data>
+ </layer>
+ <layer name="Collision" width="15" height="15">
+  <data encoding="base64" compression="zlib">
+   eJxjZGRgYCQRgwCpetD1IgNc4vjUIJtHql5c8oQArjCgtl5iw54YfcQCWugdKPcQaz419eKLL0JqAIUTAME=
+  </data>
+ </layer>
+ <objectgroup name="Events" width="15" height="15">
+  <object name="Warp to village" type="warp" x="210" y="433" width="61" height="34">
+   <properties>
+    <property name="map" value="../Data/Map/Ugly.tmx"/>
+    <property name="x" value="19"/>
+    <property name="y" value="7"/>
+   </properties>
+  </object>
+ </objectgroup>
+</map>
diff --git a/src/Actor/Actor.cpp b/src/Actor/Actor.cpp
index 6abb573..ea1bd76 100644
--- a/src/Actor/Actor.cpp
+++ b/src/Actor/Actor.cpp
@@ -4,7 +4,7 @@
 #include "../Sound/SoundEffect.h"
 #include "../Level/Level.h"
 
-Actor::Actor(const Level* level) {
+Actor::Actor(Level* level) {
   _level = level;
 
   _stepSFX[0] = sfxManager.Load("../Data/SFX/step_cloth1.wav");
@@ -13,9 +13,10 @@ Actor::Actor(const Level* level) {
   _stepSFX[3] = sfxManager.Load("../Data/SFX/step_cloth4.wav");
   _lastStepSFXPlayed = -1;
 
-  _velocity        = 4.0f;
-  _direction       = FRONT;
-  _preventMovement = NONE;
+  _velocity         = 4.0f;
+  _direction        = FRONT;
+  _preventMovement  = NONE;
+  _distanceTraveled = 0;
 
   x = 0.0f;
   y = 0.0f;
@@ -62,6 +63,10 @@ void Actor::Update(float dt) {
   float collisionYOffset = GetMaxHeight() / 2.0f;
 
   if(x != oldX || y != oldY) {
+    float dx = x - oldX;
+    float dy = y - oldY;
+    _distanceTraveled += sqrtf(dx*dx + dy*dy);
+
     if(_level->CheckCollision(x, y + collisionYOffset, GetAnimation()->GetMaxWidth(), GetAnimation()->GetMaxHeight() - collisionYOffset)) {
       x = oldX;
       y = oldY;
diff --git a/src/Actor/Actor.h b/src/Actor/Actor.h
index 3ca3b1f..831caf4 100644
--- a/src/Actor/Actor.h
+++ b/src/Actor/Actor.h
@@ -24,9 +24,11 @@ public:
     HURT
   };
 
-  Actor(const Level* level);
+  Actor(Level* level);
   ~Actor(void);
 
+  void SetLevel(Level* level) { _level = level; }
+
   void LoadSprites(const String& basename);
 
   virtual void Update(float dt);
@@ -50,7 +52,7 @@ protected:
 
   AnimatingSprite* GetAnimation(void);
 
-  const Level* _level;
+  Level* _level;
 
   float _velocity;
 
@@ -62,6 +64,8 @@ protected:
   Facing _direction;
   Facing _preventMovement;
 
+  float _distanceTraveled;
+
   float x;
   float y;
 
diff --git a/src/Actor/NPC.cpp b/src/Actor/NPC.cpp
index 673b8fe..cc76dac 100644
--- a/src/Actor/NPC.cpp
+++ b/src/Actor/NPC.cpp
@@ -1,6 +1,6 @@
 #include "NPC.h"
 
-NPC::NPC(const Level* level) : Actor(level) {
+NPC::NPC(Level* level) : Actor(level) {
 }
 
 NPC::~NPC(void) {
diff --git a/src/Actor/NPC.h b/src/Actor/NPC.h
index f5b3d61..222dc57 100644
--- a/src/Actor/NPC.h
+++ b/src/Actor/NPC.h
@@ -4,7 +4,7 @@
 
 class NPC : public Actor {
 public:
-  NPC(const Level* level);
+  NPC(Level* level);
   ~NPC(void);
 
   void Update(float dt);
diff --git a/src/Actor/Player.cpp b/src/Actor/Player.cpp
index 4df4aaa..c420d04 100644
--- a/src/Actor/Player.cpp
+++ b/src/Actor/Player.cpp
@@ -1,7 +1,10 @@
 #include "Player.h"
 #include "../IO/Input.h"
+#include "../Level/Level.h"
+#include "../Level/Warp.h"
+#include "../Main/Game.h"
 
-Player::Player(const Level* level) : Actor(level) {
+Player::Player(Level* level) : Actor(level) {
   _direction = Actor::RIGHT;
 }
 
@@ -10,6 +13,14 @@ Player::~Player(void) {
 
 void Player::Update(float dt) {
   Actor::Update(dt);
+  
+  if(_distanceTraveled > 32.0f) {
+    Warp* warp = _level->CheckWarp(x, y, GetMaxWidth(), GetMaxHeight());
+    if(warp) {
+      _level->GetGame()->Warp(warp->GetTargetMap(), warp->GetTargetX(), warp->GetTargetY());
+      _distanceTraveled = 0;
+    }
+  }
 }
 
 void Player::Render(void) {
diff --git a/src/Actor/Player.h b/src/Actor/Player.h
index 7c0d20e..0f4c599 100644
--- a/src/Actor/Player.h
+++ b/src/Actor/Player.h
@@ -9,7 +9,7 @@ class Level;
 
 class Player : public Actor{
 public:
-  Player(const Level* level);
+  Player(Level* level);
   ~Player(void);
 
   void Update(float dt);
diff --git a/src/Level/Level.cpp b/src/Level/Level.cpp
index e2f7ffe..123da3a 100644
--- a/src/Level/Level.cpp
+++ b/src/Level/Level.cpp
@@ -4,10 +4,12 @@
 #include "Level.h"
 #include "Layer.h"
 #include "Tileset.h"
+#include "Warp.h"
 #include "../Sound/Music.h"
 #include "../System/Debug.h"
 #include "../TMXParser/Tmx.h"
 #include "../Actor/NPC.h"
+#include "../Math/Rect.h"
 
 #ifdef _WIN32
 #ifndef strcasecmp
@@ -18,7 +20,8 @@
 #endif
 #endif
 
-Level::Level() {
+Level::Level(Game* game) {
+  _game = game;
   _width = 0;
   _height = 0;
   _tileWidth = 0;
@@ -41,7 +44,12 @@ Level::~Level() {
   for(std::list<NPC*>::iterator  i = _npcs.begin(); i != _npcs.end(); ++i) {
     delete (*i);
   }
-  _npcs.end();
+  _npcs.clear();
+
+  for(std::list<Warp*>::iterator i = _warps.begin(); i != _warps.end(); ++i) {
+    delete (*i);
+  }
+  _warps.clear();
 
   if(_collisions) {
   delete[] _collisions;
@@ -134,6 +142,15 @@ bool Level::Load(const std::string& filename) {
         npc->SetXY(tmxObject->GetX(), tmxObject->GetY());
         _npcs.push_back(npc);
       }
+      else if(!strncasecmp(tmxObject->GetName().c_str(), "Warp", 4)) {
+        Warp* warp = new Warp();
+        warp->SetXY(tmxObject->GetX(), tmxObject->GetY());
+        warp->SetWidthHeight(tmxObject->GetWidth(), tmxObject->GetHeight());
+        warp->SetTargetMap(tmxObject->GetProperties().GetLiteralProperty("map").c_str());
+        warp->SetTargetX(tmxObject->GetProperties().GetNumericProperty("x") * 32);
+        warp->SetTargetY(tmxObject->GetProperties().GetNumericProperty("y") * 32);
+        _warps.push_back(warp);
+      }
     }
   }
 
@@ -172,8 +189,8 @@ void Level::Draw(int xOffset, int yOffset) {
 }
 
 bool Level::CheckCollision(float x, float y, float w, float h) const {
-  if(x < 0.0f || x > (float)(_width * _tileWidth) ||
-     y < 0.0f || y > (float)(_height * _tileHeight)) {
+  if(x < 0.0f || x >= (float)((_width - 1) * _tileWidth) ||
+     y < 0.0f || y >= (float)((_height - 1) * _tileHeight)) {
     return true;
   }
 
@@ -222,3 +239,17 @@ bool Level::CheckCollision(float x, float y, float w, float h) const {
 
   return false;
 }
+
+Warp* Level::CheckWarp(float x, float y, float w, float h) const {  
+  Rect objectArea(x, y, w, h);
+  for(std::list<Warp*>::const_iterator i = _warps.cbegin(); i != _warps.cend(); ++i) {
+    Warp* warp = (*i);
+    Rect warpArea(
+      warp->GetX(), warp->GetY(),
+      warp->GetWidth(), warp->GetHeight());
+    if(warpArea.CollidesWith(objectArea)) {
+      return warp;
+    }
+  }
+  return NULL;
+}
\ No newline at end of file
diff --git a/src/Level/Level.h b/src/Level/Level.h
index f3ddf8e..7e6da0a 100644
--- a/src/Level/Level.h
+++ b/src/Level/Level.h
@@ -3,31 +3,37 @@
 #include <string>
 #include <list>
 
+class Game;
 class Layer;
 class Tileset;
 class Music;
 class NPC;
+class Warp;
 
 class Level {
 public:
-  Level();
-  ~Level();
+  Level(Game* game);
+  ~Level(void);
 
   bool Load(const std::string& filename);
 
-  void PlayBGM();
+  void PlayBGM(void);
 
   void Update(float dt);
   void Draw(int xOffset, int yOffset);
 
+  Game* GetGame() { return _game; }
+
   int GetWidth() const { return _width; }
   int GetHeight() const { return _height; }
   int GetTileWidth() const { return _tileWidth; }
   int GetTileHeight() const { return _tileHeight; }
 
-  bool CheckCollision(float x, float y, float w, float h) const;
+  bool  CheckCollision(float x, float y, float w, float h) const;
+  Warp* CheckWarp(float x, float y, float w, float h) const;
 
 private:
+  Game* _game;
   int _width;
   int _height;
   int _tileWidth;
@@ -35,6 +41,7 @@ private:
   std::list<Layer*> _layers;
   std::list<Tileset*> _tilesets;
   std::list<NPC*> _npcs;
+  std::list<Warp*> _warps;
   Music* _bgm;
   bool* _collisions;
 };
diff --git a/src/Level/Warp.cpp b/src/Level/Warp.cpp
new file mode 100644
index 0000000..9700968
--- /dev/null
+++ b/src/Level/Warp.cpp
@@ -0,0 +1,11 @@
+#include "Warp.h"
+
+Warp::Warp(void) {
+  x = 0;
+  y = 0;
+  w = 0;
+  h = 0;
+  _targetMap = "";
+  _targetX = 0;
+  _targetY = 0;
+}
diff --git a/src/Level/Warp.h b/src/Level/Warp.h
new file mode 100644
index 0000000..ed78330
--- /dev/null
+++ b/src/Level/Warp.h
@@ -0,0 +1,39 @@
+#pragma once
+
+#include "../System/String.h"
+#include "../Math/Vec2.h"
+
+class Warp {
+public:
+  Warp(void);
+
+  int   GetX(void) const { return x; }
+  int   GetY(void) const { return y; }
+  int   GetWidth(void) const { return w; }
+  int   GetHeight(void) const { return h; }
+  void  SetX(int x) { this->x = x; }
+  void  SetY(int y) { this->y = y; }
+  void  SetXY(int x, int y) { SetX(x); SetY(y); }
+  void  SetWidth(int w)   { this->w =  w; }
+  void  SetHeight(int h)  { this->h = h;}
+  void  SetWidthHeight(int w, int h) { SetWidth(w); SetHeight(h); }
+
+  const String& GetTargetMap() const { return _targetMap;}
+  void SetTargetMap(const String& targetMap) { _targetMap = targetMap; }
+
+  int   GetTargetX(void) const { return _targetX; }
+  int   GetTargetY(void) const { return _targetY; }
+  void  SetTargetX(int targetX) { _targetX = targetX; }
+  void  SetTargetY(int targetY) { _targetY = targetY; }
+  void  SetTargetXY(int targetX, int targetY) { SetTargetX(targetX); SetTargetY(targetY); }
+
+private:
+  int x;
+  int y;
+  int w;
+  int h;
+
+  String  _targetMap;
+  int     _targetX;
+  int     _targetY;
+};
diff --git a/src/Main/Game.cpp b/src/Main/Game.cpp
index 91e50e8..06c92fc 100644
--- a/src/Main/Game.cpp
+++ b/src/Main/Game.cpp
@@ -22,11 +22,8 @@
 #include "TitleScreen.h"
 
 Game::Game(void) {
-  _level  = new Level();
+  _level  = new Level(this);
   _player = new Player(_level);
-  _NPC    = new NPC(_level);
-
-  _NPC->SetXY(30.0f, 30.0f);
 
   _testFont = new Font();
 
@@ -72,7 +69,6 @@ void Game::Render(void) {
 void Game::Shutdown(void) {
   Debug::logger->message("\n ----- Cleaning Engine -----");
   delete _testFont;
-  delete _NPC;
   delete _player;
   delete _level;
   if(_inGameMenu) {
@@ -103,6 +99,23 @@ void Game::OnResize(int width, int height) {
   glLoadIdentity();
 }
 
+void Game::Warp(const String& mapName, int x, int y) {
+  Level* newLevel = new Level(this);
+
+  if(!newLevel->Load(mapName.GetPointer())) {
+    delete newLevel;
+    return;
+  }
+
+  delete _level;
+  _level = newLevel;
+
+  _player->SetXY(x, y);
+  _player->SetLevel(_level);
+
+  _level->PlayBGM();
+}
+
 void Game::UpdateTitle(float dt) {
   _titleScreen->Update(dt);
 
@@ -144,7 +157,6 @@ void Game::UpdateGame(float dt) {
     }
   } else {
     _player->Update(dt);
-    _NPC->Update(dt);
     _level->Update(dt);
   }
 }
@@ -166,26 +178,39 @@ void Game::RenderGame(void) {
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
 
-  float windowCenterX = ((float)windowWidth / 2.0f) - ((float)_player->GetMaxWidth() / 2.0f);
-  float windowCenterY = ((float)windowHeight / 2.0f) - ((float)_player->GetMaxHeight() / 2.0f);
+  float xOffset;
+  float yOffset;
 
-  float xOffset = _player->GetX() - windowCenterX;
-  float yOffset = _player->GetY() - windowCenterY;
+  int levelWidthPixels = _level->GetWidth() * _level->GetTileWidth();
+  int levelHeightPixels = _level->GetHeight() * _level->GetTileHeight();
 
-  float maxXOffset = (_level->GetWidth() * _level->GetTileWidth()) - (float)windowWidth;
-  float maxYOffset = (_level->GetHeight() * _level->GetTileHeight()) - (float)windowHeight;
+  if(levelWidthPixels < windowWidth && levelHeightPixels < windowHeight) {
+    xOffset = levelWidthPixels / 2 - windowWidth / 2;
+    yOffset = levelHeightPixels / 2 - windowHeight / 2;
+    glTranslatef((int)-xOffset, (int)-yOffset, 0.0f);
+  }
+  else
+  {
+    float windowCenterX = ((float)windowWidth / 2.0f) - ((float)_player->GetMaxWidth() / 2.0f);
+    float windowCenterY = ((float)windowHeight / 2.0f) - ((float)_player->GetMaxHeight() / 2.0f);
 
-  if(xOffset < 0.0f) xOffset = 0.0f;
-  if(yOffset < 0.0f) yOffset = 0.0f;
-  if(xOffset > maxXOffset) xOffset = maxXOffset;
-  if(yOffset > maxYOffset) yOffset = maxYOffset;
+    xOffset = _player->GetX() - windowCenterX;
+    yOffset = _player->GetY() - windowCenterY;
 
-  glTranslatef((int)-xOffset, (int)-yOffset, 0.0f);
+    float maxXOffset = (float)(levelWidthPixels - windowWidth);
+    float maxYOffset = (float)(levelHeightPixels - windowHeight);
+
+    if(xOffset < 0.0f) xOffset = 0.0f;
+    if(yOffset < 0.0f) yOffset = 0.0f;
+    if(xOffset > maxXOffset) xOffset = maxXOffset;
+    if(yOffset > maxYOffset) yOffset = maxYOffset;
+
+    glTranslatef((int)-xOffset, (int)-yOffset, 0.0f);
+  }
 
   // Render our shit..
   _level->Draw(xOffset, yOffset);
   _player->Render();
-  _NPC->Render();
   _testFont->SetColor(0.0f, 1.0f, 1.0f, 1.0f);
   _testFont->RenderText(
     _player->GetX() - 5,
@@ -214,7 +239,6 @@ void Game::NewGame(void) {
   _level->PlayBGM();
 
   _player->LoadSprites("Player");
-  _NPC->LoadSprites("Player");
 
   _testFont->Load("../Data/Font/Fairydust.ttf", 16);
   _testFont->SetColor(0.0f, 1.0f, 1.0f, 1.0f);
diff --git a/src/Main/Game.h b/src/Main/Game.h
index 4f056c1..995efc1 100644
--- a/src/Main/Game.h
+++ b/src/Main/Game.h
@@ -1,6 +1,5 @@
 #pragma once
 #include "../IO/Input.h"
-#include "../Actor/NPC.h"
 #include "../Actor/Player.h"
 #include "../Font/Font.h"
 
@@ -24,6 +23,8 @@ public:
 
   void OnResize(int width, int height);
 
+  void Warp(const String& mapName, int x, int y);
+
   bool IsRunning()              { return _running; }
   void SetRunning(bool running) { _running = running; }
 
@@ -40,7 +41,6 @@ private:
 
   Font*   _testFont;
   Player* _player;
-  NPC*    _NPC;
   Level*  _level;
 
   TitleScreen* _titleScreen;
diff --git a/src/Math/Rect.h b/src/Math/Rect.h
index bf7d281..31eb3b1 100644
--- a/src/Math/Rect.h
+++ b/src/Math/Rect.h
@@ -1,5 +1,7 @@
 #pragma once
 
+#include "Vec2.h"
+
 struct Rect
 {
   float x;
@@ -14,4 +16,20 @@ struct Rect
     this->w = w;
     this->h = h;
   }
+
+  bool CollidesWith(const Rect& other) const {
+    if(x > (other.x + other.w))
+      return false;
+
+    if(y > (other.y + other.h))
+      return false;
+
+    if((x + w) < other.x)
+      return false;
+
+    if((y + h) < other.y)
+      return false;
+
+    return true;
+  }
 };