diff --git a/Crawler/Crawler.cpp b/Crawler/Crawler.cpp
index 4d49166d..e282d5d3 100644
--- a/Crawler/Crawler.cpp
+++ b/Crawler/Crawler.cpp
@@ -426,8 +426,27 @@ void Crawler::HandleUserInput(float fElapsedTime){
 		}
 	}
 	if(player.GetVelocity()==vf2d{0,0}){
+		auto GetPlayerStaircaseDirection=[&](){
+			for(LayerTag&layer:MAP_DATA[GetCurrentLevel()].LayerData){
+				int truncatedPlayerX=int(player.GetX())/24;
+				int truncatedPlayerY=int(player.GetY())/24;
+				int tileID=layer.tiles[truncatedPlayerY][truncatedPlayerX];
+				TilesheetData dat=GetTileSheet(GetCurrentLevel(),tileID);
+				if (dat.tileset.staircaseTiles.find(tileID)!=dat.tileset.staircaseTiles.end()){
+					return dat.tileset.staircaseTiles[tileID].data["value"];	
+				}
+			}
+			return std::string("NONE");
+		};
+		std::string staircaseDirection=GetPlayerStaircaseDirection();
 		if(RightHeld()){
 			player.SetX(player.GetX()+fElapsedTime*100*player.GetMoveSpdMult());
+			if(staircaseDirection=="RIGHT"){
+				player.SetY(player.GetY()-60*fElapsedTime*player.GetMoveSpdMult());
+			} else 
+			if(staircaseDirection=="LEFT"){
+				player.SetY(player.GetY()+60*fElapsedTime*player.GetMoveSpdMult());
+			}
 			player.SetFacingDirection(RIGHT);
 			if(player.GetState()==State::NORMAL){
 				player.UpdateWalkingAnimation(RIGHT);
@@ -436,6 +455,12 @@ void Crawler::HandleUserInput(float fElapsedTime){
 		}
 		if(LeftHeld()){
 			player.SetX(player.GetX()-fElapsedTime*100*player.GetMoveSpdMult());
+			if(staircaseDirection=="RIGHT"){
+				player.SetY(player.GetY()+60*fElapsedTime*player.GetMoveSpdMult());
+			} else 
+			if(staircaseDirection=="LEFT"){
+				player.SetY(player.GetY()-60*fElapsedTime*player.GetMoveSpdMult());
+			}
 			if(setIdleAnimation){
 				player.SetFacingDirection(LEFT);
 				if(player.GetState()==State::NORMAL){
@@ -956,6 +981,7 @@ void Crawler::InitializeLevel(std::string mapFile,MapName map){
 			MAP_TILESETS["assets/maps/"+baseSourceDir].foregroundTiles=tileset.GetData().ForegroundTileData;
 			MAP_TILESETS["assets/maps/"+baseSourceDir].upperForegroundTiles=tileset.GetData().UpperForegroundTileData;
 			MAP_TILESETS["assets/maps/"+baseSourceDir].collision=tileset.GetData().CollisionData;
+			MAP_TILESETS["assets/maps/"+baseSourceDir].staircaseTiles=tileset.GetData().StaircaseData;
 			r->Load("assets/maps/"+tileset.GetData().ImageData.data["source"]);
 		}
 	}
diff --git a/Crawler/Crawler.tiled-project b/Crawler/Crawler.tiled-project
index fb2e3299..3968320a 100644
--- a/Crawler/Crawler.tiled-project
+++ b/Crawler/Crawler.tiled-project
@@ -210,6 +210,42 @@
                 "object"
             ]
         },
+        {
+            "color": "#ffffaa00",
+            "drawFill": true,
+            "id": 14,
+            "members": [
+                {
+                    "name": "climbingDirection",
+                    "propertyType": "StaircaseDirection",
+                    "type": "string",
+                    "value": "LEFT"
+                }
+            ],
+            "name": "Staircase",
+            "type": "class",
+            "useAs": [
+                "property",
+                "map",
+                "layer",
+                "object",
+                "tile",
+                "tileset",
+                "wangcolor",
+                "wangset"
+            ]
+        },
+        {
+            "id": 15,
+            "name": "StaircaseDirection",
+            "storageType": "string",
+            "type": "enum",
+            "values": [
+                "LEFT",
+                "RIGHT"
+            ],
+            "valuesAsFlags": false
+        },
         {
             "color": "#ff9200e6",
             "drawFill": true,
diff --git a/Crawler/Map.h b/Crawler/Map.h
index d4180196..e6f2832a 100644
--- a/Crawler/Map.h
+++ b/Crawler/Map.h
@@ -18,6 +18,7 @@ struct TilesetData{
 	std::map<int,XMLTag>foregroundTiles;
 	std::map<int,XMLTag>upperForegroundTiles;
 	std::map<int,TileCollisionData>collision;
+	std::map<int,XMLTag>staircaseTiles;
 };
 
 struct TileRenderData{
diff --git a/Crawler/Player.cpp b/Crawler/Player.cpp
index f83de7b1..c6c6fd7f 100644
--- a/Crawler/Player.cpp
+++ b/Crawler/Player.cpp
@@ -67,7 +67,7 @@ bool Player::SetY(float y){
 		geom2d::rect<float>collision={collisionRect.pos,collisionRect.size};
 		#pragma region lambdas
 			auto NoPlayerCollisionWithTile=[&](){return !geom2d::overlaps(newPos,collision);};
-	#pragma endregion
+		#pragma endregion
 		collision.pos+=tilePos;
 		if(NoPlayerCollisionWithTile()){
 			pos.y=std::clamp(y,12.f*GetSizeMult(),float(game->WORLD_SIZE.y*24-12*GetSizeMult()));
diff --git a/Crawler/TSXParser.h b/Crawler/TSXParser.h
index 1f95efd6..3830f70e 100644
--- a/Crawler/TSXParser.h
+++ b/Crawler/TSXParser.h
@@ -12,6 +12,7 @@ struct Tileset{
     std::map<int,XMLTag> ForegroundTileData;
     std::map<int,XMLTag> UpperForegroundTileData;
     std::map<int,TileCollisionData> CollisionData;
+    std::map<int,XMLTag> StaircaseData;
     friend std::ostream& operator << (std::ostream& os, Tileset& rhs);
 };
 
@@ -23,6 +24,7 @@ class TSXParser{
 	void ParseTag(std::string tag);
     std::string previousTag;
     int previousTagID;
+    std::string staircaseTag="";
 	public:
 	TSXParser(std::string file);
 };
@@ -92,10 +94,18 @@ class TSXParser{
         if (newTag.tag=="tile"&&newTag.data["type"]=="UpperForegroundTile"){
             parsedTilesetInfo.UpperForegroundTileData[newTag.GetInteger("id")]=newTag;
         } else
+        if (newTag.tag=="tile"&&newTag.data["type"]=="Staircase"){
+            staircaseTag=newTag.tag;
+            previousTagID=newTag.GetInteger("id");
+        } else
         if (newTag.tag=="tile"){
             previousTag=newTag.tag;
             previousTagID=newTag.GetInteger("id");
         } else
+        if (newTag.tag=="property"&&staircaseTag=="tile"){
+            parsedTilesetInfo.StaircaseData[previousTagID]=newTag;
+            staircaseTag="";
+        } else
         if (newTag.tag=="object"&&previousTag=="tile"){
             TileCollisionData data;
             data.collision=geom2d::rect<int>{{newTag.GetInteger("x"),newTag.GetInteger("y")},{newTag.GetInteger("width"),newTag.GetInteger("height")}};
diff --git a/Crawler/Version.h b/Crawler/Version.h
index e2340c77..80d7af68 100644
--- a/Crawler/Version.h
+++ b/Crawler/Version.h
@@ -2,7 +2,7 @@
 #define VERSION_MAJOR 0
 #define VERSION_MINOR 2
 #define VERSION_PATCH 0
-#define VERSION_BUILD 487
+#define VERSION_BUILD 492
 
 #define stringify(a) stringify_(a)
 #define stringify_(a) #a
diff --git a/Crawler/assets/maps/grass_tiles_24x24.tsx b/Crawler/assets/maps/grass_tiles_24x24.tsx
index e4b87438..85f9478d 100644
--- a/Crawler/assets/maps/grass_tiles_24x24.tsx
+++ b/Crawler/assets/maps/grass_tiles_24x24.tsx
@@ -304,11 +304,21 @@
    <object id="1" x="0" y="0" width="24" height="24"/>
   </objectgroup>
  </tile>
- <tile id="362">
+ <tile id="362" type="Staircase">
+  <properties>
+   <property name="climbingDirection" propertytype="StaircaseDirection" value="RIGHT"/>
+  </properties>
   <objectgroup draworder="index" id="2">
    <object id="1" x="0" y="0" width="18" height="6"/>
   </objectgroup>
  </tile>
+ <tile id="363" type="Staircase">
+  <properties>
+   <property name="climbingDirection" propertytype="StaircaseDirection" value="RIGHT"/>
+  </properties>
+ </tile>
+ <tile id="364" type="Staircase"/>
+ <tile id="365" type="Staircase"/>
  <tile id="378">
   <objectgroup draworder="index" id="2">
    <object id="1" x="0" y="0" width="24" height="24"/>
@@ -354,6 +364,18 @@
    <object id="1" x="0" y="0" width="24" height="24"/>
   </objectgroup>
  </tile>
+ <tile id="391" type="Staircase">
+  <properties>
+   <property name="climbingDirection" propertytype="StaircaseDirection" value="RIGHT"/>
+  </properties>
+ </tile>
+ <tile id="392" type="Staircase">
+  <properties>
+   <property name="climbingDirection" propertytype="StaircaseDirection" value="RIGHT"/>
+  </properties>
+ </tile>
+ <tile id="393" type="Staircase"/>
+ <tile id="394" type="Staircase"/>
  <tile id="396" type="UpperForegroundTile"/>
  <tile id="397" type="UpperForegroundTile"/>
  <tile id="398" type="UpperForegroundTile"/>