diff --git a/core/proguard-rules.pro b/core/proguard-rules.pro
index b675a2fa2..495f9284a 100644
--- a/core/proguard-rules.pro
+++ b/core/proguard-rules.pro
@@ -1,4 +1,4 @@
-# retain these to support reflection and meaningful stack traces
--keep class com.shatteredpixel.** { *; }
--keep class com.watabou.** { *; }
+# retain these to support class references and meaningful stack traces
+-keepnames class com.shatteredpixel.** { *; }
+-keepnames class com.watabou.** { *; }
 -keepattributes SourceFile,LineNumberTable
\ No newline at end of file
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Blacksmith.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Blacksmith.java
index 466e63490..1bd95ea36 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Blacksmith.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Blacksmith.java
@@ -32,8 +32,9 @@ import com.shatteredpixel.shatteredpixeldungeon.items.Item;
 import com.shatteredpixel.shatteredpixeldungeon.items.quest.DarkGold;
 import com.shatteredpixel.shatteredpixeldungeon.items.quest.Pickaxe;
 import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfUpgrade;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.BlacksmithRoom;
 import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room;
-import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room.Type;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.StandardRoom;
 import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
 import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
 import com.shatteredpixel.shatteredpixeldungeon.sprites.BlacksmithSprite;
@@ -44,7 +45,7 @@ import com.watabou.noosa.audio.Sample;
 import com.watabou.utils.Bundle;
 import com.watabou.utils.Random;
 
-import java.util.Collection;
+import java.util.ArrayList;
 
 public class Blacksmith extends NPC {
 	
@@ -278,14 +279,14 @@ public class Blacksmith extends NPC {
 			}
 		}
 		
-		public static boolean spawn( Collection<Room> rooms ) {
+		public static boolean spawn( ArrayList<Room> rooms ) {
 			if (!spawned && Dungeon.depth > 11 && Random.Int( 15 - Dungeon.depth ) == 0) {
 				
 				Room blacksmith;
 				for (Room r : rooms) {
-					if (r.type == Type.STANDARD && r.width() > 4 && r.height() > 4) {
-						blacksmith = r;
-						blacksmith.type = Type.BLACKSMITH;
+					if (r instanceof StandardRoom && r.width() > 4 && r.height() > 4) {
+						blacksmith = new BlacksmithRoom().set(r);
+						rooms.set(rooms.indexOf(r), blacksmith);
 						
 						spawned = true;
 						alternative = Random.Int( 2 ) == 0;
@@ -295,6 +296,7 @@ public class Blacksmith extends NPC {
 						break;
 					}
 				}
+				
 			}
 			return spawned;
 		}
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Wandmaker.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Wandmaker.java
index 4c68bc746..db96c1749 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Wandmaker.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Wandmaker.java
@@ -33,7 +33,11 @@ import com.shatteredpixel.shatteredpixeldungeon.items.quest.CorpseDust;
 import com.shatteredpixel.shatteredpixeldungeon.items.quest.Embers;
 import com.shatteredpixel.shatteredpixeldungeon.items.wands.Wand;
 import com.shatteredpixel.shatteredpixeldungeon.levels.PrisonLevel;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.MassGraveRoom;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.RitualSiteRoom;
 import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.RotGardenRoom;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.StandardRoom;
 import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
 import com.shatteredpixel.shatteredpixeldungeon.plants.Rotberry;
 import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
@@ -43,6 +47,7 @@ import com.shatteredpixel.shatteredpixeldungeon.windows.WndWandmaker;
 import com.watabou.utils.Bundle;
 import com.watabou.utils.Random;
 
+import java.util.ArrayList;
 import java.util.Collection;
 
 public class Wandmaker extends NPC {
@@ -278,7 +283,7 @@ public class Wandmaker extends NPC {
 			}
 		}
 		
-		public static boolean spawnRoom( Collection<Room> rooms) {
+		public static boolean spawnRoom( ArrayList<Room> rooms) {
 			questRoomSpawned = false;
 			if (!spawned && (type != 0 || (Dungeon.depth > 6 && Random.Int( 10 - Dungeon.depth ) == 0))) {
 				
@@ -290,7 +295,7 @@ public class Wandmaker extends NPC {
 				//we don't re-roll the quest, it will try to assign itself to that new level with the same type.
 				Room questRoom = null;
 				for (Room r : rooms){
-					if (r.type == Room.Type.STANDARD && r.width() > 5 && r.height() > 5){
+					if (r instanceof StandardRoom && r.width() > 5 && r.height() > 5){
 						if (type == 2 || r.connected.size() == 1){
 							questRoom = r;
 							break;
@@ -302,17 +307,19 @@ public class Wandmaker extends NPC {
 					return false;
 				}
 		
+				Room temp = questRoom;
 				switch (type){
 					case 1: default:
-						questRoom.type = Room.Type.MASS_GRAVE;
+						questRoom = new MassGraveRoom().set(temp);
 						break;
 					case 2:
-						questRoom.type = Room.Type.RITUAL_SITE;
+						questRoom = new RitualSiteRoom().set(temp);
 						break;
 					case 3:
-						questRoom.type = Room.Type.ROT_GARDEN;
+						questRoom = new RotGardenRoom().set(temp);
 						break;
 				}
+				rooms.set(rooms.indexOf(temp), questRoom);
 		
 				questRoomSpawned = true;
 				return true;
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/CavesLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/CavesLevel.java
index 80d41563d..0dacb3d02 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/CavesLevel.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/CavesLevel.java
@@ -24,7 +24,8 @@ package com.shatteredpixel.shatteredpixeldungeon.levels;
 import com.shatteredpixel.shatteredpixeldungeon.Assets;
 import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
 import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room;
-import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room.Type;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.StandardRoom;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.TunnelRoom;
 import com.shatteredpixel.shatteredpixeldungeon.levels.traps.ConfusionTrap;
 import com.shatteredpixel.shatteredpixeldungeon.levels.traps.ExplosiveTrap;
 import com.shatteredpixel.shatteredpixeldungeon.levels.traps.FireTrap;
@@ -101,7 +102,7 @@ public class CavesLevel extends RegularLevel {
 	protected void decorate() {
 		
 		for (Room room : rooms) {
-			if (room.type != Room.Type.STANDARD) {
+			if (!(room instanceof StandardRoom)) {
 				continue;
 			}
 			
@@ -144,7 +145,7 @@ public class CavesLevel extends RegularLevel {
 			}
 
 			for (Room n : room.connected.keySet()) {
-				if ((n.type == Room.Type.STANDARD || n.type == Room.Type.TUNNEL) && Random.Int( 3 ) == 0) {
+				if ((n instanceof StandardRoom || n instanceof TunnelRoom) && Random.Int( 3 ) == 0) {
 					Painter.set( this, room.connected.get( n ), Terrain.EMPTY_DECO );
 				}
 			}
@@ -186,9 +187,9 @@ public class CavesLevel extends RegularLevel {
 		}
 		
 		for (Room r : rooms) {
-			if (r.type == Type.STANDARD) {
+			if (r instanceof StandardRoom) {
 				for (Room n : r.neigbours) {
-					if (n.type == Type.STANDARD && !r.connected.containsKey( n )) {
+					if (n instanceof StandardRoom && !r.connected.containsKey( n )) {
 						Rect w = r.intersect( n );
 						if (w.left == w.right && w.bottom - w.top >= 5) {
 							
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/PrisonBossLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/PrisonBossLevel.java
index 35cf227de..dbba39f9f 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/PrisonBossLevel.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/PrisonBossLevel.java
@@ -303,11 +303,11 @@ public class PrisonBossLevel extends Level {
 				HealthIndicator.instance.target(null);
 				tengu.sprite.kill();
 
-				Room maze = new Room();
+				Room maze = new MazeRoom();
 				maze.set(10, 1, 31, 29);
 				maze.connected.put(null, new Room.Door(10, 2));
 				maze.connected.put(maze, new Room.Door(20, 29));
-				MazeRoom.paint(this, maze);
+				maze.paint(this);
 				buildFlagMaps();
 				cleanWalls();
 				GameScene.resetMap();
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/RegularLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/RegularLevel.java
index 096f1bb48..1d47a8d16 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/RegularLevel.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/RegularLevel.java
@@ -34,8 +34,14 @@ import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfWealth;
 import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.Scroll;
 import com.shatteredpixel.shatteredpixeldungeon.levels.builders.Builder;
 import com.shatteredpixel.shatteredpixeldungeon.levels.builders.LegacyBuilder;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.EntranceRoom;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.ExitRoom;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.PassageRoom;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.PitRoom;
 import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room;
-import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room.Type;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.StandardRoom;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.TunnelRoom;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.WeakFloorRoom;
 import com.shatteredpixel.shatteredpixeldungeon.levels.traps.ChillingTrap;
 import com.shatteredpixel.shatteredpixeldungeon.levels.traps.ExplosiveTrap;
 import com.shatteredpixel.shatteredpixeldungeon.levels.traps.FireTrap;
@@ -117,7 +123,7 @@ public abstract class RegularLevel extends Level {
 		if (feeling == Feeling.GRASS) {
 			
 			for (Room room : rooms) {
-				if (room.type != Type.NULL && room.type != Type.PASSAGE && room.type != Type.TUNNEL) {
+				if (!(room instanceof TunnelRoom || room instanceof PassageRoom)) {
 					grass[(room.left + 1) + (room.top + 1) * width()] = true;
 					grass[(room.right - 1) + (room.top + 1) * width()] = true;
 					grass[(room.left + 1) + (room.bottom - 1) * width()] = true;
@@ -156,7 +162,7 @@ public abstract class RegularLevel extends Level {
 				if(Dungeon.depth == 1){
 					//extra check to prevent annoying inactive traps in hallways on floor 1
 					Room r = room(i);
-					if (r != null && r.type != Type.TUNNEL){
+					if (r instanceof StandardRoom){
 						validCells.add(i);
 					}
 				} else
@@ -201,14 +207,8 @@ public abstract class RegularLevel extends Level {
 	protected boolean paint() {
 		
 		for (Room r : rooms) {
-			if (r.type != Type.NULL) {
-				placeDoors( r );
-				r.type.paint( this, r );
-			} else {
-				if (feeling == Feeling.CHASM && Random.Int( 2 ) == 0) {
-					Painter.fill( this, r, Terrain.WALL );
-				}
-			}
+			placeDoors( r );
+			r.paint( this );
 		}
 		
 		for (Room r : rooms) {
@@ -287,7 +287,7 @@ public abstract class RegularLevel extends Level {
 	
 	protected boolean joinRooms( Room r, Room n ) {
 		
-		if (r.type != Room.Type.STANDARD || n.type != Room.Type.STANDARD) {
+		if (!(r instanceof StandardRoom && n instanceof StandardRoom)) {
 			return false;
 		}
 		
@@ -356,7 +356,7 @@ public abstract class RegularLevel extends Level {
 
 		ArrayList<Room> stdRooms = new ArrayList<>();
 		for (Room room : rooms) {
-			if (room.type == Type.STANDARD) stdRooms.add(room);
+			if (room instanceof StandardRoom) stdRooms.add(room);
 		}
 		Iterator<Room> stdRoomIter = stdRooms.iterator();
 
@@ -406,7 +406,7 @@ public abstract class RegularLevel extends Level {
 				return -1;
 			}
 			
-			Room room = randomRoom( Room.Type.STANDARD, 10 );
+			Room room = randomRoom( StandardRoom.class, 10 );
 			if (room == null) {
 				continue;
 			}
@@ -501,10 +501,10 @@ public abstract class RegularLevel extends Level {
 		}
 	}
 	
-	protected Room randomRoom( Room.Type type, int tries ) {
+	protected Room randomRoom( Class<?extends Room> type, int tries ) {
 		for (int i=0; i < tries; i++) {
 			Room room = Random.element( rooms );
-			if (room.type == type) {
+			if (room.getClass().equals(type)) {
 				return room;
 			}
 		}
@@ -513,7 +513,7 @@ public abstract class RegularLevel extends Level {
 	
 	public Room room( int pos ) {
 		for (Room room : rooms) {
-			if (room.type != Type.NULL && room.inside( cellToPoint(pos) )) {
+			if (room.inside( cellToPoint(pos) )) {
 				return room;
 			}
 		}
@@ -523,7 +523,7 @@ public abstract class RegularLevel extends Level {
 	
 	protected int randomDropCell() {
 		while (true) {
-			Room room = randomRoom( Room.Type.STANDARD, 1 );
+			Room room = randomRoom( StandardRoom.class, 1 );
 			if (room != null) {
 				int pos = pointToCell(room.random());
 				if (passable[pos]) {
@@ -536,7 +536,7 @@ public abstract class RegularLevel extends Level {
 	@Override
 	public int pitCell() {
 		for (Room room : rooms) {
-			if (room.type == Type.PIT) {
+			if (room instanceof PitRoom) {
 				return pointToCell(room.random());
 			}
 		}
@@ -555,15 +555,16 @@ public abstract class RegularLevel extends Level {
 	public void restoreFromBundle( Bundle bundle ) {
 		super.restoreFromBundle( bundle );
 
+		//TODO implement legacytype support here
 		rooms = new ArrayList<>( (Collection<Room>) ((Collection<?>) bundle.getCollection( "rooms" )) );
 		for (Room r : rooms) {
-			if (r.type == Type.WEAK_FLOOR) {
+			if (r instanceof WeakFloorRoom || r.legacyType.equals("WEAK_FLOOR")) {
 				weakFloorCreated = true;
 				break;
 			}
-			if (r.type == Type.ENTRANCE){
+			if (r instanceof EntranceRoom || r.legacyType.equals("ENTRANCE")){
 				roomEntrance = r;
-			} else if (r.type == Type.EXIT){
+			} else if (r instanceof ExitRoom  || r.legacyType.equals("EXIT")){
 				roomExit = r;
 			}
 		}
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SewerBossLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SewerBossLevel.java
index 4cbf7eb97..9f65c466a 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SewerBossLevel.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SewerBossLevel.java
@@ -32,7 +32,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.Item;
 import com.shatteredpixel.shatteredpixeldungeon.levels.builders.Builder;
 import com.shatteredpixel.shatteredpixeldungeon.levels.builders.LegacyBuilder;
 import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room;
-import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room.Type;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.StandardRoom;
 import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
 import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
 import com.watabou.noosa.Group;
@@ -128,7 +128,7 @@ public class SewerBossLevel extends RegularLevel {
 		Room room;
 		do {
 			room = Random.element(rooms);
-		} while (room.type != Type.STANDARD);
+		} while (!(room instanceof StandardRoom));
 		mob.pos = pointToCell(room.random());
 		mobs.add( mob );
 	}
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/builders/LegacyBuilder.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/builders/LegacyBuilder.java
index 39936d22c..f55214fd5 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/builders/LegacyBuilder.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/builders/LegacyBuilder.java
@@ -2,18 +2,37 @@ package com.shatteredpixel.shatteredpixeldungeon.levels.builders;
 
 import com.shatteredpixel.shatteredpixeldungeon.Challenges;
 import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
+import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
 import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Blacksmith;
 import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Imp;
 import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Wandmaker;
 import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.ArmoryRoom;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.CryptRoom;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.EntranceRoom;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.ExitRoom;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.GardenRoom;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.LaboratoryRoom;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.LibraryRoom;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.MagicWellRoom;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.PassageRoom;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.PitRoom;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.RatKingRoom;
 import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room;
 import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.ShopRoom;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.StandardRoom;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.StatueRoom;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.TreasuryRoom;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.TunnelRoom;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.VaultRoom;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.WeakFloorRoom;
 import com.watabou.utils.Graph;
 import com.watabou.utils.Random;
 import com.watabou.utils.Rect;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.ListIterator;
 
 //This builder exactly mimics pre-0.6.0 levelgen, including all of its limitations
 //Currently implemented during this transition period, it will likely not survive to 0.6.0 release
@@ -44,7 +63,7 @@ public class LegacyBuilder extends Builder {
 	public Room roomEntrance;
 	public Room roomExit;
 	
-	protected ArrayList<Room.Type> specials;
+	protected ArrayList<Class<?extends Room>> specials;
 	
 	@Override
 	//The list of rooms passed to this method is ignored
@@ -86,8 +105,13 @@ public class LegacyBuilder extends Builder {
 			
 		} while (distance < minDistance);
 		
-		roomEntrance.type = Room.Type.ENTRANCE;
-		roomExit.type = Room.Type.EXIT;
+		Room temp = roomEntrance;
+		roomEntrance = new EntranceRoom().set(temp);
+		rooms.set(rooms.indexOf(temp), roomEntrance);
+		
+		temp = roomExit;
+		roomExit = new ExitRoom().set(temp);
+		rooms.set(rooms.indexOf(temp), roomExit);
 		
 		ArrayList<Room> connected = new ArrayList<>();
 		connected.add( roomEntrance );
@@ -138,21 +162,23 @@ public class LegacyBuilder extends Builder {
 			if (shop == null) {
 				return null;
 			} else {
-				shop.type = Room.Type.SHOP;
+				temp = shop;
+				shop = new LaboratoryRoom().set(temp);
+				rooms.set(rooms.indexOf(temp), shop);
 			}
 		}
 		
-		specials = new ArrayList<Room.Type>( Room.SPECIALS );
+		specials = new ArrayList<Class<? extends Room>>( Room.SPECIALS );
 		if (Dungeon.bossLevel( Dungeon.depth + 1 )) {
-			specials.remove( Room.Type.WEAK_FLOOR );
+			specials.remove( WeakFloorRoom.class );
 		}
 		if (Dungeon.isChallenged( Challenges.NO_ARMOR )){
 			//no sense in giving an armor reward room on a run with no armor.
-			specials.remove( Room.Type.CRYPT );
+			specials.remove( CryptRoom.class );
 		}
 		if (Dungeon.isChallenged( Challenges.NO_HERBALISM )){
 			//sorry warden, no lucky sungrass or blandfruit seeds for you!
-			specials.remove( Room.Type.GARDEN );
+			specials.remove( GardenRoom.class );
 		}
 		
 		if (!assignRoomType())
@@ -167,8 +193,12 @@ public class LegacyBuilder extends Builder {
 				return null;
 		}
 		
+		ArrayList<Room> resultRooms = new ArrayList<>();
+		for (Room r : rooms)
+			if (!r.getClass().equals(Room.class))
+				resultRooms.add(r);
 		
-		return rooms;
+		return resultRooms;
 	}
 	
 	private ArrayList<Room> buildSewerBossLevel(){
@@ -185,10 +215,11 @@ public class LegacyBuilder extends Builder {
 			roomEntrance = Random.element( rooms );
 		} while (roomEntrance.width() != 8 || roomEntrance.height() < 5 || roomEntrance.top == 0 || roomEntrance.top >= 8);
 		
-		roomEntrance.type = Room.Type.ENTRANCE;
+		Room temp = roomEntrance;
+		roomEntrance = new EntranceRoom().set(temp);
+		rooms.set(rooms.indexOf(temp), roomEntrance);
 		roomExit = roomEntrance;
 		
-		
 		//now find the rest of the rooms for this boss mini-maze
 		Room curRoom = null;
 		Room lastRoom = roomEntrance;
@@ -205,9 +236,11 @@ public class LegacyBuilder extends Builder {
 					curRoom = Random.element(rooms);
 					Graph.buildDistanceMap(rooms, curRoom);
 					distance = lastRoom.distance();
-				} while (curRoom.type != Room.Type.NULL || distance != 3 || curRoom.neigbours.contains(roomEntrance));
+				} while (!(curRoom.getClass().equals(Room.class)) || distance != 3 || curRoom.neigbours.contains(roomEntrance));
 				
-				curRoom.type = Room.Type.STANDARD;
+				temp = curRoom;
+				curRoom = new StandardRoom().set(temp);
+				rooms.set(rooms.indexOf(temp), curRoom);
 				
 				//otherwise, we're on the last iteration.
 			} else {
@@ -235,7 +268,7 @@ public class LegacyBuilder extends Builder {
 				//look at rooms adjacent to the final found room (likely to be furthest from start)
 				ArrayList<Room> candidates = new ArrayList<Room>();
 				for (Room r : lastRoom.neigbours) {
-					if (r.type == Room.Type.NULL && r.connected.size() == 0 && !r.neigbours.contains(roomEntrance)) {
+					if (r.getClass().equals(Room.class) && r.connected.size() == 0 && !r.neigbours.contains(roomEntrance)) {
 						candidates.add(r);
 					}
 				}
@@ -244,7 +277,10 @@ public class LegacyBuilder extends Builder {
 				if (candidates.size() > 0) {
 					Room kingsRoom = Random.element(candidates);
 					kingsRoom.connect(lastRoom);
-					kingsRoom.type = Room.Type.RAT_KING;
+					
+					temp = kingsRoom;
+					kingsRoom = new RatKingRoom().set(temp);
+					rooms.set(rooms.indexOf(temp), kingsRoom);
 					
 					//unacceptable! make a new level...
 				} else {
@@ -259,13 +295,20 @@ public class LegacyBuilder extends Builder {
 		//and boring.
 		
 		//fills our connection rooms in with tunnel
-		for (Room r : rooms) {
-			if (r.type == Room.Type.NULL && r.connected.size() > 0) {
-				r.type = Room.Type.TUNNEL;
+		ListIterator<Room> it = rooms.listIterator();
+		while (it.hasNext()) {
+			Room r = it.next();
+			if (r.getClass().equals(Room.class) && r.connected.size() > 0) {
+				it.set(new TunnelRoom().set(r));
 			}
 		}
 		
-		return rooms;
+		ArrayList<Room> resultRooms = new ArrayList<>();
+		for (Room r : rooms)
+			if (!r.getClass().equals(Room.class))
+				resultRooms.add(r);
+		
+		return resultRooms;
 	}
 	
 	private ArrayList<Room> buildsLastShopLevel(){
@@ -298,8 +341,13 @@ public class LegacyBuilder extends Builder {
 			
 		} while (distance < minDistance);
 		
-		roomEntrance.type = Room.Type.ENTRANCE;
-		roomExit.type = Room.Type.EXIT;
+		Room temp = roomEntrance;
+		roomEntrance = new EntranceRoom().set(temp);
+		rooms.set(rooms.indexOf(temp), roomEntrance);
+		
+		temp = roomExit;
+		roomExit = new ExitRoom().set(temp);
+		rooms.set(rooms.indexOf(temp), roomExit);
 		
 		Graph.buildDistanceMap( rooms, roomExit );
 		List<Room> path = Graph.buildPath( rooms, roomEntrance, roomExit );
@@ -317,9 +365,11 @@ public class LegacyBuilder extends Builder {
 		
 		Room roomShop = null;
 		int shopSquare = 0;
-		for (Room r : rooms) {
-			if (r.type == Room.Type.NULL && r.connected.size() > 0) {
-				r.type = Room.Type.PASSAGE;
+		ListIterator<Room> it = rooms.listIterator();
+		while (it.hasNext()) {
+			Room r = it.next();
+			if (r.getClass().equals(Room.class) && r.connected.size() > 0) {
+				it.set(r = new PassageRoom().set(r));
 				if (r.square() > shopSquare) {
 					roomShop = r;
 					shopSquare = r.square();
@@ -330,10 +380,17 @@ public class LegacyBuilder extends Builder {
 		if (roomShop == null || shopSquare < 54) {
 			return null;
 		} else {
-			roomShop.type = Imp.Quest.isCompleted() ? Room.Type.SHOP : Room.Type.STANDARD;
+			temp = roomShop;
+			roomShop = Imp.Quest.isCompleted() ? new ShopRoom().set(temp) : new StandardRoom().set(temp);
+			rooms.set(rooms.indexOf(temp), roomShop);
 		}
 		
-		return rooms;
+		ArrayList<Room> resultRooms = new ArrayList<>();
+		for (Room r : rooms)
+			if (!r.getClass().equals(Room.class))
+				resultRooms.add(r);
+		
+		return resultRooms;
 	}
 	
 	private boolean initRooms(){
@@ -397,8 +454,11 @@ public class LegacyBuilder extends Builder {
 		int specialRooms = 0;
 		boolean pitMade = false;
 		
-		for (Room r : rooms) {
-			if (r.type == Room.Type.NULL &&
+		ListIterator<Room> it = rooms.listIterator();
+		while (it.hasNext()) {
+			Room r = it.next();
+			Room temp;
+			if (r.getClass().equals(Room.class) &&
 					r.connected.size() == 1) {
 				
 				if (specials.size() > 0 &&
@@ -407,38 +467,50 @@ public class LegacyBuilder extends Builder {
 					
 					if (Level.pitRoomNeeded && !pitMade) {
 						
-						r.type = Room.Type.PIT;
+						temp = r;
+						r = new PitRoom().set(temp);
+						rooms.set(rooms.indexOf(temp), r);
 						pitMade = true;
 						
-						specials.remove( Room.Type.ARMORY );
-						specials.remove( Room.Type.CRYPT );
-						specials.remove( Room.Type.LABORATORY );
-						specials.remove( Room.Type.LIBRARY );
-						specials.remove( Room.Type.STATUE );
-						specials.remove( Room.Type.TREASURY );
-						specials.remove( Room.Type.VAULT );
-						specials.remove( Room.Type.WEAK_FLOOR );
+						specials.remove( ArmoryRoom.class );
+						specials.remove( CryptRoom.class );
+						specials.remove( LaboratoryRoom.class );
+						specials.remove( LibraryRoom.class );
+						specials.remove( StatueRoom.class );
+						specials.remove( TreasuryRoom.class );
+						specials.remove( VaultRoom.class );
+						specials.remove( WeakFloorRoom.class );
 						
-					} else if (Dungeon.depth % 5 == 2 && specials.contains( Room.Type.LABORATORY )) {
+					} else if (Dungeon.depth % 5 == 2 && specials.contains( LaboratoryRoom.class )) {
 						
-						r.type = Room.Type.LABORATORY;
+						temp = r;
+						r = new LaboratoryRoom().set(temp);
+						rooms.set(rooms.indexOf(temp), r);
 						
-					} else if (Dungeon.depth >= Dungeon.transmutation && specials.contains( Room.Type.MAGIC_WELL )) {
+					} else if (Dungeon.depth >= Dungeon.transmutation && specials.contains( MagicWellRoom.class )) {
 						
-						r.type = Room.Type.MAGIC_WELL;
+						temp = r;
+						r = new MagicWellRoom().set(temp);
+						rooms.set(rooms.indexOf(temp), r);
 						
 					} else {
 						
 						int n = specials.size();
-						r.type = specials.get( Math.min( Random.Int( n ), Random.Int( n ) ) );
-						if (r.type == Room.Type.WEAK_FLOOR) {
+						temp = r;
+						try {
+							r = specials.get( Math.min( Random.Int( n ), Random.Int( n ) ) ).newInstance().set(temp);
+						} catch (Exception e) {
+							ShatteredPixelDungeon.reportException(e);
+						}
+						rooms.set(rooms.indexOf(temp), r);
+						if (r instanceof WeakFloorRoom) {
 							Level.weakFloorCreated = true;
 						}
 						
 					}
 					
-					Room.useType( r.type );
-					specials.remove( r.type );
+					Room.useType( r.getClass() );
+					specials.remove( r.getClass() );
 					specialRooms++;
 					
 				} else if (Random.Int( 2 ) == 0){
@@ -446,8 +518,8 @@ public class LegacyBuilder extends Builder {
 					ArrayList<Room> neigbours = new ArrayList<>();
 					for (Room n : r.neigbours) {
 						if (!r.connected.containsKey( n ) &&
-								!Room.SPECIALS.contains( n.type ) &&
-								n.type != Room.Type.PIT) {
+								!Room.SPECIALS.contains( n.getClass() ) &&
+								!(n instanceof PitRoom)) {
 							
 							neigbours.add( n );
 						}
@@ -461,23 +533,29 @@ public class LegacyBuilder extends Builder {
 		
 		if (Level.pitRoomNeeded && !pitMade) return false;
 		
-		Room.Type tunnelType = Room.Type.TUNNEL;
+		Class<? extends Room> tunnelType = TunnelRoom.class;
 		if ((Dungeon.depth > 5 && Dungeon.depth <= 10) ||
 				(Dungeon.depth > 15 && Dungeon.depth <= 20)){
-			tunnelType = Room.Type.PASSAGE;
+			tunnelType = PassageRoom.class;
 		}
 		
 		int count = 0;
-		for (Room r : rooms) {
-			if (r.type == Room.Type.NULL) {
+		it = rooms.listIterator();
+		while (it.hasNext()) {
+			Room r = it.next();
+			if (r.getClass().equals(Room.class)) {
 				int connections = r.connected.size();
 				if (connections == 0) {
 					
 				} else if (Random.Int( connections * connections ) == 0) {
-					r.type = Room.Type.STANDARD;
+					it.set(new StandardRoom().set(r));
 					count++;
 				} else {
-					r.type = tunnelType;
+					if (tunnelType == TunnelRoom.class){
+						it.set(new TunnelRoom().set(r));
+					} else {
+						it.set(new PassageRoom().set(r));
+					}
 				}
 			}
 		}
@@ -485,7 +563,7 @@ public class LegacyBuilder extends Builder {
 		while (count < 6) {
 			Room r = randomRoom( tunnelType, 20 );
 			if (r != null) {
-				r.type = Room.Type.STANDARD;
+				rooms.set(rooms.indexOf(r), new StandardRoom().set(r));
 				count++;
 			} else {
 				return false;
@@ -495,10 +573,10 @@ public class LegacyBuilder extends Builder {
 		return true;
 	}
 	
-	private Room randomRoom( Room.Type type, int tries ) {
+	private Room randomRoom( Class<?extends Room> type, int tries ) {
 		for (int i=0; i < tries; i++) {
 			Room room = Random.element( rooms );
-			if (room.type == type) {
+			if (room.getClass().equals(type)) {
 				return room;
 			}
 		}
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/features/Chasm.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/features/Chasm.java
index 41de55c4c..f31b49971 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/features/Chasm.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/features/Chasm.java
@@ -33,6 +33,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.DriedRose;
 import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.TimekeepersHourglass;
 import com.shatteredpixel.shatteredpixeldungeon.levels.RegularLevel;
 import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room;
+import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.WeakFloorRoom;
 import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
 import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
 import com.shatteredpixel.shatteredpixeldungeon.scenes.InterlevelScene;
@@ -82,7 +83,7 @@ public class Chasm {
 			InterlevelScene.mode = InterlevelScene.Mode.FALL;
 			if (Dungeon.level instanceof RegularLevel) {
 				Room room = ((RegularLevel)Dungeon.level).room( pos );
-				InterlevelScene.fallIntoPit = room != null && room.type == Room.Type.WEAK_FLOOR;
+				InterlevelScene.fallIntoPit = room != null && room instanceof WeakFloorRoom;
 			} else {
 				InterlevelScene.fallIntoPit = false;
 			}
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/AltarRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/AltarRoom.java
index dbbd9a39f..15b649a75 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/AltarRoom.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/AltarRoom.java
@@ -31,7 +31,7 @@ import com.watabou.utils.Point;
 
 public class AltarRoom extends Room {
 
-	public static void paint( Level level, Room room ) {
+	public void paint( Level level, Room room ) {
 		
 		Painter.fill( level, room, Terrain.WALL );
 		Painter.fill( level, room, 1, Dungeon.bossLevel( Dungeon.depth + 1 ) ? Terrain.HIGH_GRASS : Terrain.CHASM );
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/ArmoryRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/ArmoryRoom.java
index a86add208..6c0203973 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/ArmoryRoom.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/ArmoryRoom.java
@@ -34,7 +34,7 @@ import com.watabou.utils.Random;
 
 public class ArmoryRoom extends Room {
 
-	public static void paint( Level level, Room room ) {
+	public void paint( Level level, Room room ) {
 		
 		Painter.fill( level, room, Terrain.WALL );
 		Painter.fill( level, room, 1, Terrain.EMPTY );
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/BlacksmithRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/BlacksmithRoom.java
index da095eee8..0fe92f0b5 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/BlacksmithRoom.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/BlacksmithRoom.java
@@ -32,7 +32,7 @@ import com.watabou.utils.Random;
 
 public class BlacksmithRoom extends Room {
 
-	public static void paint( Level level, Room room ) {
+	public void paint( Level level, Room room ) {
 
 		Painter.fill( level, room, Terrain.WALL );
 		Painter.fill( level, room, 1, Terrain.TRAP );
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/CryptRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/CryptRoom.java
index e86cd854a..f0cc0a5b3 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/CryptRoom.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/CryptRoom.java
@@ -34,7 +34,7 @@ import com.watabou.utils.Point;
 
 public class CryptRoom extends Room {
 
-	public static void paint( Level level, Room room ) {
+	public void paint( Level level, Room room ) {
 		
 		Painter.fill( level, room, Terrain.WALL );
 		Painter.fill( level, room, 1, Terrain.EMPTY );
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/EntranceRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/EntranceRoom.java
index f6e9d4cda..f03850020 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/EntranceRoom.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/EntranceRoom.java
@@ -27,7 +27,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
 
 public class EntranceRoom extends Room {
 
-	public static void paint( Level level, Room room ) {
+	public void paint( Level level, Room room ) {
 		
 		Painter.fill( level, room, Terrain.WALL );
 		Painter.fill( level, room, 1, Terrain.EMPTY );
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/ExitRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/ExitRoom.java
index 55ec6ca1f..d705e0511 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/ExitRoom.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/ExitRoom.java
@@ -27,7 +27,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
 
 public class ExitRoom extends Room {
 
-	public static void paint( Level level, Room room ) {
+	public void paint( Level level, Room room ) {
 
 		Painter.fill( level, room, Terrain.WALL );
 		Painter.fill( level, room, 1, Terrain.EMPTY );
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/GardenRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/GardenRoom.java
index 0c2b51cd5..7eef1e3a5 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/GardenRoom.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/GardenRoom.java
@@ -33,7 +33,7 @@ import com.watabou.utils.Random;
 
 public class GardenRoom extends Room {
 
-	public static void paint( Level level, Room room ) {
+	public void paint( Level level, Room room ) {
 		
 		Painter.fill( level, room, Terrain.WALL );
 		Painter.fill( level, room, 1, Terrain.HIGH_GRASS );
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/LaboratoryRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/LaboratoryRoom.java
index 48f677db9..a04017848 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/LaboratoryRoom.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/LaboratoryRoom.java
@@ -35,7 +35,7 @@ import com.watabou.utils.Random;
 
 public class LaboratoryRoom extends Room {
 
-	public static void paint( Level level, Room room ) {
+	public void paint( Level level, Room room ) {
 		
 		Painter.fill( level, room, Terrain.WALL );
 		Painter.fill( level, room, 1, Terrain.EMPTY_SP );
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/LibraryRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/LibraryRoom.java
index 783216f37..e00995418 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/LibraryRoom.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/LibraryRoom.java
@@ -36,7 +36,7 @@ import com.watabou.utils.Random;
 
 public class LibraryRoom extends Room {
 
-	public static void paint( Level level, Room room ) {
+	public void paint( Level level, Room room ) {
 		
 		Painter.fill( level, room, Terrain.WALL );
 		Painter.fill( level, room, 1, Terrain.EMPTY_SP );
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/MagicWellRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/MagicWellRoom.java
index 1f4d6e459..4f9754ccc 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/MagicWellRoom.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/MagicWellRoom.java
@@ -38,7 +38,7 @@ public class MagicWellRoom extends Room {
 	private static final Class<?>[] WATERS =
 		{WaterOfAwareness.class, WaterOfHealth.class, WaterOfTransmutation.class};
 	
-	public static void paint( Level level, Room room ) {
+	public void paint( Level level, Room room ) {
 
 		Painter.fill( level, room, Terrain.WALL );
 		Painter.fill( level, room, 1, Terrain.EMPTY );
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/MassGraveRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/MassGraveRoom.java
index 687f2076d..59e76c100 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/MassGraveRoom.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/MassGraveRoom.java
@@ -41,7 +41,7 @@ import java.util.ArrayList;
 
 public class MassGraveRoom extends Room {
 
-	public static void paint( Level level, Room room){
+	public void paint( Level level, Room room){
 
 		Room.Door entrance = room.entrance();
 		entrance.set(Room.Door.Type.BARRICADE);
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/MazeRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/MazeRoom.java
index 63b894b83..a0467cfe1 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/MazeRoom.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/MazeRoom.java
@@ -28,7 +28,7 @@ import com.watabou.utils.Random;
 
 public class MazeRoom extends Room {
 
-	public static void paint( Level level, Room room ) {
+	public void paint( Level level, Room room ) {
 		Painter.fill(level, room, 1, Terrain.EMPTY);
 
 		//true = space, false = wall
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/PassageRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/PassageRoom.java
index 8bd60608a..a562e2124 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/PassageRoom.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/PassageRoom.java
@@ -33,7 +33,7 @@ public class PassageRoom extends Room {
 	private static int pasWidth;
 	private static int pasHeight;
 	
-	public static void paint( Level level, Room room ) {
+	public void paint( Level level, Room room ) {
 		
 		pasWidth = room.width() - 2;
 		pasHeight = room.height() - 2;
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/PitRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/PitRoom.java
index 112d9facd..c684cf724 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/PitRoom.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/PitRoom.java
@@ -34,7 +34,7 @@ import com.watabou.utils.Random;
 
 public class PitRoom extends Room {
 
-	public static void paint( Level level, Room room ) {
+	public void paint( Level level, Room room ) {
 		
 		Painter.fill( level, room, Terrain.WALL );
 		Painter.fill( level, room, 1, Terrain.EMPTY );
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/PoolRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/PoolRoom.java
index 31b936ded..86aa84301 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/PoolRoom.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/PoolRoom.java
@@ -37,7 +37,7 @@ public class PoolRoom extends Room {
 
 	private static final int NPIRANHAS	= 3;
 	
-	public static void paint( Level level, Room room ) {
+	public void paint( Level level, Room room ) {
 		
 		Painter.fill( level, room, Terrain.WALL );
 		Painter.fill( level, room, 1, Terrain.WATER );
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/RatKingRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/RatKingRoom.java
index 21cb83dec..e8483fafc 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/RatKingRoom.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/RatKingRoom.java
@@ -32,7 +32,7 @@ import com.watabou.utils.Random;
 
 public class RatKingRoom extends Room {
 
-	public static void paint( Level level, Room room ) {
+	public void paint( Level level, Room room ) {
 
 		Painter.fill( level, room, Terrain.WALL );
 		Painter.fill( level, room, 1, Terrain.EMPTY_SP );
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/RitualSiteRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/RitualSiteRoom.java
index f8531c06e..8a289eafa 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/RitualSiteRoom.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/RitualSiteRoom.java
@@ -32,7 +32,7 @@ import com.watabou.utils.Point;
 
 public class RitualSiteRoom extends Room {
 
-	public static void paint( Level level, Room room) {
+	public void paint( Level level, Room room) {
 
 		for (Room.Door door : room.connected.values()) {
 			door.set( Room.Door.Type.REGULAR );
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/Room.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/Room.java
index bdbe0ac4f..3a6e60cc7 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/Room.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/Room.java
@@ -21,7 +21,6 @@
 
 package com.shatteredpixel.shatteredpixeldungeon.levels.rooms;
 
-import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
 import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
 import com.watabou.utils.Bundlable;
 import com.watabou.utils.Bundle;
@@ -30,7 +29,6 @@ import com.watabou.utils.Point;
 import com.watabou.utils.Random;
 import com.watabou.utils.Rect;
 
-import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -48,79 +46,42 @@ public class Room extends Rect implements Graph.Node, Bundlable {
 		super();
 	}
 	
-	public Room(Rect other){
+	public Room( Rect other ){
 		super(other);
 	}
 	
-	public Room( int left, int top, int right, int bottom ) {
-		super( left, top, right, bottom );
+	public Room set( Room other ) {
+		super.set( other );
+		for (Room r : other.neigbours){
+			neigbours.add(r);
+			r.neigbours.remove(other);
+			r.neigbours.add(this);
+		}
+		for (Room r : other.connected.keySet()){
+			Door d = other.connected.get(r);
+			r.connected.remove(other);
+			r.connected.put(this, d);
+			connected.put(r, d);
+		}
+		return this;
 	}
 	
-	//TODO convert these types into full subclasses of room
-	public static enum Type {
-		NULL( null ),
-		STANDARD	( StandardRoom.class ),
-		ENTRANCE	( EntranceRoom.class ),
-		EXIT		( ExitRoom.class ),
-		TUNNEL		( TunnelRoom.class ),
-		PASSAGE		( PassageRoom.class ),
-		SHOP		( ShopRoom.class ),
-		BLACKSMITH	( BlacksmithRoom.class ),
-		TREASURY	( TreasuryRoom.class ),
-		ARMORY		( ArmoryRoom.class ),
-		LIBRARY		( LibraryRoom.class ),
-		LABORATORY	( LaboratoryRoom.class ),
-		VAULT		( VaultRoom.class ),
-		TRAPS		( TrapsRoom.class ),
-		STORAGE		( StorageRoom.class ),
-		MAGIC_WELL	( MagicWellRoom.class ),
-		GARDEN		( GardenRoom.class ),
-		CRYPT		( CryptRoom.class ),
-		STATUE		( StatueRoom.class ),
-		POOL		( PoolRoom.class ),
-		RAT_KING	( RatKingRoom.class ),
-		WEAK_FLOOR	( WeakFloorRoom.class ),
-		PIT			( PitRoom.class ),
+	public void paint(Level level){
+		paint(level, this);
+	}
+	
+	public void paint(Level level, Room room){
+		
+	}
 
-		//prison quests
-		MASS_GRAVE  ( MassGraveRoom.class ),
-		ROT_GARDEN  ( RotGardenRoom.class ),
-		RITUAL_SITE ( RitualSiteRoom.class );
-		
-		private Method paint;
-		
-		Type( Class<? extends Room> painter ) {
-			if (painter == null)
-				paint = null;
-			else
-				try {
-					paint = painter.getMethod( "paint", Level.class, Room.class );
-				} catch (Exception e) {
-					ShatteredPixelDungeon.reportException(e);
-					paint = null;
-				}
-		}
-		
-		public void paint( Level level, Room room ) {
-			try {
-				paint.invoke( null, level, room );
-			} catch (Exception e) {
-				ShatteredPixelDungeon.reportException(e);
-			}
-		}
-	};
-
-	private static final ArrayList<Type> ALL_SPEC = new ArrayList<Type>( Arrays.asList(
-		Type.WEAK_FLOOR, Type.MAGIC_WELL, Type.CRYPT, Type.POOL, Type.GARDEN, Type.LIBRARY, Type.ARMORY,
-		Type.TREASURY, Type.TRAPS, Type.STORAGE, Type.STATUE, Type.LABORATORY, Type.VAULT
+	private static final ArrayList<Class<? extends Room>> ALL_SPEC = new ArrayList<>( Arrays.asList(
+		WeakFloorRoom.class, MagicWellRoom.class, CryptRoom.class, PoolRoom.class, GardenRoom.class, LibraryRoom.class, ArmoryRoom.class,
+		TreasuryRoom.class, TrapsRoom.class, StorageRoom.class, StatueRoom.class, LaboratoryRoom.class, VaultRoom.class
 	) );
 	
-	public static ArrayList<Type> SPECIALS = new ArrayList<Type>( Arrays.asList(
-		Type.WEAK_FLOOR, Type.MAGIC_WELL, Type.CRYPT, Type.POOL, Type.GARDEN, Type.LIBRARY, Type.ARMORY,
-		Type.TREASURY, Type.TRAPS, Type.STORAGE, Type.STATUE, Type.LABORATORY, Type.VAULT
-	) );
+	public static ArrayList<Class<? extends Room>> SPECIALS = new ArrayList<>();
 	
-	public Type type = Type.NULL;
+	public String legacyType = "NULL";
 	
 	public Point random() {
 		return random( 0 );
@@ -196,7 +157,8 @@ public class Room extends Rect implements Graph.Node, Bundlable {
 		bundle.put( "top", top );
 		bundle.put( "right", right );
 		bundle.put( "bottom", bottom );
-		bundle.put( "type", type.toString() );
+		if (!legacyType.equals("NULL"))
+			bundle.put( "type", legacyType );
 	}
 	
 	@Override
@@ -205,35 +167,36 @@ public class Room extends Rect implements Graph.Node, Bundlable {
 		top = bundle.getInt( "top" );
 		right = bundle.getInt( "right" );
 		bottom = bundle.getInt( "bottom" );
-		type = Type.valueOf( bundle.getString( "type" ) );
+		if (bundle.contains( "type" ))
+			legacyType = bundle.getString( "type" );
 	}
 	
 	public static void shuffleTypes() {
-		SPECIALS = (ArrayList<Type>)ALL_SPEC.clone();
+		SPECIALS = (ArrayList<Class<?extends Room>>)ALL_SPEC.clone();
 		int size = SPECIALS.size();
 		for (int i=0; i < size - 1; i++) {
 			int j = Random.Int( i, size );
 			if (j != i) {
-				Type t = SPECIALS.get( i );
+				Class<?extends Room> c = SPECIALS.get( i );
 				SPECIALS.set( i, SPECIALS.get( j ) );
-				SPECIALS.set( j, t );
+				SPECIALS.set( j, c );
 			}
 		}
 	}
 	
-	public static void useType( Type type ) {
+	public static void useType( Class<?extends Room> type ) {
 		if (SPECIALS.remove( type )) {
 			SPECIALS.add( type );
 		}
 	}
 	
-	private static final String ROOMS	= "rooms";
+	private static final String ROOMS	= "special_rooms";
 	
 	public static void restoreRoomsFromBundle( Bundle bundle ) {
 		if (bundle.contains( ROOMS )) {
 			SPECIALS.clear();
-			for (String type : bundle.getStringArray( ROOMS )) {
-				SPECIALS.add( Type.valueOf( type ));
+			for (Class<?extends Room> type : bundle.getClassArray( ROOMS )) {
+				SPECIALS.add( type );
 			}
 		} else {
 			shuffleTypes();
@@ -241,11 +204,7 @@ public class Room extends Rect implements Graph.Node, Bundlable {
 	}
 	
 	public static void storeRoomsInBundle( Bundle bundle ) {
-		String[] array = new String[SPECIALS.size()];
-		for (int i=0; i < array.length; i++) {
-			array[i] = SPECIALS.get( i ).toString();
-		}
-		bundle.put( ROOMS, array );
+		bundle.put( ROOMS, SPECIALS.toArray(new Class[0]) );
 	}
 	
 	public static class Door extends Point {
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/RotGardenRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/RotGardenRoom.java
index 85b3c7cce..ce123b461 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/RotGardenRoom.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/RotGardenRoom.java
@@ -34,7 +34,7 @@ import com.watabou.utils.Random;
 
 public class RotGardenRoom extends Room {
 
-	public static void paint( Level level, Room room ) {
+	public void paint( Level level, Room room ) {
 
 		Room.Door entrance = room.entrance();
 		entrance.set(Room.Door.Type.LOCKED);
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/ShopRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/ShopRoom.java
index e15342be0..388813026 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/ShopRoom.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/ShopRoom.java
@@ -85,7 +85,7 @@ public class ShopRoom extends Room {
 
 	private static ArrayList<Item> itemsToSpawn;
 	
-	public static void paint( Level level, Room room ) {
+	public void paint( Level level, Room room ) {
 		
 		Painter.fill( level, room, Terrain.WALL );
 		Painter.fill( level, room, 1, Terrain.EMPTY_SP );
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/StandardRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/StandardRoom.java
index be6290b60..30e5b615c 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/StandardRoom.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/StandardRoom.java
@@ -35,7 +35,7 @@ import com.watabou.utils.Random;
 
 public class StandardRoom extends Room {
 
-	public static void paint( Level level, Room room ) {
+	public void paint( Level level, Room room ) {
 		
 		Painter.fill( level, room, Terrain.WALL );
 		for (Room.Door door : room.connected.values()) {
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/StatueRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/StatueRoom.java
index 9570a7355..fdb207ec0 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/StatueRoom.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/StatueRoom.java
@@ -31,7 +31,7 @@ import com.watabou.utils.Point;
 
 public class StatueRoom extends Room {
 
-	public static void paint( Level level, Room room ) {
+	public void paint( Level level, Room room ) {
 
 		Painter.fill( level, room, Terrain.WALL );
 		Painter.fill( level, room, 1, Terrain.EMPTY );
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/StorageRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/StorageRoom.java
index dca285a9c..f64cd6852 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/StorageRoom.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/StorageRoom.java
@@ -32,7 +32,7 @@ import com.watabou.utils.Random;
 
 public class StorageRoom extends Room {
 
-	public static void paint( Level level, Room room ) {
+	public void paint( Level level, Room room ) {
 		
 		final int floor = Terrain.EMPTY_SP;
 		
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/TrapsRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/TrapsRoom.java
index d1d9078b1..9fd1e6bac 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/TrapsRoom.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/TrapsRoom.java
@@ -50,7 +50,7 @@ import com.watabou.utils.Random;
 
 public class TrapsRoom extends Room {
 
-	public static void paint( Level level, Room room ) {
+	public void paint( Level level, Room room ) {
 		 
 		Painter.fill( level, room, Terrain.WALL );
 
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/TreasuryRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/TreasuryRoom.java
index e5a639d8d..97761a522 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/TreasuryRoom.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/TreasuryRoom.java
@@ -32,7 +32,7 @@ import com.watabou.utils.Random;
 
 public class TreasuryRoom extends Room {
 
-	public static void paint( Level level, Room room ) {
+	public void paint( Level level, Room room ) {
 		
 		Painter.fill( level, room, Terrain.WALL );
 		Painter.fill( level, room, 1, Terrain.EMPTY );
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/TunnelRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/TunnelRoom.java
index ad8408126..efa038cf3 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/TunnelRoom.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/TunnelRoom.java
@@ -28,7 +28,7 @@ import com.watabou.utils.Random;
 
 public class TunnelRoom extends Room {
 
-	public static void paint( Level level, Room room ) {
+	public void paint( Level level, Room room ) {
 		
 		int floor = level.tunnelTile();
 		
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/VaultRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/VaultRoom.java
index 841cea726..ddfedadf0 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/VaultRoom.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/VaultRoom.java
@@ -35,7 +35,7 @@ import com.watabou.utils.Random;
 
 public class VaultRoom extends Room {
 
-	public static void paint( Level level, Room room ) {
+	public void paint( Level level, Room room ) {
 
 		Painter.fill( level, room, Terrain.WALL );
 		Painter.fill( level, room, 1, Terrain.EMPTY_SP );
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/WeakFloorRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/WeakFloorRoom.java
index 867c21876..5a843f3b7 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/WeakFloorRoom.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/WeakFloorRoom.java
@@ -33,7 +33,7 @@ import com.watabou.utils.Random;
 
 public class WeakFloorRoom extends Room {
 
-	public static void paint( Level level, Room room ) {
+	public void paint( Level level, Room room ) {
 		
 		Painter.fill( level, room, Terrain.WALL );
 		Painter.fill( level, room, 1, Terrain.CHASM );